Synchronet v3.19b-Win32 (install) has been released (Jan-2022).

You can donate to the Synchronet project using PayPal.

Web Server

The Synchronet Web Server serves static (e.g. files) and dynamic content to HTTP clients (e.g. web browsers).


The Synchronet Web Server is a mostly HTTP 1.1 compliant web server capable of handing basic web servicing tasks. It has most of the basic features of a general-purpose web server one would come to expect, including (Fast)CGI.

It also, through Server-Side JavaScript (SSJS), allows dynamic pages to be created which can access BBS data directly.


The Synchronet Web Server can be configured via SCFG:Servers->Web Server:

║                            Web Server                            ║
║ │Enabled                       Yes                               ║
║ │Log Level                     Informational                     ║
║ │HTTP Interfaces     , ::                       ║
║ │HTTP Port                     80                                ║
║ │HTTPS Support                 Yes                               ║
║ │HTTPS Interfaces    , ::                       ║
║ │HTTPS Port                    443                               ║
║ │SSJS File Extension           .ssjs                             ║
║ │Index Filenames               index.html, index.ssjs, index.xjs ║
║ │Content Root Directory        ../webv4/root                     ║
║ │Error Sub-directory           error                             ║
║ │Strict Transport Security     No                                ║
║ │Virtual Host Support          No                                ║
║ │Access Logging                <disabled>                        ║
║ │Max Clients                   100                               ║
║ │Max Inactivity                2 minutes                         ║
║ │Filebase Index Script         webfileindex.ssjs                 ║
║ │Filebase VPath Prefix         /files/                           ║
║ │Filebase VPath for VHosts     No                                ║
║ │Authentication Methods        Basic,Digest,TLS-PSK              ║
║ │Output Buffer Drain Timeout   10 ms                             ║
║ │Lookup Client Hostname        No                                ║
║ │CGI Support                   No                                ║
║ │CGI Directory                 cgi-bin                           ║
║ │CGI File Extensions           .cgi                              ║
║ │CGI Default Content-Type      text/plain                        ║
║ │CGI Max Inactivity            2 minutes                         ║
║ │JavaScript Settings...                                          ║
║ │Failed Login Attempts...                                        ║

... or via SBBSCTRL:Web->Configure:

... or via manual edit of the [Web] section of the ctrl/sbbs.ini file.


The [Web] section of your sbbs.ini file supports the following configuration settings (keys):

Key Default Description
AutoStart true Automatically start-up the server when Synchronet is started
HostName none Override system hostname
LogLevel Informational Default minimum severity of log messages to view or log-to-disk
TLSErrorLevel Emergency Maximum severity of TLS-related log messages
Interface,:: Comma-separated list of IPv4 and IPv6 addresses of network interfaces and optional port numbers to listen for incoming HTTP/TCP connections
TLSInterface Interface ... for incoming HTTPS/TLS connections
Port 80 Default TCP port to listen for incoming HTTP connections
TLSPort 443 Default TCP port to listen for incoming HTTPS/TLS connections
BindRetryCount 2 Default number of network interface/port bind retry attempts
BindRetryDelay 15 Default number of seconds to wait between bind attempts
MaxClients 100 Maximum number of simultaneous connections supported (0 = unlimited)
MaxInactivity 2m Maximum duration of client inactivity before disconnection
MaxCgiInactivity 2m Maximum duration of CGI application inactivity
SemFileCheckFrequency global (2) Seconds between semaphore file checks
IndexFileNames index.html,index.ssjs Index filenames to search for and serve up (when no file name was requested)
RootDirectory ../web/root Files are served out of this directory tree
ErrorDirectory error Sub-directory of RootDirectory where error files are served from
CGIDirectory cgi-bin Sub-directory of RootDirectory where CGI applications are served from
DefaultCGIContent text/plain Default MIME-type of CGI content
CGIExtensions .cgi Comma-separate list of file extensions (suffixes) used to recognize CGI application files
JavaScriptExtension .ssjs File extension used to recognize Server-side JavaScript content files
Authentication Basic,Digest,TLS-PSK Authentication methods supported
HttpLogFile data/logs/http- Path prefix for HTTP access log files
FileIndexScript “” Server-side JavaScript to execute to provide HTML/CSS library and directory listings of virtual file paths (e.g. webfileindex.ssjs)
FileVPathPrefix “” Virtual path for HTTP file base access, suggested value: /files/
FileVPathForVHosts false If you'd like your virtual hosts to provide HTTP access to your file bases (using virtual file paths), set this to true
OutbufDrainTimeout 10 Number of milliseconds to wait for output buffer to drain
TempDirectory ../temp/ Override default temporary file directory
Options See below for details


The Options key is set to a | separated list of options to enable.


In addition to the standard options, the web server also supports the following:


Log all received data to the console log, as well as various extra bits related to receiving data.


Log all transmitted data except the reply body itself, as well as various extra bits of information related to transmitted data.


Log server-side JavaScript execution details.


Supports name-based virtual hosts. If your system has multiple host names, you can have each host name return unique content depending on which hostname is used. ie: if and both resolved to your system, you could have FreeBSD-specific pages on one, and general *nix stuff on the other.

A virtual host is added by simply putting the desired content into a sub-directory of RootDirectory with the desired hostname ie: web/root/ if the browser doesn't send the request host name (very old browsers, or some automated tools) they will be served out of document root. It is therefore a good idea to put links to your various virtual hosts in an index.html page in RootDirectory something like this:

    <title>Old Browser</title>
    Your browser is either too old to support
    name-based virtual hosts, or you have visited a
    virtual hosts that is not yet configured.  The
    following are hosted here:<br>
    <a href=""></a><br>
    <a href=""></a><br>

Disable CGI/FastCGI script execution.


Enable logging to a Common Logfile Format log as described in the HttpLogFile section. Usefull for running log analysis programs (like Webalizer:


Disable SSJS execution.


Enable TLS/SSL support.


Indicates that all URLs available via http are also available via https and redirects clients who want a TLS session to the https location.


Web Server configuration settings reference:


Default value: ../web/root

This is the root directory of your web server... a request to will be served out of this directory.

NOTE: Older versions of Synchronet had this value default to ../web/html


Default value: error

The directory relative to RootDirectory where the various error message files are located. The error message files are named by the numeric HTTP error code they will represent and may be either .html or .ssjs files (.ssjs files take precedence over .html files for the same error).


Default value: index.html,index.ssjs

A comma-separated list of filenames in order of preference to serve as the default document in a directory. Many Sysops change this to: index.html,index.htm,index.ssjs. Do not remove the index.ssjs unless you are not using the stock web pages at all.


Default value: Basic,Digest

A comma-separated list of authentication mechanisms in order of preference. The standards say that Basic must come first, but no browser currently appears to use Digest if Basic is listed first. Supported values are Basic and Digest. Digest is more secure as the users password is not sent in the clear over the wire.


Default value: cgi-bin

A directory relative to RootDirectory where any files found will be considered CGI-executable. Be careful what files you put in this directory.


Default value: .cgi

A comma-separated list of file extensions/suffixes. Files with these extensions will be considered CGI-executable and the web server will attempt to execute them as such.

Other probably values include: .pl,.php,.exe


Default value: text/plain

If the CGI program does not generate a content-type header, this value will be used for the MIME content-type specified in the HTTP response.


Default value: .ssjs

Files with this extension will be considered SSJS files. On all systems, this will be attempted to run with the JavaScript interpreter.


Default value: 120

If a client holds a connection open for this many seconds without a request, the web server will shut down the connection.


Defalut value: 120

If a CGI script runs for more than this many seconds without any output, it will be terminated and the connection will be shut down.


Default value: ../data/logs/http-

The prefix of log files if HTTP_LOGGING is enabled (See next item) to store Common Logfile Format logs in. The current virtual host (if enabled, see next item), date, and .log are appended to this (e.g.http-2005-03-12.log).


Default value: “”

Suggested value: /files/

A virtual sub-directory of your web root to provide direct HTTP[S] access to your file bases. HTTP-AUTH is used for conditional access/restrictions, when necessary. The trailing slash is important.


Default value: false

By default, virtual hosts will not have the virtual file path (if enabled). Set this to true if you would like your virtual hosts to support the virtual file paths as well.


Default value: “”

Suggested value: webfileindex.ssjs

A Server-side JavaScript (SSJS) file to execute and provide HTML/CSS indexes to file libraries and directories accessed via virtual file paths.

Other configuration files

In addition to the [Web] keys in the sbbs.ini file, the web server also uses some other configuration files:


Contains the file extension to mime-type mapping. Each line is in the format “extension = mime-type” ie: “html = text/html” The extensions are case-insensitive and do not include the '.'.


Contains the URLs to the icons used by the default 404.ssjs script for each file type/extension. Format is “extension = URL”. Example: “html=/icons/layout.gif”. Two “magical” extensions exist: DIRECTORY which is used for directories and DefaultIcon which is used for extensions which don't exist in the list.


This file contains 2 sections where a list of file extensions and their associated content-creation handlers are specified:


The [CGI] section is for natively-executed CGI handlers (e.g. “pl = perl” indicates “perl” will be used to handle “.pl” files).


The [JavaScript] section is used for JS-executed content handlers (e.g. “xjs = xjs_handler.js”).


Contains a list of system environment variables to pass to CGI processes. Each variable can have an optionally specified default value, over-ridden value, and prepended or appended text.


Each directory under the RootDirectory may have a webctrl.ini file which overrides certain settings for the directory it's in and all child directories. Configuration keys may be set either globally, in a per-filename group, or, in version 3.17 or greater, a per-directory-name group. Using the * and ? wildcards as the group name such as [*.html] or [dirname/]. The following keys may be used in these files:


Specifies an ARS string which all users must match to be able to access files in this directory. Will force an HTTP login.

For example, to require a login, but allow any user to access files in a directory, but only a sysop to access *.log files and .git directories, the following could be used:

AccessRequirements=level 0
AccessRequirements=level 90
AccessRequirements=level 90


Sets the realm that is displayed to the user for the HTTP login. Default is the BBS name.


Sets the realm that is displayed to the user for the HTTP login when Digest authentication is being used. Default is the Realm value.


A comma-separated list of authentication mechanisms in order of preference. The standards say that Basic must come first, but no browser currently appears to use Digest if Basic is listed first. Supported values are Basic and Digest. Digest is more secure as the users password is never sent over the wire.


Specifies a different directory to check for error pages. If the error page is not found, will still check the global error directory.


Specify an alternate CGI directory to check for CGI files.


Specifies that the index files can be ran for unlocated pages in the current directory. This effecively works like a custom 404 page.


Specifies the socket address of a FastCGI listener in either <Address>:<Port> format (e.g. or unix:/path/to/unix/socket format. Should be used with wildcard sections like this:


See php for details on using with PHP.


Specifies a Javascript snippet which can modify the http_request.request_string. This allows internal redirects like the RewriteRule feature in Apache .htaccess files. The key must *begin* with the string “Rewrite” which may be followed by any legal INI key characters. The order of execution is not guaranteed.

RewriteDetail=var n=http_request.request_string.replace(/_detail\/(.*)/,"lib/exe/detail.php?media=$1"); if(n != http_request.request_string) { http_request.request_string=n; true }

If the expression returns “true”, reparses http_request.request_string as an internal redirect.

Added on November 3rd, 2015 to CVS (in 3.17a). (Commit)


A JavaScript snippet which is executed in the same context as Rewrite* lines, but before any Rewrites are executed. This allows load()ing some common code before execution... ie: JSPreExec=load(js.startup_dir+'/rewrite_lib.js');.

Added on November 3rd, 2015 to CVS (in 3.17a).

JavaScript Objects

In addition to the standard JavaScript objects, the web server provides the following:

http_request object

The http_request object contains information from the client that was included during this request. This objects properties are as follows:


Contains extra path information that was included with the request AFTER the URI which identified this script. For example, if the request was for then path_info would contain the string “/test/this”


Contains the HTTP method used to run the script. As of this writing, the available methods are “HEAD”, “GET”, “POST”, and “OPTIONS”


The virtual path that this URI was reached by. This is the portion of the URI from the end of the host to the end of the filename.


This object contains the values of any form data which was submitted with the request. This is an associative “array” of name/value pairs. THE VALUES ARE ARRAYS OF STRINGS. The reason for this is that it is legal and often useful to have multiple form fields with the same name.


If a query string was included, this is the raw, unparsed query string.


As with query_string but for data which was POSTed.

An associative array of header name/value pairs.

Much like the query object, this object contains key/value pairs of set cookies. Once again, this is an array of strings since multiple values for the same key can be set for cookies.


The real OS's complete path to this script.


The ARS string which applies to this request.


The raw request string sent by the client.


The value of the host header for this request.


The virtual host serving this request.


The HTTP version used for this request as a string.


The IP address of the client.


If the web server does host lookups (disabled by default), this is the remote hostname.


“https” if TLS is in use, “http” otherwise.

http_reply object

The http_reply object is used to pass information about the reply back to the Synchronet web server. The properties are as follows:


HTTP status string. The default is generally “200 Ok”


An associative array of headers to include with the reply. The only pre-defined one is “Content-Type” which defaults to “text/html”.


This optional property can be set to “true” to make write()s go directly to the client for HTTP/1.0 connections. This prevents keep-alives from working but generally appears faster to the client. Since HTTP/1.1 requests use chunked mode, this isn't required for HTTP/1.1.

Extra global methods

The web server also adds a new global JavaScript method that requests that the specified cookie be set:

set_cookie(string key, 
         string value 
	   [, time_t expires 
	   [, string domain 
	   [, string path 
	   [, bool secure ]]]])

Extra global variables


The path to the web server's document root directory.

See also: the RootDirectory key under [Web] in sbbs.ini.

XJS files

XJS files, handled by exec/xjs_handler.js are what many people consider to be an easier method of generating SSJS files. XJS files are HTML files with JS commands embedded in them using special tags much like PHP. XJS files are translated on-the-fly to .ssjs files using the same name with .ssjs appended. For example, a file named test.xjs will, when ran, generate a test.xjs.ssjs file.

XJS syntax

In an XJS file, everything not within a special xjs tag is send to the remote host unmodified, and everything inside the xjs tag is interpreted as JS statements to be executed at that point in the file. The xjs tag begins with either “<?xjs” or “<?” and ends with “?>”. A simple example would be:

<html><head><title><?xjs write( ?></title></head>
Your SysOp "<?xjs write(system.operator) ?>" welcomes you to
<?xjs write( ?>

This would send the following web page to the remote system:

<html><head><title>My Brand New BBS</title></head>
Your SysOp "Sysop" welcomes you to
My Brand New BBS

Looping constructs are permitted, however, not using brackets can result in unexpected effects. Because of this, it is reccomended to *always* use brackets with looping and flow control items.

The following example displays the numbers from one to 10.

var i;
for(i=1; i<=10; i++) {
<?xjs write(i) ?><br>
<?xjs } ?>

XJS-specific global methods and properties

The following JavaScript methods and properties are available to XJS files only.


Runs the specified xjs file at the current position. Local variables are NOT visible to xjs_load()ed pages. The filename is assumed to be relative to the including file (or absolute.)


Contains the path that the current xjs script was loaded from and which parameters to xjs_load() are assumed to be relative to. If you change the value of cwd, it will change the location where xjs_load() will check for files.