Robert Brewer avatar Robert Brewer committed 995f0a8

Fix for #721 (bugs in tools.caching).

Comments (0)

Files changed (2)

cherrypy/lib/caching.py

     request.cacheable = not c
     if c:
         response = cherrypy.response
-        s, response.headers, b, create_time = cache_data
+        s, h, b, create_time = cache_data
+        
+        # Make a copy. See http://www.cherrypy.org/ticket/721
+        response.headers = rh = http.HeaderMap()
+        for k in h:
+            dict.__setitem__(rh, k, dict.__getitem__(h, k))
         
         # Add the required Age header
         response.headers["Age"] = str(int(response.time - create_time))
             # this was put into the cached copy, and should have been
             # resurrected just above (response.headers = cache_data[1]).
             cptools.validate_since()
-        except cherrypy.HTTPError, x:
+        except cherrypy.HTTPRedirect, x:
             if x.status == 304:
                 cherrypy._cache.tot_non_modified += 1
             raise

cherrypy/test/test_caching.py

 curdir = os.path.join(os.getcwd(), os.path.dirname(__file__))
 
 import cherrypy
+from cherrypy.lib import http
+
+gif_bytes = ('GIF89a\x01\x00\x01\x00\x82\x00\x01\x99"\x1e\x00\x00\x00\x00\x00'
+             '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
+             '\x00,\x00\x00\x00\x00\x01\x00\x01\x00\x02\x03\x02\x08\t\x00;')
 
 
 def setup_server():
             msg = "visit #%s" % cherrypy.counter
             return msg
         index.exposed = True
-
+        
+        def a_gif(self):
+            cherrypy.response.headers['Last-Modified'] = http.HTTPDate()
+            return gif_bytes
+        a_gif.exposed = True
+    
     class UnCached(object):
         _cp_config = {'tools.expires.on': True,
                       'tools.staticdir.on': True,
             self.assertHeader("Cache-Control", "no-cache, must-revalidate")
         d = self.assertHeader("Date")
         self.assertHeader("Expires", d)
+    
+    def testLastModified(self):
+        self.getPage("/a.gif")
+        self.assertStatus(200)
+        self.assertBody(gif_bytes)
+        lm1 = self.assertHeader("Last-Modified")
+        
+        # this request should get the cached copy.
+        self.getPage("/a.gif")
+        self.assertStatus(200)
+        self.assertBody(gif_bytes)
+        self.assertHeader("Age")
+        lm2 = self.assertHeader("Last-Modified")
+        self.assertEqual(lm1, lm2)
+        
+        # this request should match the cached copy, but raise 304.
+        self.getPage("/a.gif", [('If-Modified-Since', lm1)])
+        self.assertStatus(304)
+        self.assertNoHeader("Last-Modified")
+        self.assertHeader("Age")
+
 
 if __name__ == '__main__':
     setup_server()
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.