Ticket #455: wsgi_modifications_on_rev956.diff
-
cherrypy/_cpserver.py
old new 7 7 import warnings 8 8 9 9 import cherrypy 10 from cherrypy import _cphttptools, filters 10 from cherrypy import _cphttptools, filters, _cpwsgi 11 11 from cherrypy.lib import autoreload, profiler, cptools 12 12 13 13 # Use a flag to indicate the state of the application server. … … 41 41 self.onStartThreadList = [] 42 42 self.onStartServerList = [] 43 43 self.onStopThreadList = [] 44 44 45 self.cp_mount_point = '' 46 self.cp_wsgi_app = _cpwsgi.wsgiApp 47 45 48 def start(self, init_only = False, server_class = _missing, **kwargs): 46 49 """Main function. MUST be called from the main thread. 47 50 … … 153 156 on_what = "socket file: %s" % cherrypy.config.get('server.socket_file') 154 157 155 158 # Instantiate the server. 156 self.httpserver = self.httpserverclass() 159 if self.httpserverclass == _cpwsgi.WSGIServer: 160 if self.cp_mount_point: 161 app = None 162 self.httpserver = self.httpserverclass(app) 163 self.httpserver.add_application(self.cp_mount_point, 164 self.cp_wsgi_app) 165 else: 166 self.httpserver = self.httpserverclass(self.cp_wsgi_app) 167 168 else: 169 self.httpserver = self.httpserverclass() 157 170 158 171 # HTTP servers MUST be started in a new thread, so that the 159 172 # main thread persists to receive KeyboardInterrupt's. This -
cherrypy/_cpwsgi.py
old new 148 148 # Request header is parsed 149 149 # We prepare the SizeCheckWrapper for the request body 150 150 self.rfile.bytes_read = 0 151 path = self.environ[" SCRIPT_NAME"]151 path = self.environ["PATH_INFO"] 152 152 if path == "*": 153 153 path = "global" 154 else:155 path = "/" + path156 154 mbs = int(cherrypy.config.get('server.max_request_body_size', 157 155 100 * 1024 * 1024, path=path)) 158 156 self.rfile.maxlen = mbs -
cherrypy/_cpwsgiserver.py
old new 24 24 # de-dupe the list 25 25 socket_errors_to_ignore = dict.fromkeys(socket_errors_to_ignore).keys() 26 26 27 def not_found_app(environ, start_response): 28 status = '404 Not Found' 29 headers = [('Content-type', 'text/html')] 30 start_response(status, headers) 31 sn = environ.get('SCRIPT_NAME', '') 32 pi = environ.get('PATH_INFO', '') 33 rp = (sn + pi) or '/' 34 return ['Nothing found at %s' % rp] 27 35 28 36 class HTTPRequest(object): 29 37 … … 44 52 self.wfile = self.socket.makefile("w", self.bufsize) 45 53 self.sent_headers = False 46 54 55 def _find_sn_pi(self, path): 56 "find SCRIPT_NAME and PATH_INFO for requested path" 57 if path == '*': 58 return '', '*' 59 if path == '/': 60 return '', '/' 61 candidates = [] 62 for loc, app in self.server.apps.iteritems(): 63 if path.startswith(loc): 64 candidates.append(loc) 65 if not candidates: 66 return path, '' #, self.server.err_app 67 if len(candidates) == 1: 68 sn = candidates[0] 69 pi = path[len(sn):] 70 else: 71 sn = max(candidates) 72 pi = path[len(sn):] 73 return sn, pi #, self.server.apps[sn] 74 47 75 def parse_request(self): 48 76 self.sent_headers = False 49 77 self.environ = {} … … 64 92 else: 65 93 qs = "" 66 94 self.environ["REQUEST_METHOD"] = method 67 if path == "*": 68 self.environ["SCRIPT_NAME"] = path 69 else: 70 self.environ["SCRIPT_NAME"] = path[1:] 71 self.environ["PATH_INFO"] = "" 95 sn, pi = self._find_sn_pi(path) 96 self.environ["SCRIPT_NAME"] = sn 97 self.environ["PATH_INFO"] = pi 72 98 self.environ["QUERY_STRING"] = qs 73 99 self.environ["SERVER_PROTOCOL"] = version 74 100 self.environ["SERVER_NAME"] = self.server.server_name … … 151 177 self.server = server 152 178 threading.Thread.__init__(self) 153 179 180 def _get_app(self, mount_point): 181 return self.server.apps.get(mount_point, self.server.err_app) 182 154 183 def run(self): 155 184 try: 156 185 self.ready = True … … 163 192 try: 164 193 request.parse_request() 165 194 if request.ready: 166 response = self.server.wsgi_app(request.environ, 167 request.start_response) 195 mp = request.environ['SCRIPT_NAME'] 196 wsgi_app = self._get_app(mp) 197 response = wsgi_app(request.environ, 198 request.start_response) 168 199 for line in response: 169 200 request.write(line) 170 201 except socket.error, e: … … 188 219 interrupt = None 189 220 RequestHandlerClass = HTTPRequest 190 221 191 def __init__(self, bind_addr, wsgi_app , numthreads=10, server_name=None,192 max=-1, request_queue_size=5 ):222 def __init__(self, bind_addr, wsgi_app=None, numthreads=10, server_name=None, 223 max=-1, request_queue_size=5, err_app=not_found_app): 193 224 ''' 194 225 be careful w/ max 195 226 ''' 196 227 self.requests = Queue.Queue(max) 197 self.wsgi_app = wsgi_app198 228 self.bind_addr = bind_addr 199 229 self.numthreads = numthreads or 1 200 230 if not server_name: … … 202 232 self.server_name = server_name 203 233 self.request_queue_size = request_queue_size 204 234 self._workerThreads = [] 205 235 self.err_app = err_app 236 self.apps = {} 237 if wsgi_app: 238 self.add_application('', wsgi_app) 239 240 def add_application(self, mount_point, app): 241 self.apps[mount_point] = app 242 206 243 def start(self): 207 244 """Run the server forever.""" 208 245 # We don't have to trap KeyboardInterrupt or SystemExit here, … … 303 340 worker.join() 304 341 305 342 self._workerThreads = [] 343 344 if __name__ == '__main__': 345 def hello_app(environ, start_response): 346 status = '200 OK' 347 headers = [('Content-type', 'text/html')] 348 start_response(status, headers) 349 yield '<h1>Hello, World!</h1>\n' 350 keys = environ.keys() 351 keys.sort() 352 for k in keys: 353 yield "%s = %s<br>\n" % (k, environ[k]) 354 355 server = CherryPyWSGIServer(('127.0.0.1', 8080)) 356 server.add_application('/hello', hello_app) 357 server.add_application('/test', hello_app) 358 try: 359 server.start() 360 except KeyboardInterrupt: 361 server.stop() 362

