# Tcl Server Reference

##

Basic Configuration

The main Tcl script consists of `package require` commands and module-specific initialization commands. The sample main script is `bin/httpd` in the distribution. The things you may want to change are inbetween the CONFIGURATION and END CONFIGURATION lines in the script.

### Document Root

The document root is the name of the directory on your server machine that corresponds to the root of server's URL hierarchy. This is defined with the `Doc_Root` command:

`Doc_Root /usr/local/htdocs`

With no arguments, `Doc_Root` returns the current root.

If you have additional directories you need to paste into the hierarchy you can use `Doc_AddRoot`. This creates sort of a symbolic link from a URL to some point in your server's file system:

`Doc_AddRoot virtual directory`

The term `virtual` means a URL path like `/cgi-bin` or `/foobar`. The directory is a file pathname like `/export/disk3/foobar`.

### Per-User Directories

If you want users to export their own pages under ~user URLs, then use the `Doc_PublicHtml` command to define what subdirectory of their home is used.

`Doc_PublicHtml public_html`

### Index Files

The `Doc_IndexFile` specifies a pattern for the base name of the index file. The pattern can be an exact name, like "index.html", or a pattern that allows any suffix (e.g., index.*) If more than one file matches the pattern, the most recently modified file is used.

`Doc_IndexFile index.{html,shtml,htm}`

### Log Files

The server generates log files in a standard format that is understood by various log-processing utilities. (If you have special needs you can implement a new log module.) The log files are automatically rotated every day, except that there is only one error log that is always appended. You specify the base name of the log file and a different suffix is appended for the daily logs and the error file:

`Log_SetFile /usr/local/tclhttpd/log:`

The logs are flushed periodically instead of on each log entry, except the error log which is flushed immediately. You can set the period with:

`Log_FlushMinutes minutes`

### Server Name and Port

You set the server's host name and port with the `Httpd_Server` command. This command opens the socket and activates the server:

`Httpd_Server 80 sunscript.sun.com`

If you need to specify the server's own IP address, in case you have multiple servers running on different interfaces, just append the IP address to this command:

`Httpd_Server 80 sunscript.sun.com 152.70.4.123`

If you are going to run several servers you'll need to clone the startup script and run a different Tcl process for each server.

## URL Domain Handlers

The server partitions the URL space into "domains" that are uniquely identified by a prefix of the URL. The longest matching prefix is used. For example, "/" is the prefix of all URLs, but you can also have a "/device" domain and a "/status" domain that are handled by different Tcl procedures. Basic file system service is provided by the Doc domain (i.e., doc.tcl), which makes a call like this:

`Url_PrefixInstall / [list DocDomain $Doc(root)]`

but the CGI domain makes a call like

`Url_PrefixInstall /cgi-bin [list CgiDomain $directory]`

This registers a Tcl procedure that is called each time a request matches the prefix. The longest matching prefix is used to resolve conflicts between prefixes like "/" and "/cgi-bin". The domain handler is invoked like this:

`DocDomain $directory $sock $suffix`

The `$sock` and `$suffix` are added by `Url_Dispatch` when the handler is invoked. The `$directory` was defined at the time `Url_PrefixInstall` was called. A domain handler can be installed with any arguments it needs. The `$sock` is the socket for the connection, and it is used in calls on the Httpd module to return results. The `$suffix` is the part of the URL after the prefix is stripped off.

Sample domain handlers include `DocDomain`, `CgiDomain`, and `DirectDomain`, which can be found in `doc.tcl,` `cgisrv.tcl`, and `direct.tcl`, respectively.

## Application Direct URLs

The Direct module implements a mapping from URLs to Tcl procedure calls. The name of the URL determines the procedure, and the arguments come from query data. Use `Direct_Url` to define the command prefix associated with a URL subtree. For example:

`Direct_Url /status Status` `
Direct_Url /mail Mail`

This declares that URLs beginning with `/status` are handled by Tcl procedures that begin with `Status`, and URLS beginning with `/mail` are handled by Tcl procedures that begin with `Mail`. The URL must match the Tcl procedure exactly. For example:

`proc Status/hello {args} {return hello}`

This defines an implementation for the `/status/hello` URL that returns a page containing the string "hello".

If the procedure has arguments defined, then the `Direct` module looks for those names in the query data posted (or included) with the URL. The `args` parameter is used to collect extra form data. If there is no matching form data then the parameter gets its default value or the empty string. For example, the server defines`proc Mail/formdata {email subject args} { ... }`

If you have an HTML form with `email` and `subject` fields, then you can use `/mail/formdata` as the action URL for your form. The Mail/formdata Tcl procedure is called with `email` and `subject` bound to the values from the form. Any additional fields in the form are collected into `args` as a list that alternates between name and value.

## Document Type Handlers

The Doc domain supports handlers for MIME types. The `mime.types` file establishes a mapping from file suffixes (e.g., `html`) to MIME types (e.g. `text/html`). For example, files with suffix `.shtml` are type `application/x-server-include`. The Doc module checks to see if a handler exists for a type before returning the file. If it exists, the handler is called like this:

`Doc_application/x-server-include $path $suffix $sock`

The `$path` is the absolute pathname of the file. The `$suffix` is the URL suffix. The `$sock` is the socket handle for the connection.

Example handlers include `Doc_application/x-cgi`, `Doc_application/x-imagemap`, `Doc_application/x-tcl-subst`, and `Doc_application/x-server-include`.

## Safe-Tcl in an external process

This is currently broken, and safesrv.tcl and safecgio.tcl need to be updated to the new server core. Instead of putting the Safe-Tcl processing in another file, it is done in a the main process using the "Subst" approach described below.

## HTML+Tcl Templates

The `Doc_Subst` procedure is a handler for `application/x-tcl-subst`. This handler simply reads a file and does a Tcl `subst` on it to replace any embedded Tcl commands and variable references. By default the `subst` is done in the main interpreter so you have to be careful. However, `Doc_Subst` is often used by other handler types that use sessions that are maintained in safe slave interpreters.

For example, a simple `foo.subst` file might contain:

    <h1>Hello World</h1>
    The current time is [clock format [clock seconds]]

## Sessions and Session State

The `Session` module keeps track of session state in slave interpreters. A session has a 4-character ID that is dynamically generated when a new session is created. Sessions work by passing around the session ID in URL requests. For example, a URL that starts a new session looks like:

`/something.special?session=new`

The MIME type handler for `.special` (e.g., `Doc_application/x-whizbang`) must process the query data and then process the named file. When it sees the `session=new` it calls `Session_Create` to create a new slave interpreter for the session and return the ID. If it sees something like

`/something.special?session=3f3b`

Then it calls `Session_Match` to hook up with the existing interpreter state.

The `Doc_application/x-tcl-snmp` is the best example that uses session state. It uses `Url_DecodeQuery` to parse incoming form data, `Session_Match` to hook up to session state, and `SnmpProcess` to handle the form data in an application-specific way. It then falls through to `Doc_Subst` to process the page in the context of the session.