Mini Server Internals
This document describes some of the design details of the W3C Mini Server
Startup and Main Loop
The Server needs the following things before being ready for serving requests:
- It starts up the W3C Reference Library
- It sets up a set of protocol modules. A HTTP server needs a HTTP server module and a FILE access
module. A proxy server also needs a HTTP client module
- It enables a set of converters that can handle basic MIME, multipart etc.
- It then looks for configuration options, like command line options, rule files and maybe
environment variables.
- It registers dialog handling callback functions that can generate error messages back to the
client.
- It registers a server handler that starts a Library server request
- It registers a timeout handler on the connection to the client. The timeout period is the same
for keeping persistent connections open and for readin a request. This is a compromise when we are
using the select call as our timer.
- Now it is ready to start listening on the specified port using a non-blocking socket (the server
socket). This is done by going into the main loop which in this case is identical to the internal
event loop in the Library.
Handling a request
Event Loop
- When the event loop announces an event on the server socket, the server handler is called to
handle the request
Server Handler
- A HTServDocument() request is issued to the request manager with the created request object and
the access scheme (HTTP) by which we want to serve the request
- If not more connection are to be accepted then the connection request can be ignored and no
action is taken.
Request Manager
- The Request verifies the request and calls the Net manager for a new server object
Net Manager
- The Net manager creates a new Net object which then in turn finds a suitable callback event
function function (for example HTServHTTP) and starts the request
Event Call Back
- The connection is accepted by the callback function.
- If a connection is accepted then a new request object is created. This object lives as long as
the connection which may contain multiple requests/responses if the client supports persistent
connections.
- The HTServHTTP module sets up the I/O read buffer and a HTTPReceive stream to read the first
line of the request. Then it starts reading the non-blocking socket.
- The HTTPReceive stream identifies the METHOD, the URI, and the VERSION in the
Request-Line of the HTTP request. It matches the METHOD against the global set of acceptable methods
and sees whether it can serve the request or not.
- When we have the URI we create an anchor object
- If we decide on looking for the URI, we create a new Request object and do a HTLoadAnchor with
the URI request anchor. By setting up appropriate pass rules in the config file, we can decide how
to serve the request, for example by proxying it, sending it to a gateway, or to serve it from local
disk. We may also have the object in memory as a HyperDoc object hanging of the Anchor
object.
- A HTTPResponse stream is chosen as a function of the VERSION information. This stream
may either be connected directly to the server request or to a the new request object
created in the previous item.
- One of the differences between a server and a client applications is that the MIME parser
doesn't call the stream stack when the header has been parsed. The reason is that we don't want to
set up a streamstack and start reading before we actually know whether we accept the data or not.
Generate a Response
- When the HTTPResponse stream gets data first time it looks for any error stack in the request
object. If no stack is available then take "200 OK". Otherwise it takes the error stream and
generates an error code formated according to the protocol VERSION in use.
Restart the Server
The server can be restarted in which case we flushes the memory cache of ducuments and rereads the
rule file.
Henrik Frystyk libwww@w3.org, December 1995