Web Server Support

RScheme's strengths are best revealed when it can be the web server itself.

Connecting the service

To build an actual web server, the first thing to do is to hook up a protocol interpreter to an appropriate TCP/IP socket.

Session Management

Facilities are included to manage sessions in two ways: using cookies, and using virtual subspaces. We could also support the hidden-variable approach, but that is too inconvenient to deploy services based on it and there is no apparent advantage, so we leave that as an exercise for the user.

Web spaces

An web server built using rs.net.http has an internal representation of the shape of the web space it serves. This space is structured mostly as a tree, reflecting the hierarchy of a URL.

When a request comes in, the server starts at the "web root" and walks down the tree, following links labelled by the elements in the request. For example, if a request for the object "/pub/build/" comes in (as, for example, from the URL "http://www.rscheme.org/pub/build/"), then the system will start at the root, follow the "pub" link from there, follow the "build" link from that location, and finally deliver the request to the result of following the "" link from there.

Forms (POST)

A web-enabled service likely has a need to put data into the system. This is typically done with the HTTP POST method.

Queries (GET)

Sometimes it is convenient to encode a request as part of the URL. This shows up as a '?' after the last element in the URL path, as in "/pub/inspect?cr=123", which is a reference to the queryable resource "/pub/inspect" with the parameter "cr" with a value of "123".

As a matter of convention, I reserve this notation for side-effect-free operations (hence, I call them "queries"). For operations which update some persistent representation, I use POST.

Authentication and Security

Some portions of the web space may be protected. There is built-in support for using HTTP-based authentication as well as identd-based authentication.

A protected web node has a value for the protect property. When the web space traversal procedure gets to such a node, the generic function check-protection is invoked on the value of the protect property. Typically, this value will be an instance of <http-protection>, which has a method for doing basic authentication.

(define *confidential* 
  (make <http-protection>
        in-realm: "ABC Inc."
        password-check-proc: my-password-ok?
        use-identd: '("*.abc.com")))

The check-protection method will signal an appropriate condition if the request does not satisfy the security constraints. In the case of HTTP authorization, using in-realm, this condition may be an <http-error> with code 401 (Unauthorized), with appropriate headers to elicit authorization from the web client and/or user.