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): 33 34 """ 35 Initialise the parser object with the given root application-specific 36 'resource' and optional 'authenticator'. 37 """ 38 39 self.webstack_resource = resource 40 self.webstack_authenticator = authenticator 41 42 def parse(self, trans, requestPath): 43 44 """ 45 For the given Webware transaction, 'trans', override the usual servlet 46 factory mechanism and return a servlet which will provide access to the 47 application-specific resources. 48 The 'trans' object - a Webware transaction - is not given to the servlet 49 since such information is available when the 'respond' method is invoked 50 on the servlet. 51 The provided 'requestPath' object is not used, since this information 52 should be available elsewhere. 53 """ 54 55 return WebStackServlet(self.webstack_resource, self.webstack_authenticator) 56 57 # For Webware 0.8.1 and earlier, employ servlet factories and servlets. 58 59 from WebKit.ServletFactory import ServletFactory 60 from WebKit.Servlet import Servlet 61 62 class WebStackServletFactory(ServletFactory): 63 64 """ 65 A servlet factory object producing servlets which provide access to 66 application-specific resources. 67 """ 68 69 def __init__(self, application, resource, file_extensions, authenticator=None): 70 71 """ 72 Initialise the servlet factory with the Webware 'application' and the 73 WebStack root application-specific 'resource'. The 'file_extensions' 74 specified indicate for which files this factory is invoked. An optional 75 'authenticator' is used to control access to the resource. 76 """ 77 78 ServletFactory.__init__(self, application) 79 self.webstack_resource = resource 80 self.file_extensions = file_extensions 81 self.webstack_authenticator = authenticator 82 83 def uniqueness(self): 84 85 """ 86 Return "file" uniqueness - probably the most appropriate response. 87 """ 88 89 return "file" 90 91 def extensions(self): 92 93 """ 94 Return the file extensions supported by this factory. 95 """ 96 97 return self.file_extensions 98 99 def servletForTransaction(self, trans): 100 101 """ 102 Return a servlet which will provide access to the application-specific 103 resources. The 'trans' object - a Webware transaction - is not given to 104 the servlet since such information is available when the 'respond' 105 method is invoked on the servlet. 106 """ 107 108 return WebStackServlet(self.webstack_resource, self.webstack_authenticator) 109 110 # Servlets are common to both solutions. 111 112 class WebStackServlet(Servlet): 113 114 "A servlet which dispatches transactions to application-specific resources." 115 116 def __init__(self, resource, authenticator): 117 118 """ 119 Initialise the servlet with an application-specific 'resource' and 120 'authenticator'. 121 """ 122 123 Servlet.__init__(self) 124 self.webstack_resource = resource 125 self.webstack_authenticator = authenticator 126 127 def respond(self, trans): 128 129 """ 130 Respond to the incoming transaction, 'trans', by dispatching to the 131 application-specific resource. 132 """ 133 134 new_trans = WebStack.Webware.Transaction(trans) 135 if self.webstack_authenticator is None or self.webstack_authenticator.authenticate(new_trans): 136 try: 137 self.webstack_resource.respond(new_trans) 138 except EndOfResponse: 139 pass 140 else: 141 new_trans.set_response_code(401) # Unauthorized 142 new_trans.set_header_value("WWW-Authenticate", '%s realm="%s"' % ( 143 self.webstack_authenticator.get_auth_type(), self.webstack_authenticator.get_realm())) 144 145 new_trans.commit() 146 147 # vim: tabstop=4 expandtab shiftwidth=4