Changeset 837
- Timestamp:
- 11/26/05 14:32:53
- Files:
-
- trunk/cherrypy/_cperror.py (modified) (3 diffs)
- trunk/cherrypy/_cphttptools.py (modified) (7 diffs)
- trunk/cherrypy/_cputil.py (modified) (2 diffs)
- trunk/cherrypy/filters/cachefilter.py (modified) (2 diffs)
- trunk/cherrypy/filters/encodingfilter.py (modified) (1 diff)
- trunk/cherrypy/filters/logdebuginfofilter.py (modified) (1 diff)
- trunk/cherrypy/filters/nsgmlsfilter.py (modified) (2 diffs)
- trunk/cherrypy/filters/sessionauthenticatefilter.py (modified) (2 diffs)
- trunk/cherrypy/filters/staticfilter.py (modified) (1 diff)
- trunk/cherrypy/filters/tidyfilter.py (modified) (4 diffs)
- trunk/cherrypy/filters/xmlrpcfilter.py (modified) (4 diffs)
- trunk/cherrypy/lib/cptools.py (modified) (3 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/cherrypy/_cperror.py
r831 r837 107 107 def set_response(self): 108 108 import cherrypy 109 cherrypy.response.status = status = self.status 110 cherrypy.response.headerMap['Content-Type'] = "text/html" 109 response = cherrypy.response 110 response.status = status = self.status 111 response.headerMap['Content-Type'] = "text/html" 111 112 112 113 if status in (300, 301, 302, 303, 307): 113 114 # "The ... URI SHOULD be given by the Location field 114 115 # in the response." 115 cherrypy.response.headerMap['Location'] = self.urls[0]116 response.headerMap['Location'] = self.urls[0] 116 117 117 118 # "Unless the request method was HEAD, the entity of the response … … 124 125 307: "This resource has moved temporarily to <a href='%s'>%s</a>.", 125 126 }[status] 126 cherrypy.response.body = ["<br />\n".join([msg % (url, url) 127 for url in self.urls])] 127 response.body = "<br />\n".join([msg % (u, u) for u in self.urls]) 128 128 elif status == 304: 129 129 # Not Modified. … … 133 133 134 134 # "The 304 response MUST NOT contain a message-body." 135 cherrypy.response.body = []135 response.body = None 136 136 elif status == 305: 137 137 # Use Proxy. 138 138 # self.urls[0] should be the URI of the proxy. 139 cherrypy.response.headerMap['Location'] = self.urls[0]140 cherrypy.response.body = []139 response.headerMap['Location'] = self.urls[0] 140 response.body = None 141 141 else: 142 142 raise ValueError("The %s status code is unknown." % status) trunk/cherrypy/_cphttptools.py
r835 r837 27 27 self.remoteHost = remoteHost 28 28 self.scheme = scheme 29 self.executeMain = True 29 30 30 31 def run(self, requestLine, headers, rfile): … … 77 78 78 79 applyFilters('beforeMain') 79 if cherrypy.response.body is None:80 if self.executeMain: 80 81 self.main() 81 82 … … 231 232 x.args = x.args + (page_handler,) 232 233 raise 233 cherrypy.response.body = iterable(body)234 cherrypy.response.body = body 234 235 return 235 236 except cherrypy.InternalRedirect, x: … … 318 319 319 320 321 class Body(object): 322 """The body of the HTTP response (the response entity).""" 323 324 def __get__(self, obj, objclass=None): 325 if obj is None: 326 # When calling on the class instead of an instance... 327 return self 328 else: 329 return obj._body 330 331 def __set__(self, obj, value): 332 # Convert the given value to an iterable object. 333 if isinstance(value, types.FileType): 334 value = cptools.fileGenerator(value) 335 elif isinstance(value, types.GeneratorType): 336 value = flattener(value) 337 elif isinstance(value, basestring): 338 # strings get wrapped in a list because iterating over a single 339 # item list is much faster than iterating over every character 340 # in a long string. 341 value = [value] 342 elif value is None: 343 value = [] 344 obj._body = value 345 346 347 def flattener(input): 348 """Yield the given input, recursively iterating over each result (if needed).""" 349 for x in input: 350 if not isinstance(x, types.GeneratorType): 351 yield x 352 else: 353 for y in flattener(x): 354 yield y 355 356 320 357 class Response(object): 321 358 """An HTTP Response.""" 359 360 body = Body() 322 361 323 362 def __init__(self): … … 336 375 self.simpleCookie = Cookie.SimpleCookie() 337 376 377 def collapse_body(self): 378 newbody = ''.join([chunk for chunk in self.body]) 379 self.body = newbody 380 return newbody 381 338 382 def finalize(self): 339 383 """Transform headerMap (and cookies) into cherrypy.response.headers.""" … … 361 405 # but allow user code to set Content-Length if desired. 362 406 if self.headerMap.get('Content-Length') is None: 363 content = ''.join([chunk for chunk in self.body]) 364 self.body = [content] 407 content = self.collapse_body() 365 408 self.headerMap['Content-Length'] = len(content) 366 409 … … 429 472 self.status, self.headers, self.body = _cputil.bareError(body) 430 473 431 432 def iterable(body):433 """Convert the given body to an iterable object."""434 if isinstance(body, types.FileType):435 body = cptools.fileGenerator(body)436 elif isinstance(body, types.GeneratorType):437 body = flattener(body)438 elif isinstance(body, basestring):439 # strings get wrapped in a list because iterating over a single440 # item list is much faster than iterating over every character441 # in a long string.442 body = [body]443 elif body is None:444 body = [""]445 return body446 447 def flattener(input):448 """Yield the given input, recursively iterating over each result (if needed)."""449 for x in input:450 if not isinstance(x, types.GeneratorType):451 yield x452 else:453 for y in flattener(x):454 yield ytrunk/cherrypy/_cputil.py
r831 r837 262 262 response.status = status 263 263 content = getErrorPage(status, traceback=tb, message=message) 264 response.body = [content]264 response.body = content 265 265 response.headerMap['Content-Length'] = len(content) 266 266 response.headerMap['Content-Type'] = "text/html" … … 290 290 # Since we are issuing an HTTP error status, we assume that 291 291 # the entity is short, and we should just collapse it. 292 content = ''.join([chunk for chunk in response.body])292 content = response.collapse_body() 293 293 l = len(content) 294 294 if l and l < s: 295 295 # IN ADDITION: the response must be written to IE 296 296 # in one chunk or it will still get replaced! Bah. 297 response.body = [content + (" " * (s - l))] 298 else: 299 response.body = [content] 300 response.headerMap['Content-Length'] = len(response.body[0]) 297 content = content + (" " * (s - l)) 298 response.body = content 299 response.headerMap['Content-Length'] = len(content) 301 300 302 301 def formatExc(exc=None): trunk/cherrypy/filters/cachefilter.py
r814 r837 114 114 cherrypy._cache.totNonModified += 1 115 115 cherrypy.response.status = "304 Not Modified" 116 cherrypy.response.body = []116 cherrypy.response.body = None 117 117 else: 118 118 # serve it & get out from the request … … 131 131 132 132 # Consume the body iterable. Only do this once! 133 body = cherrypy.response. body = [chunk for chunk in cherrypy.response.body]133 body = cherrypy.response.collapse_body() 134 134 135 135 if cherrypy.response.headerMap.get('Pragma', None) != 'no-cache': trunk/cherrypy/filters/encodingfilter.py
r831 r837 21 21 return True 22 22 else: 23 response. body = ''.join([chunk for chunk in response.body])23 response.collapse_body() 24 24 def encode_body(encoding): 25 25 try: 26 response.body = [response.body.encode(encoding)] 26 body = [] 27 for chunk in response.body: 28 body.append(chunk.encode(encoding)) 29 response.body = body 27 30 except UnicodeError: 28 31 # Try the next encoding trunk/cherrypy/filters/logdebuginfofilter.py
r814 r837 23 23 ct = cherrypy.response.headerMap.get('Content-Type').split(';')[0] 24 24 if ct in mimelist: 25 body = ''.join([chunk for chunk in cherrypy.response.body])25 body = cherrypy.response.collapse_body() 26 26 debuginfo = '\n' 27 27 trunk/cherrypy/filters/nsgmlsfilter.py
r814 r837 15 15 # the tidy filter, by its very nature it's not generator friendly, 16 16 # so we just collect the body and work with it. 17 originalBody = ''.join([chunk for chunk in cherrypy.response.body]) 18 cherrypy.response.body = [originalBody] 17 originalBody = cherrypy.response.collapse_body() 19 18 20 19 fct = cherrypy.response.headerMap.get('Content-Type', '') … … 59 58 newBody += "%03d - "%i + cgi.escape(line).replace('\t',' ').replace(' ',' ') + '<br />' 60 59 61 cherrypy.response.body = [newBody]60 cherrypy.response.body = newBody 62 61 trunk/cherrypy/filters/sessionauthenticatefilter.py
r814 r837 51 51 if errorMsg: 52 52 cherrypy.response.body = loginScreen(fromPage, login = login, errorMsg = errorMsg) 53 cherrypy.request.executeMain = False 53 54 else: 54 55 cherrypy.session[sessionKey] = login … … 65 66 if not cherrypy.session.get(sessionKey): 66 67 cherrypy.response.body = loginScreen(cherrypy.request.browserUrl) 68 cherrypy.request.executeMain = False 67 69 return 68 70 69 71 # Everything is OK: user is logged in 70 72 if loadUserByUsername: trunk/cherrypy/filters/staticfilter.py
r814 r837 43 43 44 44 cptools.serveFile(filename) 45 request.executeMain = False 45 46 trunk/cherrypy/filters/tidyfilter.py
r814 r837 23 23 # the tidy filter, by its very nature it's not generator friendly, 24 24 # so we just collect the body and work with it. 25 originalBody = ''.join([chunk for chunk in cherrypy.response.body]) 26 cherrypy.response.body = [originalBody] 25 originalBody = cherrypy.response.collapse_body() 27 26 28 27 fct = cherrypy.response.headerMap.get('Content-Type', '') … … 74 73 newBody += "%03d - "%i + cgi.escape(line).replace('\t',' ').replace(' ',' ') + '<br />' 75 74 76 cherrypy.response.body = [newBody]75 cherrypy.response.body = newBody 77 76 78 77 elif strictXml: … … 94 93 bodyFile = StringIO.StringIO() 95 94 traceback.print_exc(file = bodyFile) 96 cherrypy.response.body = [bodyFile.getvalue()]95 cherrypy.response.body = bodyFile.getvalue() 97 96 98 97 newBody = "Wrong XML:<br />" + cgi.escape(bodyFile.getvalue().replace('\n','<br />')) … … 103 102 newBody += "%03d - "%i + cgi.escape(line).replace('\t',' ').replace(' ',' ') + '<br />' 104 103 105 cherrypy.response.body = [newBody]104 cherrypy.response.body = newBody 106 105 trunk/cherrypy/filters/xmlrpcfilter.py
r836 r837 99 99 so CP2 will find the right method to call for you, 100 100 based on the root's position. 101 before Finalize:101 beforeMain: 102 102 Marshalls cherrypy.response.body to xmlrpc. 103 103 - Until resolved: cherrypy.response.body must be a python source string; … … 171 171 args = virtual_path + cherrypy.request.paramList 172 172 body = page_handler(*args, **cherrypy.request.paramMap) 173 # Don't form an iterable like CP core main() does174 ## cherrypy.response.body = iterable(body)175 173 break 176 174 except cherrypy.InternalRedirect, x: … … 185 183 encoding=encoding, allow_none=0) 186 184 self.respond(body) 185 cherrypy.request.executeMain = False 187 186 188 187 def afterErrorResponse(self): … … 204 203 response = cherrypy.response 205 204 response.status = '200 OK' 206 response.body = [body]205 response.body = body 207 206 response.headerMap['Content-Type'] = 'text/xml' 208 207 response.headerMap['Content-Length'] = len(body) trunk/cherrypy/lib/cptools.py
r807 r837 108 108 if cherrypy.request.headerMap['If-Modified-Since'] == strModifTime: 109 109 response.status = "304 Not Modified" 110 response.body = []110 response.body = None 111 111 if getattr(cherrypy, "debug", None): 112 112 cherrypy.log(" Found file (304 Not Modified): %s" % path, "DEBUG") … … 145 145 response.headerMap['Content-Length'] = r_len 146 146 bodyfile.seek(start) 147 response.body = [bodyfile.read(r_len)]147 response.body = bodyfile.read(r_len) 148 148 else: 149 149 # Return a multipart/byteranges response. … … 168 168 else: 169 169 response.headerMap['Content-Length'] = c_len 170 response.body = fileGenerator(bodyfile)170 response.body = bodyfile 171 171 else: 172 172 response.headerMap['Content-Length'] = c_len 173 response.body = fileGenerator(bodyfile)173 response.body = bodyfile 174 174 return response.body 175 175

