Package glass :: Module HTTPServer :: Class _HTTPServer
[show private | hide private]
[frames | no frames]

Class _HTTPServer

BaseServer --+    
             |    
     TCPServer --+
                 |
                _HTTPServer


This is a replacement for BaseHTTPServer.HTTPServer.

It does all the same work BaseHTTPServer.HTTPServer does. However, instead of inheriting from something like SocketServer.ThreadingTCPServer, it inherits directly from SocketServer.TCPServer and accepts a servertype for creating sockets and threads. This is necessary to support new threading models and socket types.

This whole class is a move away from the design espoused by SocketServer toward a design suggested by Paul Clegg. Specifically, instead of using mixins for the various threading models, factories are used for both socket and thread creation.

The following attributes are used:

RequestHandlerClass
By default, this is HTTPHandler.
server_ctx
This is ServerContext.
servertype
This is an instance of some class from the servertype package.
is_secure
Return getattr(self.servertype.create_socket, "is_secure", False).
mounts
This is configured using server_ctx.mounts. It is a list of tuples of the form [(url_path, vfs)]. Each vfs is a virtual filesystem object (i.e. an instance of some class from the glass.vfs package). Abstracting the filesystem allows me to do things like use a zip file for a document root.
available_vfs_modules
This is a list of the names of the available vfs modules. When creating self.mounts, I'll try to instantiate each vfs to see if it can handle the given path_translated.

Method Summary
  __init__(self, server_address, RequestHandlerClass, server_ctx, servertype)
Against doctor's orders, I must override (not extend) this.
  __call__(self)
Create, bind, and activate the socket.
  __getattr__(self, attr)
Handle the is_secure attribute.
  close_request(self, request)
HACK: Call TCPServer.close_request, if defined.
  finish_request(self, request, client_address)
Instantiate the RequestHandlerClass and run it.
  finish_request_threaded(self, request, client_address)
Call finish_request, but handle exceptions.
  handle_disconnect_error(self, e, request, client_address)
Handle errors such as errno.EPIPE or errno.ECONNRESET.
  handle_early_socket_error(self, e, request, client_address)
Override this to handle socket errors from get_request.
  handle_error(self, e, request, client_address)
Differentiate errors.
  handle_other_error(self, e, request, client_address)
Handle all other errors that handle_disconnect_error doesn't.
  handle_request(self)
Handle early socket exceptions.
  init_mounts(self)
Setup self.mounts.
  is_disconnect_error(self, e)
Is e an error like errno.EPIPE or errno.ECONNRESET?
  process_request(self, request, client_address)
Call finish_request_threaded in a new "thread".
  server_bind(self)
Extend server_bind to store the server name and port.
    Inherited from TCPServer
  fileno(self)
Return socket file number.
  get_request(self)
Get the request and client address from the socket.
  server_activate(self)
Called by constructor to activate the server.
  server_close(self)
Called to clean-up the server.
    Inherited from BaseServer
  serve_forever(self)
Handle one request at a time until doomsday.
  verify_request(self, request, client_address)
Verify the request.

Class Variable Summary
int allow_reuse_address = 1                                                                     
list available_vfs_modules = ['Standard', 'Zip']
    Inherited from TCPServer
int address_family = 2                                                                     
int request_queue_size = 5                                                                     
int socket_type = 1                                                                     

Method Details

__init__(self, server_address=('', 80), RequestHandlerClass=None, server_ctx=None, servertype=None)
(Constructor)

Against doctor's orders, I must override (not extend) this.

Specifically, I need to accept and make use of additional parameters as well as split part of __init__ into __call__ for coro safety reasons. Otherwise, this is pretty much like TCPServer.__init__.

server_address
By default, this is ('', 80).
RequestHandlerClass
By default, this is HTTPHandler.
server_ctx
By default, this is an instance of ServerContext.
servertype
By default, this is an instance of the Standard servertype.
Overrides:
SocketServer.TCPServer.__init__

__call__(self)
(Call operator)

Create, bind, and activate the socket.

__getattr__(self, attr)
(Qualification operator)

Handle the is_secure attribute.

is_secure returns getattr(self.servertype.create_socket, "is_secure", False).

close_request(self, request)

HACK: Call TCPServer.close_request, if defined.

It isn't defined in Python 2.0, but it must be done in Python 2.3.

Overrides:
SocketServer.TCPServer.close_request

finish_request(self, request, client_address)

Instantiate the RequestHandlerClass and run it.

In TCPServer.finish_request, instantiating the RequestHandlerClass is sufficient to run it. However, in coro, you can't have anything in an __init__ that may lead to a context switch. SocketServer.BaseRequestHandler.__init__, unsurprisingly, is ignorant of this rule. Hence, we require that the RequestHandlerClass passed to us implement a separate __init__ and __call__ method, both of which will be called here, in order to work around this problem. This is an API change that must apply to coro and non-coro alike since it affects the request handlers.

Overrides:
SocketServer.BaseServer.finish_request

finish_request_threaded(self, request, client_address)

Call finish_request, but handle exceptions.

This is nice because I don't won't exceptions from one "thread" being handled in another "thread".

handle_disconnect_error(self, e, request, client_address)

Handle errors such as errno.EPIPE or errno.ECONNRESET.

By default, they are ignored.

handle_early_socket_error(self, e, request, client_address)

Override this to handle socket errors from get_request.

By default, I output to stderr just to make sure you see something if things are completely messed up.

Beware, request and client_address might each be None.

handle_error(self, e, request, client_address)

Differentiate errors.

Differentiate handle_disconnect_error and handle_other_error.

Overrides:
SocketServer.BaseServer.handle_error

handle_other_error(self, e, request, client_address)

Handle all other errors that handle_disconnect_error doesn't.

Since I don't know what's appropriate for your app, I'll just call TCPServer.handle_error.

handle_request(self)

Handle early socket exceptions.

Call handle_early_socket_error.

Overrides:
SocketServer.BaseServer.handle_request

init_mounts(self)

Setup self.mounts.

Implicitly add the document root as the first member. Pick the right vfs for each path_translated. Make sure each url_path has a trailing slash. If not, add one.

is_disconnect_error(self, e)

Is e an error like errno.EPIPE or errno.ECONNRESET?

Various types of sockets might represent disconnect errors differently. Hopefully, one of the ways I've coded will apply.

process_request(self, request, client_address)

Call finish_request_threaded in a new "thread".

Overrides:
SocketServer.BaseServer.process_request

server_bind(self)

Extend server_bind to store the server name and port.

Overrides:
SocketServer.TCPServer.server_bind

Class Variable Details

allow_reuse_address

Type:
int
Value:
1                                                                     

available_vfs_modules

Type:
list
Value:
['Standard', 'Zip']                                                    

Generated by Epydoc 2.1 on Mon Jan 1 16:36:34 2007 http://epydoc.sf.net