1 #!/usr/bin/env python 2 3 """ 4 WSGI adapter. 5 """ 6 7 import WebStack.WSGI 8 from WebStack.Generic import EndOfResponse 9 10 class WSGIAdapter: 11 12 "A WSGI adapter class." 13 14 def __init__(self, resource, authenticator=None): 15 16 """ 17 Initialise the adapter with the given WebStack 'resource' and the 18 optional 'authenticator'. 19 """ 20 21 self.resource = resource 22 self.authenticator = authenticator 23 24 def __call__(self, environ, start_response): 25 26 """ 27 Dispatch to the root application-specific 'resource'. Return a list of 28 strings comprising the response body text. 29 """ 30 31 # NOTE: It would be best to give start_response to the transaction so 32 # NOTE: that the underlying response's write method can be used by the 33 # NOTE: transaction directly. Unfortunately, WebStack doesn't provide 34 # NOTE: any means of declaring when the headers have been set and when 35 # NOTE: response body output is the only thing to be subsequently 36 # NOTE: produced. 37 38 trans = WebStack.WSGI.Transaction(environ) 39 40 try: 41 if self.authenticator is None or self.authenticator.authenticate(trans): 42 try: 43 self.resource.respond(trans) 44 except EndOfResponse: 45 pass 46 else: 47 trans.set_response_code(401) # Unauthorized 48 trans.set_header_value("WWW-Authenticate", '%s realm="%s"' % ( 49 self.authenticator.get_auth_type(), self.authenticator.get_realm())) 50 finally: 51 trans.commit() 52 53 # NOTE: Provide sensible messages. 54 # NOTE: Ignoring the write method returned by start_response. 55 56 start_response( 57 "%s WebStack status" % trans.get_response_code(), 58 trans.get_wsgi_headers() 59 ) 60 return [trans.get_wsgi_content()] 61 62 # vim: tabstop=4 expandtab shiftwidth=4