April 2024 - This site, and Kamaelia are being updated. There is significant work needed, and PRs are welcome.

Kamaelia.Protocol.HTTP.HTTPServer

HTTP Server

The fundamental parts of a webserver - an HTTP request parser and a request handler/response generator. One instance of this component can handle one TCP connection. Use a SimpleServer or similar component to allow several concurrent HTTP connections to the server.

Example Usage

def createhttpserver():
return HTTPServer(HTTPResourceGlue.createRequestHandler)

SimpleServer(protocol=createhttpserver, port=80).run()

This defines a function which creates a HTTPServer instance with HTTPResourceGlue.createRequestHandler as the request handler component creator function. This function is then called by SimpleServer for every new TCP connection.

How does it work?

HTTPServer creates and links to a HTTPParser and HTTPRequestHandler component. Data received over TCP is forwarded to the HTTPParser and the output of HTTPRequestHandler forwarded to the TCP component's inbox for sending.

See HTTPParser (in HTTPParser.py) and HTTPRequestHandler (below) for details of how these components work.

HTTPServer accepts a single parameter - a request handler function which is passed onto and used by HTTPRequestHandler to generate request handler components. This allows different HTTP server setups to run on different ports serving completely different content.

HTTP Request Handler

HTTPRequestHandler accepts parsed HTTP requests (from HTTPParser) and outputs appropriate responses to those requests.

How does it work?

HTTPServer creates 2 subcomponents - HTTPParser and HTTPRequestHandler which handle the processing of requests and the creation of responses respectively.

Both requests and responses are handled in a stepwise manner (as opposed to processing a whole request or response in one go) to reduce latency and cope well with bottlenecks.

One request handler (self.handler) component is used per request - the particular component instance (including parameters, component state) is picked by a function called createRequestHandler - a function specified by the user. A suitable definition of this function is available in HTTPResourceGlue.py.

Generally you will have a handler spawned for each new request, terminating after completing the sending of the response. However, it is also possible to use a 'persistent' component if you do the required jiggery-pokery to make sure that at any one time this component is not servicing more than one request simultaenously ('cause it wouldn't work).

What does it support?

Components as request handlers (hurrah!).

3 different ways in which the response data (body) can be terminated:

Chunked transfer encoding

This is the most complex of the 3 ways and was introduced in HTTP/1.1. Its performance is slightly worse that the other 2 as multiple length-lines have to be added to the data stream. It is recommended for responses whose size is not known in advance as it allows keep-alive connections (more than one HTTP request per TCP connection).

Explicit length

This is the easiest of the 3 ways but requires the length of the response to be known before it is sent. It uses a header 'Content-Length' to indicate this value. This method is prefered for any response whose length is known in advance.

Connection: close

This method closes (or half-closes) the TCP connection when the response is complete. This is highly inefficient when the client wishes to download several resources as a new TCP connection must be created and destroyed for each resource. This method is retained for HTTP/1.0 compatibility. It is however preferred for responses that do not have a true end, e.g. a continuous stream over HTTP as the alternative, chunked transfer encoding, has poorer performance.

The choice of these three methods is determined at runtime by the characteristics of the first response part produced by the request handler and the version of HTTP that the client supports (chunked requires 1.1 or higher).

What may need work?
  • HTTP standards-compliance (e.g. handling of version numbers for a start)

  • Requests for byte ranges, cache control (though these may be better implemented

    in each request handler)

  • Performance tuning (also in HTTPParser)

  • Prevent many MBs of data being queued up because TCPClient finds it has a slow

    upload to the remote host


Kamaelia.Protocol.HTTP.HTTPServer.HTTPServer

prefab: HTTPServer

HTTPServer() -> new HTTPServer component capable of handling a single connection

Arguments:
-- createRequestHandler - a function required by HTTPRequestHandler that
creates the appropriate request-handler component for each request, see HTTPResourceGlue

Feedback

Got a problem with the documentation? Something unclear that could be clearer? Want to help improve it? Constructive criticism is very welcome - especially if you can suggest a better rewording!

Please leave you feedback here in reply to the documentation thread in the Kamaelia blog.

-- Automatic documentation generator, 05 Jun 2009 at 03:01:38 UTC/GMT