Setting Up And Configuring TWS

TWS is very easy to install and configure. Basically all you have to do three simple things:

  1. Download a precompiled binary.

  2. Run the binary.

  3. Use your favorite web browser to configure TWS using built-in configuration web pages.

The details are provided below. The only moderately challenging part is step 3, and so a discussion of that step comprises most of what follows.

Step 1: Download The Binaries

Precompiled binaries for TWS are available at TWS is a stand-alone program that does not depend on any outside DLL or shared library, so it should work on any Linux or Windows system.

The precompiled binary for windows comes as a ZIP archive. On Linux, the precompiled binary is compressed using BZIP2. In either case, you will need to unpack the binary before you try to run it, of course. TWS keeps a record of its configuration in a file named tws.conf located in the same directory as the executable. So if you want to be able to change the configuration of the TWS server, you need to place the executable in a directory that has write permission.

If you need to compile TWS from sources, you can also download the source code from the same website. Just edit the Makefile to suit your needs and then type "make". At this time, TWS will only build on a Unix host environment - the windows binaries are constructed using a cross-compiler. If you want to compile from sources and only have Windows machines available, you should acquire a copy of the Cygwin environment for windows first. (Use your search engine to find it.)

Step 2: Running The Binary

On Windows, just double-click on the TWS icon in Windows Explorer to launch the web server. By default, the web server listens for inbound connections on port 80. You can change this using the "-port" command-line option if you like.

On Linux (and most other Unixes), you must either launch the TWS server as root or use the "-port" command-line option specify a high-number TCP port to listen on. Linux will not allow any user other than root to open a listening TCP socket on a port number less than 1024. So if you are not root and you try to launch TWS with the default port number of 80, it will fail

For experimentation, it is easy to launch the server on a high-numbered port, like this:

./tws -port 8080

If you launch TWS as root, it will automatically convert to an unprivileged user before accepting any HTTP requests. You can specify the unprivileged user using the "-user" option, like this:

./tws -user nobody

If you omit the "-user" option, TWS will select an unprivileged user on its own. Its first choice is the user who owns the tws.conf configuration file located in the same directory as the executable. If that file does not exist, it tries various usernames like "nobody", "guest", "httpd", "http", and "www". If none of those work, it uses the numeric user ID of 1000.

On UNIX systems, TWS does a "chroot" to the directory the contains the executable in order to place itself in a chroot jail prior to accepting any HTTP requests. This prevents the server from accessing any files outside of the directory containing the TWS executable. You can override this behaviour using the "-chroot" command-line option. The argument to the -chroot option should be the name of the directory that the server will chroot into. The TWS executable must be able to access itself, so if you specify a chroot directory that does not contain the TWS executable the server will fail with a (cryptic) error message. You can disable the chroot by specifying a chroot directory of "/". Like this:

./tws -chroot /

Step 3: Configuring The New Web Server

TWS is configured using a web browser to access configuration pages that are built into the server. To access the built-in configuration pages, start a web browser on the same machine as the web server is running and point the web browser to


If you are running the TWS server on a non-standard TCP port using the "-port" command-line option, then you need to specify the port number after "localhost". Like this:


Note that you must run the web browser on the same machine as the TWS server. This is a security precaution designed to prevent unauthorized users from altering the TWS configuration. By default, the built-in configuration pages can only be accessed from a web-browser running on the same machine as the web-server. You can change this later to allow configuration changes with password access, if you like. But when it first comes up, TWS is configured to used host-based authentication.

Take note: on a multi-user operating system like Linux, the default host-based authentication scheme is still vulnerable to attack by other local users. So you should consider changing to password-based authentication at the earliest opportunity. Instructions on how to do this are given below.


TWS's built-in configuration pages are self-explanatory once you understand how the dispatcher works. So rather than spend time describing the obvious, this document will focus on the dispatch algorithm that TWS uses and leave the rest as an exercise for the reader.

TWS uses the word "dispatch" to mean the algorithm that analyzes an incoming URL to figure out:

  1. whether or not to grant access to the requested page,
  2. what disk file to use to generate the reply,
  3. how to process the disk file, and
  4. what MIME-type to use for the reply.

The key to this process in TWS is the dispatch and MIME tables. You can see the dispatch table by clicking on the "Dispatch" notebook tab of the configuration page and the MIME table by clicking on the "MIME" notebook tab.

We will describe the operation of the dispatcher using an example. Suppose the incoming URL is this:


The first thing that happens is that a hostname and request path are extracted from the request URL. In the example, the hostname is localhost. (The :8080 suffix is ignored by the dispatcher.) The request path is /config/pw/medit. These are the only features of the request URL that the dispatcher uses. The query string ("?oe=bz2") is used elsewhere but is ignored by the dispatcher. The filename suffix (.html) is ignored completely.

After finding the hostname and request path, TWS scans the dispatcher table from top to bottom looking for any entry where the hostname matches the Virtual Server Name and where the Resource Prefix is a prefix of the request path. Blank Virtual Server Name entries on in the dispatch table will match any hostname. If no match is found, then TWS generates a NOT FOUND error as its reply. If a match is found, then the Document Root, Authentication Realm and Namespace for that match are recorded and used in subsequent steps.

If an Authentication Realm is defined for the matching entry, then access to the page is restricted to users who have supplied a valid user ID and password. An UNAUTHORIZED error will be generated if this is not the case. This will provoke most web browsers to prompt the user for a valid user ID and password. You can create new users IDs and authentication realms by visiting the "Access" and "Users" notebook tabs of the built-in configuration page.

If authentication is successful, the next step is to produce a document name. The document name is constructed by removing the Resource Prefix from the request path and replacing it with the Document Root. Suppose in our example that the Document Root was /-builtin-/config. Then the document name would become /-builtin-/config/pw/medit.

If the document name ends with a "/" character, then "index" is appended automatically. So, for example, if the original request URL had been just


Then the document name would become /-builtin-/config/index.

The next step is to use the document name to search for a content file. TWS scans the disk looking for files with the same base name as the document name but with any file suffix. Usually there is only one match, but if more than one file matches the document name, then the first file in lexical order is used. The matching file is call the "content file". If no content file is found, then the right-most name in the path is changed to "notfound" and the search repeats. If still no content file is found, TWS returns a NOT FOUND error to the user.

Assuming a content file is found, the next step is to determine the default MIME-type of the content file and whether or not the content file should be processed for dynamic content. This is accomplished by extracting the filename suffix from the content file and looking it up in the MIME-type table.

The MIME-type table tells the dispatcher two things about this request: (1) the default MIME-type of the response, and (2) whether to process the content file for scripts or to return the content file to the requester as-is. The first piece of information comes from the MIME-Type column of the MIME-type table. The second comes from the Content Handler column. If the Content Handler is "static", then the content file is returned to the users exactly as it is found on the disk. If the Content Handler is "dynamic", then TWS first tries to execute any TCL scripts that are embedded in the content file. Any such TCL scripts are executed in the TCL namespace that was specified by the dispatcher table.

The default MIME-Type is always the actual MIME-Type for static content. But TCL scripts embedded in dynamic content can change the MIME-Type if they want.

An important point: Notice that TWS uses the filename suffix of the content file, not the request URL, as the key to the MIME-type table. The filename suffix of the request URL is completely ignored. This is one area where TWS differs from other web servers, but it is also an area where TWS gives the web site administrator additional control and flexibility. Because the MIME-type table is controlled by the content file extension, you can change the MIME-type and Content Handler for a URL without having to modify the URL itself. All you have to do is change the suffix on the content file. You do not need to modify any hyperlinks.

Dispatcher Summary

Are you confused by all of the above? There is a lot of detail, but the underlying concept is simple. Once you understand what is going on, you will find that TWS is easy to configure and administer. To aid the learning process, here is a quick summary of the steps the dispatcher goes through in processing an incoming URL:

Dispatcher Action Example
Step 0 Web browser sends an HTTP request to the TWS server http://localhost:8080/config/pw/medit.html?oe=bz2
Step 1 The dispatcher extracts the hostname and request path hostname = localhost
request-path = /config/pw/medit
Step 2 Scan the dispatch table looking for the first entry where the hostname matches the Virtual Server Name and the Resource Prefix is a prefix of the request path. Find the corresponding Document Root, Authentication Realm, and Namespace. Document Root = /-builtin-/config
Authentication Realm = (nil)
Namespace = ::twscfg
Step 3 If an Authentication Realm is defined, make sure the request contains valid credentials.  
Step 4 Replace the Resource Prefix with the Document Root to find the document name. document name = /-builtin-/config/pw/medit
Step 5 Locate a content file that matches the document name content file = /-builtin-/config/pw/medit.tws
Step 6 Use the file suffix of the content file to look up a Content Handler and MIME-Type in the MIME-type table. Content Handler = dynamic
MIME Type = text/html

Built-In Content

In the examples above, the document name began with the directory "/-builtin-/". This is not a real directory on the disk. It is a ZIP archive appended to the TWS executable. Whenever a document name begins with /-builtin-/ the contents of the ZIP archive are consulted instead of the disk drive. This is how the configuration pages for TWS are built into the server itself - they are just files contained in the ZIP archive. You can see this by using an utility like pkunzip or unzip to list the contents of the ZIP archive appended to TWS. You will find this archive contains a file named config/pw/medit.tws. It is this file in the ZIP archive, not a real disk file, that is used as the content file in the example.

You are free to add new content files to the ZIP archive attached to TWS if you want. By so doing, you can create your own custom, stand-alone web applications. You can also modify the files that implement the existing configuration pages for TWS if you like.

Contents This page was last modified on 2001/02/17 21:26:50 GMT