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