1 #!/usr/bin/env python 2 3 """ 4 BaseHTTPRequestHandler adapter. 5 """ 6 7 import WebStack.BaseHTTPRequestHandler 8 import BaseHTTPServer 9 from WebStack.Generic import EndOfResponse 10 11 class HandlerFactory: 12 13 "A factory class creating WebStack dispatcher objects." 14 15 def __init__(self, resource, authenticator=None, handle_errors=1): 16 17 """ 18 Initialise the root application-specific 'resource' and optional 19 'authenticator'. The optional 'handle_errors' parameter (if true) causes 20 handlers to deal with uncaught exceptions cleanly. 21 """ 22 23 self.webstack_resource = resource 24 self.webstack_authenticator = authenticator 25 self.handle_errors = handle_errors 26 27 def __call__(self, request, client_address, server): 28 29 "Act as a factory for the server objects." 30 31 handler = Handler(request, client_address, server, self.webstack_resource, 32 self.webstack_authenticator, self.handle_errors) 33 return handler 34 35 class Handler(BaseHTTPServer.BaseHTTPRequestHandler): 36 37 "A class dispatching requests to WebStack resources." 38 39 def __init__(self, request, client_address, server, resource, authenticator, handle_errors): 40 41 """ 42 Initialise the root application-specific 'resource' and 'authenticator'. 43 Where 'handle_errors' is true, uncaught exceptions are dealt with by the 44 handler. 45 """ 46 47 self.webstack_resource = resource 48 self.webstack_authenticator = authenticator 49 self.handle_errors = handle_errors 50 BaseHTTPServer.BaseHTTPRequestHandler.__init__(self, request, client_address, server) 51 52 def handle(self): 53 54 "Dispatch the request to the root application-specific resource." 55 56 # NOTE: Overriding and trimming back the method's functionality. 57 58 self.raw_requestline = self.rfile.readline() 59 if not self.parse_request(): # An error code has been sent, just exit 60 return 61 62 trans = WebStack.BaseHTTPRequestHandler.Transaction(self) 63 if self.webstack_authenticator is None or self.webstack_authenticator.authenticate(trans): 64 try: 65 self.webstack_resource.respond(trans) 66 except EndOfResponse: 67 pass 68 except: 69 if self.handle_errors: 70 trans.set_response_code(500) # Internal error 71 else: 72 raise 73 else: 74 trans.set_response_code(401) # Unauthorized 75 trans.set_header_value("WWW-Authenticate", '%s realm="%s"' % ( 76 self.webstack_authenticator.get_auth_type(), self.webstack_authenticator.get_realm())) 77 78 trans.commit() 79 80 # vim: tabstop=4 expandtab shiftwidth=4