1 #!/usr/bin/env python 2 3 """ 4 Webware adapter. 5 """ 6 7 import WebStack.Webware 8 from WebStack.Generic import EndOfResponse 9 10 # For Webware releases later than 0.8.1, employ special URLParsers in contexts 11 # for each application in the application server; such parsers create servlets 12 # instead of having servlet factories do that work. 13 14 try: 15 from WebKit.URLParser import URLParser 16 17 except ImportError: 18 19 # NOTE: Using Webware 0.8.1 or earlier. Assume that this really is the case. 20 21 pass 22 23 else: 24 class WebStackURLParser(URLParser): 25 26 """ 27 A custom URL parser which provides access to application-specific resources. 28 Override the 'parse' method for more precise control of servlet 29 instantiation. 30 """ 31 32 def __init__(self, resource, authenticator=None, handle_errors=1): 33 34 """ 35 Initialise the parser object with the given root application-specific 36 'resource' and optional 'authenticator'. The optional 'handle_errors' 37 parameter (if true) causes handlers to deal with uncaught exceptions 38 cleanly. 39 """ 40 41 self.webstack_resource = resource 42 self.webstack_authenticator = authenticator 43 self.handle_errors = handle_errors 44 45 def parse(self, trans, requestPath): 46 47 """ 48 For the given Webware transaction, 'trans', override the usual servlet 49 factory mechanism and return a servlet which will provide access to the 50 application-specific resources. 51 The 'trans' object - a Webware transaction - is not given to the servlet 52 since such information is available when the 'respond' method is invoked 53 on the servlet. 54 The provided 'requestPath' object is not used, since this information 55 should be available elsewhere. 56 """ 57 58 return WebStackServlet(self.webstack_resource, self.webstack_authenticator, 59 self.handle_errors) 60 61 # For Webware 0.8.1 and earlier, employ servlet factories and servlets. 62 63 from WebKit.ServletFactory import ServletFactory 64 from WebKit.Servlet import Servlet 65 66 class WebStackServletFactory(ServletFactory): 67 68 """ 69 A servlet factory object producing servlets which provide access to 70 application-specific resources. 71 """ 72 73 def __init__(self, application, resource, file_extensions, authenticator=None, handle_errors=1): 74 75 """ 76 Initialise the servlet factory with the Webware 'application' and the 77 WebStack root application-specific 'resource'. The 'file_extensions' 78 specified indicate for which files this factory is invoked. An optional 79 'authenticator' is used to control access to the resource. The optional 80 'handle_errors' parameter (if true) causes handlers to deal with 81 uncaught exceptions cleanly. 82 """ 83 84 ServletFactory.__init__(self, application) 85 self.webstack_resource = resource 86 self.file_extensions = file_extensions 87 self.webstack_authenticator = authenticator 88 self.handle_errors = handle_errors 89 90 def uniqueness(self): 91 92 """ 93 Return "file" uniqueness - probably the most appropriate response. 94 """ 95 96 return "file" 97 98 def extensions(self): 99 100 """ 101 Return the file extensions supported by this factory. 102 """ 103 104 return self.file_extensions 105 106 def servletForTransaction(self, trans): 107 108 """ 109 Return a servlet which will provide access to the application-specific 110 resources. The 'trans' object - a Webware transaction - is not given to 111 the servlet since such information is available when the 'respond' 112 method is invoked on the servlet. 113 """ 114 115 return WebStackServlet(self.webstack_resource, self.webstack_authenticator, 116 self.handle_errors) 117 118 # Servlets are common to both solutions. 119 120 class WebStackServlet(Servlet): 121 122 "A servlet which dispatches transactions to application-specific resources." 123 124 def __init__(self, resource, authenticator, handle_errors): 125 126 """ 127 Initialise the servlet with an application-specific 'resource' and 128 'authenticator'. Where 'handle_errors' is true, uncaught exceptions are 129 dealt with by the handler. 130 """ 131 132 Servlet.__init__(self) 133 self.webstack_resource = resource 134 self.webstack_authenticator = authenticator 135 self.handle_errors = handle_errors 136 137 def respond(self, trans): 138 139 """ 140 Respond to the incoming transaction, 'trans', by dispatching to the 141 application-specific resource. 142 """ 143 144 new_trans = WebStack.Webware.Transaction(trans) 145 if self.webstack_authenticator is None or self.webstack_authenticator.authenticate(new_trans): 146 try: 147 self.webstack_resource.respond(new_trans) 148 except EndOfResponse: 149 pass 150 except: 151 if self.handle_errors: 152 new_trans.set_response_code(500) # Internal error 153 else: 154 raise 155 else: 156 new_trans.set_response_code(401) # Unauthorized 157 new_trans.set_header_value("WWW-Authenticate", '%s realm="%s"' % ( 158 self.webstack_authenticator.get_auth_type(), self.webstack_authenticator.get_realm())) 159 160 new_trans.commit() 161 162 # vim: tabstop=4 expandtab shiftwidth=4