Changeset 1309
- Timestamp:
- 09/02/06 02:09:33
- Files:
-
- trunk/cherrypy/__init__.py (modified) (1 diff)
- trunk/cherrypy/_cptree.py (modified) (2 diffs)
- trunk/cherrypy/_cpwsgi.py (modified) (4 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/cherrypy/__init__.py
r1307 r1309 16 16 tree = _cptree.Tree() 17 17 from cherrypy._cptree import Application 18 from cherrypy import _cpwsgi as wsgi 18 19 from cherrypy import _cpengine 19 20 engine = _cpengine.Engine() trunk/cherrypy/_cptree.py
r1305 r1309 1 from cherrypy import _cpconfig, _cplogging, _cpwsgi 1 """CherryPy Application and Tree objects.""" 2 3 import sys 4 import cherrypy 5 from cherrypy import _cpconfig, _cplogging 6 from cherrypy._cperror import format_exc, bare_error 7 from cherrypy.lib import http 2 8 3 9 … … 68 74 return scheme + host + self.script_name 69 75 76 def wsgiapp(self, environ, start_response): 77 # This is here instead of __call__ because it's really hard 78 # to overwrite special methods like __call__ per instance. 79 return wsgi_handler(environ, start_response, app=self) 80 70 81 def __call__(self, environ, start_response): 71 return _cpwsgi._wsgi_callable(environ, start_response, app=self) 82 return self.wsgiapp(environ, start_response) 83 84 85 headerNames = {'HTTP_CGI_AUTHORIZATION': 'Authorization', 86 'CONTENT_LENGTH': 'Content-Length', 87 'CONTENT_TYPE': 'Content-Type', 88 'REMOTE_HOST': 'Remote-Host', 89 'REMOTE_ADDR': 'Remote-Addr', 90 } 91 92 def translate_headers(environ): 93 """Translate CGI-environ header names to HTTP header names.""" 94 for cgiName in environ: 95 # We assume all incoming header keys are uppercase already. 96 if cgiName in headerNames: 97 yield headerNames[cgiName], environ[cgiName] 98 elif cgiName[:5] == "HTTP_": 99 # Hackish attempt at recovering original header names. 100 translatedHeader = cgiName[5:].replace("_", "-") 101 yield translatedHeader, environ[cgiName] 102 103 104 def wsgi_handler(environ, start_response, app): 105 request = None 106 try: 107 env = environ.get 108 local = http.Host('', int(env('SERVER_PORT', 80)), 109 env('SERVER_NAME', '')) 110 remote = http.Host(env('REMOTE_ADDR', ''), 111 int(env('REMOTE_PORT', -1)), 112 env('REMOTE_HOST', '')) 113 request = cherrypy.engine.request(local, remote, 114 env('wsgi.url_scheme'), 115 env('ACTUAL_SERVER_PROTOCOL', "HTTP/1.1")) 116 117 # LOGON_USER is served by IIS, and is the name of the 118 # user after having been mapped to a local account. 119 # Both IIS and Apache set REMOTE_USER, when possible. 120 request.login = env('LOGON_USER') or env('REMOTE_USER') or None 121 122 request.multithread = environ['wsgi.multithread'] 123 request.multiprocess = environ['wsgi.multiprocess'] 124 request.wsgi_environ = environ 125 126 request.app = app 127 128 path = env('SCRIPT_NAME', '') + env('PATH_INFO', '') 129 response = request.run(environ['REQUEST_METHOD'], path, 130 env('QUERY_STRING'), 131 env('SERVER_PROTOCOL'), 132 translate_headers(environ), 133 environ['wsgi.input']) 134 s, h, b = response.status, response.header_list, response.body 135 exc = None 136 except (KeyboardInterrupt, SystemExit), ex: 137 try: 138 if request: 139 request.close() 140 except: 141 cherrypy.log(traceback=True) 142 request = None 143 raise ex 144 except: 145 if request and request.throw_errors: 146 raise 147 tb = format_exc() 148 cherrypy.log(tb) 149 if request and not request.show_tracebacks: 150 tb = "" 151 s, h, b = bare_error(tb) 152 exc = sys.exc_info() 153 154 try: 155 start_response(s, h, exc) 156 for chunk in b: 157 # WSGI requires all data to be of type "str". This coercion should 158 # not take any time at all if chunk is already of type "str". 159 # If it's unicode, it could be a big performance hit (x ~500). 160 if not isinstance(chunk, str): 161 chunk = chunk.encode("ISO-8859-1") 162 yield chunk 163 if request: 164 request.close() 165 request = None 166 except (KeyboardInterrupt, SystemExit), ex: 167 try: 168 if request: 169 request.close() 170 except: 171 cherrypy.log(traceback=True) 172 request = None 173 raise ex 174 except: 175 cherrypy.log(traceback=True) 176 try: 177 if request: 178 request.close() 179 except: 180 cherrypy.log(traceback=True) 181 request = None 182 s, h, b = bare_error() 183 # CherryPy test suite expects bare_error body to be output, 184 # so don't call start_response (which, according to PEP 333, 185 # may raise its own error at that point). 186 for chunk in b: 187 if not isinstance(chunk, str): 188 chunk = chunk.encode("ISO-8859-1") 189 yield chunk 72 190 73 191 trunk/cherrypy/_cpwsgi.py
r1278 r1309 1 1 """WSGI interface (see PEP 333).""" 2 2 3 import sys 4 import cherrypy 3 import cherrypy as _cherrypy 5 4 from cherrypy import _cpwsgiserver 6 from cherrypy._cperror import format_exc, bare_error 7 from cherrypy.lib import http 5 from cherrypy.lib import http as _http 8 6 9 10 headerNames = {'HTTP_CGI_AUTHORIZATION': 'Authorization',11 'CONTENT_LENGTH': 'Content-Length',12 'CONTENT_TYPE': 'Content-Type',13 'REMOTE_HOST': 'Remote-Host',14 'REMOTE_ADDR': 'Remote-Addr',15 }16 17 def translate_headers(environ):18 """Translate CGI-environ header names to HTTP header names."""19 for cgiName in environ:20 # We assume all incoming header keys are uppercase already.21 if cgiName in headerNames:22 yield headerNames[cgiName], environ[cgiName]23 elif cgiName[:5] == "HTTP_":24 # Hackish attempt at recovering original header names.25 translatedHeader = cgiName[5:].replace("_", "-")26 yield translatedHeader, environ[cgiName]27 28 29 def _wsgi_callable(environ, start_response, app):30 request = None31 try:32 env = environ.get33 local = http.Host('', int(env('SERVER_PORT', 80)),34 env('SERVER_NAME', ''))35 remote = http.Host(env('REMOTE_ADDR', ''),36 int(env('REMOTE_PORT', -1)),37 env('REMOTE_HOST', ''))38 request = cherrypy.engine.request(local, remote,39 env('wsgi.url_scheme'),40 env('ACTUAL_SERVER_PROTOCOL', "HTTP/1.1"))41 42 # LOGON_USER is served by IIS, and is the name of the43 # user after having been mapped to a local account.44 # Both IIS and Apache set REMOTE_USER, when possible.45 request.login = env('LOGON_USER') or env('REMOTE_USER') or None46 47 request.multithread = environ['wsgi.multithread']48 request.multiprocess = environ['wsgi.multiprocess']49 request.wsgi_environ = environ50 51 request.app = app52 53 path = env('SCRIPT_NAME', '') + env('PATH_INFO', '')54 response = request.run(environ['REQUEST_METHOD'], path,55 env('QUERY_STRING'),56 env('SERVER_PROTOCOL'),57 translate_headers(environ),58 environ['wsgi.input'])59 s, h, b = response.status, response.header_list, response.body60 exc = None61 except (KeyboardInterrupt, SystemExit), ex:62 try:63 if request:64 request.close()65 except:66 cherrypy.log(traceback=True)67 request = None68 raise ex69 except:70 if request and request.throw_errors:71 raise72 tb = format_exc()73 cherrypy.log(tb)74 if request and not request.show_tracebacks:75 tb = ""76 s, h, b = bare_error(tb)77 exc = sys.exc_info()78 79 try:80 start_response(s, h, exc)81 for chunk in b:82 # WSGI requires all data to be of type "str". This coercion should83 # not take any time at all if chunk is already of type "str".84 # If it's unicode, it could be a big performance hit (x ~500).85 if not isinstance(chunk, str):86 chunk = chunk.encode("ISO-8859-1")87 yield chunk88 if request:89 request.close()90 request = None91 except (KeyboardInterrupt, SystemExit), ex:92 try:93 if request:94 request.close()95 except:96 cherrypy.log(traceback=True)97 request = None98 raise ex99 except:100 cherrypy.log(traceback=True)101 try:102 if request:103 request.close()104 except:105 cherrypy.log(traceback=True)106 request = None107 s, h, b = bare_error()108 # CherryPy test suite expects bare_error body to be output,109 # so don't call start_response (which, according to PEP 333,110 # may raise its own error at that point).111 for chunk in b:112 if not isinstance(chunk, str):113 chunk = chunk.encode("ISO-8859-1")114 yield chunk115 7 116 8 … … 121 13 122 14 def parse_request(self): 123 mhs = cherrypy.server.max_request_header_size15 mhs = _cherrypy.server.max_request_header_size 124 16 if mhs > 0: 125 self.rfile = http.SizeCheckWrapper(self.rfile, mhs)17 self.rfile = _http.SizeCheckWrapper(self.rfile, mhs) 126 18 127 19 try: 128 20 _cpwsgiserver.HTTPRequest.parse_request(self) 129 except http.MaxSizeExceeded:21 except _http.MaxSizeExceeded: 130 22 self.simple_response("413 Request Entity Too Large") 131 cherrypy.log(traceback=True)23 _cherrypy.log(traceback=True) 132 24 133 25 def decode_chunked(self): 134 26 """Decode the 'chunked' transfer coding.""" 135 if isinstance(self.rfile, http.SizeCheckWrapper):27 if isinstance(self.rfile, _http.SizeCheckWrapper): 136 28 self.rfile = self.rfile.rfile 137 mbs = cherrypy.server.max_request_body_size29 mbs = _cherrypy.server.max_request_body_size 138 30 if mbs > 0: 139 self.rfile = http.SizeCheckWrapper(self.rfile, mbs)31 self.rfile = _http.SizeCheckWrapper(self.rfile, mbs) 140 32 try: 141 33 return _cpwsgiserver.HTTPRequest.decode_chunked(self) 142 except http.MaxSizeExceeded:34 except _http.MaxSizeExceeded: 143 35 self.simple_response("413 Request Entity Too Large") 144 cherrypy.log(traceback=True)36 _cherrypy.log(traceback=True) 145 37 return False 146 38 … … 164 56 165 57 def __init__(self): 166 server = cherrypy.server58 server = _cherrypy.server 167 59 sockFile = server.socket_file 168 60 if sockFile: … … 174 66 # We could just pass cherrypy.tree, but by passing tree.apps, 175 67 # we get correct SCRIPT_NAMEs as early as possible. 176 s.__init__(self, bind_addr, cherrypy.tree.apps.items(),68 s.__init__(self, bind_addr, _cherrypy.tree.apps.items(), 177 69 server.thread_pool, 178 70 server.socket_host,

