1 #!/usr/bin/env python 2 3 """ 4 BaseHTTPRequestHandler adapter. 5 6 Copyright (C) 2004, 2005 Paul Boddie <paul@boddie.org.uk> 7 8 This library is free software; you can redistribute it and/or 9 modify it under the terms of the GNU Lesser General Public 10 License as published by the Free Software Foundation; either 11 version 2.1 of the License, or (at your option) any later version. 12 13 This library is distributed in the hope that it will be useful, 14 but WITHOUT ANY WARRANTY; without even the implied warranty of 15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 Lesser General Public License for more details. 17 18 You should have received a copy of the GNU Lesser General Public 19 License along with this library; if not, write to the Free Software 20 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 21 """ 22 23 import WebStack.BaseHTTPRequestHandler 24 import BaseHTTPServer 25 from WebStack.Generic import EndOfResponse 26 27 class HandlerFactory: 28 29 "A factory class creating WebStack dispatcher objects." 30 31 def __init__(self, resource, authenticator=None, handle_errors=1): 32 33 """ 34 Initialise the root application-specific 'resource' and optional 35 'authenticator'. The optional 'handle_errors' parameter (if true) causes 36 handlers to deal with uncaught exceptions cleanly. 37 """ 38 39 self.webstack_resource = resource 40 self.webstack_authenticator = authenticator 41 self.handle_errors = handle_errors 42 43 def __call__(self, request, client_address, server): 44 45 "Act as a factory for the server objects." 46 47 handler = Handler(request, client_address, server, self.webstack_resource, 48 self.webstack_authenticator, self.handle_errors) 49 return handler 50 51 class Handler(BaseHTTPServer.BaseHTTPRequestHandler): 52 53 "A class dispatching requests to WebStack resources." 54 55 def __init__(self, request, client_address, server, resource, authenticator, handle_errors): 56 57 """ 58 Initialise the root application-specific 'resource' and 'authenticator'. 59 Where 'handle_errors' is true, uncaught exceptions are dealt with by the 60 handler. 61 """ 62 63 self.webstack_resource = resource 64 self.webstack_authenticator = authenticator 65 self.handle_errors = handle_errors 66 BaseHTTPServer.BaseHTTPRequestHandler.__init__(self, request, client_address, server) 67 68 def handle(self): 69 70 "Dispatch the request to the root application-specific resource." 71 72 # NOTE: Overriding and trimming back the method's functionality. 73 74 self.raw_requestline = self.rfile.readline() 75 if not self.parse_request(): # An error code has been sent, just exit 76 return 77 78 trans = WebStack.BaseHTTPRequestHandler.Transaction(self) 79 if self.webstack_authenticator is None or self.webstack_authenticator.authenticate(trans): 80 try: 81 self.webstack_resource.respond(trans) 82 except EndOfResponse: 83 pass 84 except: 85 if self.handle_errors: 86 trans.set_response_code(500) # Internal error 87 else: 88 raise 89 else: 90 trans.set_response_code(401) # Unauthorized 91 trans.set_header_value("WWW-Authenticate", '%s realm="%s"' % ( 92 self.webstack_authenticator.get_auth_type(), self.webstack_authenticator.get_realm())) 93 94 trans.commit() 95 96 default_address = ("", 8080) 97 98 def deploy(resource, authenticator=None, address=None, handle_errors=1): 99 100 """ 101 Deploy the given 'resource', with the given optional 'authenticator', at the 102 given optional 'address', where 'address' is a 2-tuple of the form 103 (host_string, port_integer). 104 105 The optional 'handle_errors' flag (true by default) specifies whether error 106 conditions are handled gracefully. 107 """ 108 109 handler = HandlerFactory(resource, authenticator, handle_errors) 110 server = BaseHTTPServer.HTTPServer(address or default_address, handler) 111 server.serve_forever() 112 113 # vim: tabstop=4 expandtab shiftwidth=4