diff options
author | Christian Wyglendowski <devnull@localhost> | 2006-12-28 22:16:54 +0000 |
---|---|---|
committer | Christian Wyglendowski <devnull@localhost> | 2006-12-28 22:16:54 +0000 |
commit | d9090a6fc343195b3014f566cde5f1d9faf89cd2 (patch) | |
tree | 9ac77da87645a55afa4b3ebfc38de5972a00fd2a | |
parent | e0078b45167db6f6927011140753bebe602b157d (diff) | |
download | cherrypy-d9090a6fc343195b3014f566cde5f1d9faf89cd2.tar.gz |
Backport of [1187] to 2.x branch. (Age header in cached responses). See #567.
-rw-r--r-- | cherrypy/filters/cachefilter.py | 22 | ||||
-rw-r--r-- | cherrypy/test/test_cache_filter.py | 29 |
2 files changed, 39 insertions, 12 deletions
diff --git a/cherrypy/filters/cachefilter.py b/cherrypy/filters/cachefilter.py index c27a65aa..7f10d5ae 100644 --- a/cherrypy/filters/cachefilter.py +++ b/cherrypy/filters/cachefilter.py @@ -117,6 +117,7 @@ class CacheFilter(basefilter.BaseFilter): return request = cherrypy.request + response = cherrypy.response # POST, PUT, DELETE should invalidate (delete) the cached copy. # See http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html#sec13.10. @@ -129,20 +130,21 @@ class CacheFilter(basefilter.BaseFilter): if cacheData: # found a hit! check the if-modified-since request header expirationTime, lastModified, obj = cacheData - s, h, b = obj + s, h, b, create_time = obj modifiedSince = request.headers.get('If-Modified-Since', None) if modifiedSince is not None and modifiedSince == lastModified: cherrypy._cache.totNonModified += 1 - cherrypy.response.status = "304 Not Modified" - ct = h.get("Content-Type") + response.status = "304 Not Modified" + ct = h.get('Content-Type', None) if ct: - cherrypy.response.header_list["Content-Type"] = ct - cherrypy.response.body = None + response.headers['Content-Type'] = ct + response.body = None else: # serve it & get out from the request response = cherrypy.response - response.status, response.header_list, response.body = s, h, b - raise cherrypy.RequestHandled() + response.status, response.headers, response.body = s, h, b + response.headers['Age'] = str(int(time.time() - create_time)) + request.execute_main = False else: request.cacheable = True @@ -168,9 +170,11 @@ class CacheFilter(basefilter.BaseFilter): lastModified = response.headers.get('Last-Modified', None) # save the cache data body = ''.join([chunk for chunk in response._cachefilter_tee]) + create_time = time.time() cherrypy._cache.put(lastModified, (response.status, - response.header_list, - body)) + response.headers, + body, + create_time)) def percentual(n,d): diff --git a/cherrypy/test/test_cache_filter.py b/cherrypy/test/test_cache_filter.py index d85fd4c9..6d1e894f 100644 --- a/cherrypy/test/test_cache_filter.py +++ b/cherrypy/test/test_cache_filter.py @@ -3,6 +3,7 @@ test.prefer_parent_path() import cherrypy from cherrypy.filters.cachefilter import expires +from cherrypy.lib.httptools import HTTPDate def setup_server(): @@ -15,7 +16,13 @@ def setup_server(): msg = "visit #%s" % cherrypy.counter return msg index.exposed = True - + + def textplain(self): + cherrypy.response.headers['Content-type'] = 'text/plain' + cherrypy.response.headers['Last-Modified'] = HTTPDate() + return self.index() + textplain.exposed = True + class UnCached(object): use_force = False @@ -59,10 +66,16 @@ import helper class CacheFilterTest(helper.CPWebCase): def testCaching(self): + elapsed = 0.0 for trial in xrange(10): self.getPage("/") - # The response should be the same every time! + # The response should be the same every time, + # except for the Age response header. self.assertBody('visit #1') + if trial != 0: + age = int(self.assertHeader("Age")) + self.assert_(age >= elapsed) + elapsed = age # POST, PUT, DELETE should not be cached. self.getPage("/", method="POST") @@ -80,7 +93,17 @@ class CacheFilterTest(helper.CPWebCase): # so this request will recalc the response. self.getPage("/", method="GET") self.assertBody('visit #5') - + + # make sure that custom set Content-types get passed through on 304s + self.getPage("/textplain") + self.assertHeader("Content-type", "text/plain") + self.assertStatus("200 OK") + self.assertBody('visit #6') + date = self.assertHeader("Last-Modified") + self.getPage("/textplain", [("If-Modified-Since", date)]) + self.assertHeader("Content-type", "text/plain") + self.assertStatus("304 Not Modified") + def testExpiresTool(self): # test setting an expires header |