diff options
author | Robert Brewer <fumanchu@aminus.org> | 2006-10-20 07:14:06 +0000 |
---|---|---|
committer | Robert Brewer <fumanchu@aminus.org> | 2006-10-20 07:14:06 +0000 |
commit | b20c6f68995fbf9fb182e64a928dd0266fa815c5 (patch) | |
tree | a3f8be3b76f6bd2b7a64c9760ebec63e6b62418e | |
parent | 501c3afbd6b7446be83313c351153095ebd529d1 (diff) | |
download | cherrypy-git-b20c6f68995fbf9fb182e64a928dd0266fa815c5.tar.gz |
Trunk fix for #577 (GzipFilter doesn't force an update of the Content-Length header). All code which could change the length of response.body should delete the Content-Length header (if already set).
-rw-r--r-- | cherrypy/lib/cptools.py | 6 | ||||
-rw-r--r-- | cherrypy/lib/encoding.py | 15 | ||||
-rw-r--r-- | cherrypy/lib/static.py | 6 | ||||
-rw-r--r-- | cherrypy/lib/tidy.py | 34 |
4 files changed, 49 insertions, 12 deletions
diff --git a/cherrypy/lib/cptools.py b/cherrypy/lib/cptools.py index 9ae76086..2aced1b6 100644 --- a/cherrypy/lib/cptools.py +++ b/cherrypy/lib/cptools.py @@ -210,6 +210,9 @@ Message: %(error_msg)s if error_msg: body = self.login_screen(from_page, username, error_msg) cherrypy.response.body = body + if cherrypy.response.headers.has_key("Content-Length"): + # Delete Content-Length header so finalize() recalcs it. + del cherrypy.response.headers["Content-Length"] return True else: cherrypy.session[self.session_key] = username @@ -235,6 +238,9 @@ Message: %(error_msg)s sess[self.session_key] = username = self.anonymous() if not username: cherrypy.response.body = self.login_screen(cherrypy.url(qs=request.query_string)) + if cherrypy.response.headers.has_key("Content-Length"): + # Delete Content-Length header so finalize() recalcs it. + del cherrypy.response.headers["Content-Length"] return True self.on_check(username) diff --git a/cherrypy/lib/encoding.py b/cherrypy/lib/encoding.py index 82a1d081..14391880 100644 --- a/cherrypy/lib/encoding.py +++ b/cherrypy/lib/encoding.py @@ -100,6 +100,18 @@ def find_acceptable_charset(encoding=None, default_encoding='utf-8', errors='str else: response.collapse_body() encoder = encode_string + if response.headers.has_key("Content-Length"): + # Delete Content-Length header so finalize() recalcs it. + # Encoded strings may be of different lengths from their + # unicode equivalents, and even from each other. For example: + # >>> t = u"\u7007\u3040" + # >>> len(t) + # 2 + # >>> len(t.encode("UTF-8")) + # 6 + # >>> len(t.encode("utf7")) + # 8 + del response.headers["Content-Length"] # Parse the Accept-Charset request header, and try to provide one # of the requested charsets (in order of user preference). @@ -217,5 +229,8 @@ def gzip(compress_level=9, mime_types=['text/html', 'text/plain']): response.headers['Content-Encoding'] = 'gzip' response.body = compress(response.body, compress_level) + if response.headers.has_key("Content-Length"): + # Delete Content-Length header so finalize() recalcs it. + del response.headers["Content-Length"] return cherrypy.HTTPError(406, "identity, gzip").set_response() diff --git a/cherrypy/lib/static.py b/cherrypy/lib/static.py index c28cf006..dee635e7 100644 --- a/cherrypy/lib/static.py +++ b/cherrypy/lib/static.py @@ -17,7 +17,7 @@ from cherrypy.lib import cptools, http def serve_file(path, content_type=None, disposition=None, name=None): """Set status, headers, and body in order to serve the given file. - The Content-Type header will be set to the content_ype arg, if provided. + The Content-Type header will be set to the content_type arg, if provided. If not provided, the Content-Type will be guessed by its extension. If disposition is not None, the Content-Disposition header will be set @@ -96,7 +96,9 @@ def serve_file(path, content_type=None, disposition=None, name=None): boundary = mimetools.choose_boundary() ct = "multipart/byteranges; boundary=%s" % boundary response.headers['Content-Type'] = ct -## del response.headers['Content-Length'] + if response.headers.has_key("Content-Length"): + # Delete Content-Length header so finalize() recalcs it. + del response.headers["Content-Length"] def file_ranges(): # Apache compatibility: diff --git a/cherrypy/lib/tidy.py b/cherrypy/lib/tidy.py index cac5f9f8..25e34984 100644 --- a/cherrypy/lib/tidy.py +++ b/cherrypy/lib/tidy.py @@ -18,11 +18,13 @@ def tidy(temp_dir, tidy_path, strict_xml=False, errors_to_ignore=None, stable and it crashes on some HTML pages (which means that the server would also crash) """ + response = cherrypy.response + # the tidy tool, by its very nature it's not generator friendly, # so we just collapse the body and work with it. - orig_body = cherrypy.response.collapse_body() + orig_body = response.collapse_body() - fct = cherrypy.response.headers.get('Content-Type', '') + fct = response.headers.get('Content-Type', '') ct = fct.split(';')[0] encoding = '' i = fct.find('charset=') @@ -73,8 +75,10 @@ def tidy(temp_dir, tidy_path, strict_xml=False, errors_to_ignore=None, new_errs.append(err) if new_errs: - cherrypy.response.body = wrong_content('<br />'.join(new_errs), - orig_body) + response.body = wrong_content('<br />'.join(new_errs), orig_body) + if response.headers.has_key("Content-Length"): + # Delete Content-Length header so finalize() recalcs it. + del response.headers["Content-Length"] return elif strict_xml: # The HTML is OK, but is it valid XML? @@ -96,11 +100,17 @@ def tidy(temp_dir, tidy_path, strict_xml=False, errors_to_ignore=None, body_file = StringIO.StringIO() traceback.print_exc(file = body_file) body_file = '<br />'.join(body_file.getvalue()) - cherrypy.response.body = wrong_content(body_file, orig_body, "XML") + response.body = wrong_content(body_file, orig_body, "XML") + if response.headers.has_key("Content-Length"): + # Delete Content-Length header so finalize() recalcs it. + del response.headers["Content-Length"] return if use_output: - cherrypy.response.body = [output] + response.body = [output] + if response.headers.has_key("Content-Length"): + # Delete Content-Length header so finalize() recalcs it. + del response.headers["Content-Length"] def html_space(text): """Escape text, replacing space with nbsp and tab with 4 nbsp's.""" @@ -118,11 +128,13 @@ def wrong_content(header, body, content_type="HTML"): def nsgmls(temp_dir, nsgmls_path, catalog_path, errors_to_ignore=None): + response = cherrypy.response + # the tidy tool, by its very nature it's not generator friendly, # so we just collect the body and work with it. - orig_body = cherrypy.response.collapse_body() + orig_body = response.collapse_body() - fct = cherrypy.response.headers.get('Content-Type', '') + fct = response.headers.get('Content-Type', '') ct = fct.split(';')[0] encoding = '' i = fct.find('charset=') @@ -162,6 +174,8 @@ def nsgmls(temp_dir, nsgmls_path, catalog_path, errors_to_ignore=None): new_errs.append(err) if new_errs: - cherrypy.response.body = wrong_content('<br />'.join(new_errs), - orig_body) + response.body = wrong_content('<br />'.join(new_errs), orig_body) + if response.headers.has_key("Content-Length"): + # Delete Content-Length header so finalize() recalcs it. + del response.headers["Content-Length"] |