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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 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 try: 80 if self.webstack_authenticator is None or self.webstack_authenticator.authenticate(trans): 81 try: 82 self.webstack_resource.respond(trans) 83 except EndOfResponse: 84 pass 85 except: 86 if self.handle_errors: 87 trans.set_response_code(500) # Internal error 88 else: 89 raise 90 else: 91 trans.set_response_code(401) # Unauthorized 92 trans.set_header_value("WWW-Authenticate", '%s realm="%s"' % ( 93 self.webstack_authenticator.get_auth_type(), self.webstack_authenticator.get_realm())) 94 95 finally: 96 trans.commit() 97 98 default_address = ("", 8080) 99 100 def deploy(resource, authenticator=None, address=None, handle_errors=1): 101 102 """ 103 Deploy the given 'resource', with the given optional 'authenticator', at the 104 given optional 'address', where 'address' is a 2-tuple of the form 105 (host_string, port_integer). 106 107 The optional 'handle_errors' flag (true by default) specifies whether error 108 conditions are handled gracefully. 109 """ 110 111 handler = HandlerFactory(resource, authenticator, handle_errors) 112 server = BaseHTTPServer.HTTPServer(address or default_address, handler) 113 server.serve_forever() 114 115 # vim: tabstop=4 expandtab shiftwidth=4