## PLT Web Server: Servlet Interface

Instead of serving files from a special directory verbatim, the Web server executes the contained Scheme code and serves the output. By default, the special directory is named "servlets" within the "default-web-root" of the "web-server" collection directory. Each file in that directory must evaluate to a servlet. A servlet is a `unit/sig` that imports the `servlet^` signature and exports nothing. (Search in `help-desk` for more information on `unit/sig` and on signatures.) To construct a `unit/sig` with the appropriate imports, the servlet must require the two modules providing`unit/sig`s and the `servlet^` signature:

> `

>     (require (lib "unitsig.ss")
>              (lib "servlet-sig.ss" "web-server"))
>     (unit/sig ()
>       (import servlet^)

> ...insert servlet code here...`)``

The last value in the `unit/sig` must be a response to an HTTP request.

A `Response` is one of the following:

- an `X-expression` representing HTML
  (Search for XML in `help-desk`.)
- a `(listof string)` where
  - The first string is the mime type (often "text/html", but see RFC 2822 for other options).The rest of the strings provide the document's content.
- `(make-response/full` code message seconds mime extras body`)` where
  - code is a natural number indicating the HTTP response code
  - message is a string describing the code to a human
  - seconds is a natural number indicating the time the resource was created. Use (current-seconds) for dynamically created responses.
  - mime is a string indicating the response type.
  - extras is a `(listof (cons symbol string))` containing extra headers for redirects, authentication, or cookies.
  - body is a `(listof string)`

Evaluating `(require (lib "servlet-sig.ss" "web-server"))` loads the `servlet^` signature consisting of the following imports:

- initial-request : `request`, where a request is
  `(make-request method uri headers bindings host-ip client-ip)`, where
  - method : `(Union 'get 'post)`
  - uri : `URL`
    see the `net` collection in `help-desk` for details
  - headers : `(listof (cons symbol string))`
    optional HTTP headers for this request
  - bindings : `(listof (cons symbol string))`
    name value pairs from the form submitted or the query part of the URL.

The `path` part of the URL suplies the file path to the servlet relative to the "servlets" directory. However, paths may also contain extra path components that servlets may use as additional input. For example all of the following URLs refer to the same servlet:

- `http://www.plt-scheme.org/servlets/my-servlet`
- `http://www.plt-scheme.org/servlets/my-servlet/extra`
- `http://www.plt-scheme.org/servlets/my-servlet/extra/directories`

The above imports support handling a single input from a Web form. To ease the development of more interactive servlets, the `servlet^` signature also provides the following functions:

- `send/suspend : (str -> Response) -> request`

The argument, a function that consumes a string, is given a `URL` that can be used in the document. The argument function must produce a response corresponding to the document's body. Requests to the given `URL` resume the computation at the point `send/suspend` was invoked. Thus, the argument function normally produces an HTML form with the "action" attribute set to the provided `URL`. The result of `send/suspend` represents the next request.

- `send/finish : Response ->` doesn't return
  This provides a convenient way to report an error or otherwise produce a final response. Once called, all URLs generated by send/suspend become invalid. Calling send/finish allows the system to reclaim resources consumed by the servlet.
- `adjust-timeout! : Nat -> Void`
  The server will shutdown each instance of a servlet after an unspecified default amount of time since the last time that servlet instance handled a request. Calling adjust-timeout! allows programmers to choose this number of seconds. Larger numbers consume more resources while smaller numbers force servlet users to restart computations more often.

The `servlet-helpers` module, required with

> `(require (lib "servlet-helpers.ss" "web-server"))`

provides a few additional functions helpful for constructing servlets:

- `extract-binding/single : sym (listof (cons sym str)) -> str`This extracts a single value associated with sym in the form bindings. If multiple or zero values are associated with the name, it raises an exception.
- extract-bindings : sym (listof (cons sym str)) -> (listof str)returns a list of values assocaited with the name sym.
- `extract-user-pass : (listof (cons sym str)) -> (U #f (cons str str))`
  `(define (extract-user-pass headers) ...)`Servlets may easily implement password based authentication by extracting password information from the HTTP headers. The return value is either a pair consisting of the username and password from the headers or #f if no password was provided.

### Special URLs

The Web server caches passwords and servlets for performance reasons. Requesting the URL

> `http://my-host/conf/refresh-passwords`

reloads the password file. After updating a servlet, loading the URL

> `http://my-host/conf/refresh-servlets`

causes the server to reload each servlet on the next invocation. This loses any per-servlet state (not per servlet instance state) computed before the unit invocation.

The Web server's garbage collect may be invoked at the URL:

> `http://my-host/conf/collect-garbage`

Examples of Servlets

Powered by