Commits

Robert Brewer committed 5a034c4

3.0.2 bugfix: responses were being gzipped twice when served from cache. Needs port to trunk eventually.

Comments (0)

Files changed (2)

cherrypy/lib/encoding.py

     yield struct.pack("<l", crc)
     yield struct.pack("<L", size & 0xFFFFFFFFL)
 
+def decompress(body):
+    import gzip, StringIO
+    
+    zbuf = StringIO.StringIO()
+    zbuf.write(body)
+    zbuf.seek(0)
+    zfile = gzip.GzipFile(mode='rb', fileobj=zbuf)
+    data = zfile.read()
+    zfile.close()
+    return data
+
+
 def gzip(compress_level=9, mime_types=['text/html', 'text/plain']):
     response = cherrypy.response
     if not response.body:
         # Response body is empty (might be a 304 for instance)
         return
     
+    # If returning cached content (which should already have been gzipped),
+    # don't re-zip.
+    if getattr(cherrypy.request, "cached", False):
+        return
+    
     acceptable = cherrypy.request.headers.elements('Accept-Encoding')
     if not acceptable:
         # If no Accept-Encoding field is present in a request,

cherrypy/test/test_caching.py

         
         # The previous request should have invalidated the cache,
         # so this request will recalc the response.
-        zbuf = StringIO.StringIO()
-        zfile = gzip.GzipFile(mode='wb', fileobj=zbuf, compresslevel=9)
-        zfile.write("visit #5")
-        zfile.close()
-        
         self.getPage("/", method="GET", headers=[('Accept-Encoding', 'gzip')])
         self.assertHeader('Content-Encoding', 'gzip')
-        self.assertInBody(zbuf.getvalue()[:3])
+        self.assertEqual(cherrypy.lib.encoding.decompress(self.body), "visit #5")
         
-        # Now check that a second request gets the gzip header and gzipped body
+        # Now check that a second request gets the gzip header and gzipped body.
+        # This also tests a bug in 3.0 to 3.0.2 whereby the cached, gzipped
+        # response body was being gzipped a second time.
         self.getPage("/", method="GET", headers=[('Accept-Encoding', 'gzip')])
         self.assertHeader('Content-Encoding', 'gzip')
-        self.assertInBody(zbuf.getvalue()[:3])
+        self.assertEqual(cherrypy.lib.encoding.decompress(self.body), "visit #5")
         
         # Now check that a third request that doesn't accept gzip
-        # gets another hit.
+        # skips the cache (because the 'Vary' header denies it).
         self.getPage("/", method="GET")
         self.assertNoHeader('Content-Encoding')
         self.assertBody("visit #6")
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.