1 #!/usr/bin/env python 2 3 """ 4 Twisted adapter. 5 """ 6 7 import WebStack.Twisted 8 from WebStack.Generic import EndOfResponse 9 import twisted.web.resource 10 import twisted.web.server 11 import twisted.internet.reactor 12 13 class Dispatcher(twisted.web.resource.Resource): 14 15 "A class dispatching requests to WebStack resources." 16 17 isLeaf = 1 18 19 def __init__(self, resource, authenticator=None, handle_errors=1): 20 21 """ 22 Initialise the root application-specific 'resource' and optional 23 'authenticator'. The optional 'handle_errors' parameter (if true) causes 24 handlers to deal with uncaught exceptions cleanly. 25 """ 26 27 twisted.web.resource.Resource.__init__(self) 28 self.webstack_resource = resource 29 self.webstack_authenticator = authenticator 30 self.handle_errors = handle_errors 31 32 def getChild(self, path, request): 33 raise NotImplementedError, "getChild" 34 35 def render(self, request): 36 37 "Dispatch the given 'request' to the root application-specific resource." 38 39 trans = WebStack.Twisted.Transaction(request) 40 if self.webstack_authenticator is None or self.webstack_authenticator.authenticate(trans): 41 try: 42 self.webstack_resource.respond(trans) 43 except EndOfResponse: 44 pass 45 except: 46 if self.handle_errors: 47 trans.set_response_code(500) # Internal error 48 else: 49 raise 50 else: 51 trans.set_response_code(401) # Unauthorized 52 trans.set_header_value("WWW-Authenticate", '%s realm="%s"' % ( 53 self.webstack_authenticator.get_auth_type(), self.webstack_authenticator.get_realm())) 54 55 trans.commit() 56 request.finish() 57 return twisted.web.server.NOT_DONE_YET 58 59 default_address = ("", 8080) 60 61 def deploy(resource, authenticator=None, address=None): 62 63 """ 64 Deploy the given 'resource', with the given optional 'authenticator', at the 65 given optional 'address', where 'address' is a 2-tuple of the form 66 (host_string, port_integer). 67 68 NOTE: Twisted only makes use of the port number provided in the 'address'. 69 """ 70 71 address = address or default_address 72 73 top_level = Dispatcher(resource, authenticator) 74 site = twisted.web.server.Site(top_level) 75 twisted.internet.reactor.listenTCP(address[1], site) 76 twisted.internet.reactor.run() 77 78 # vim: tabstop=4 expandtab shiftwidth=4