summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Wyglendowski <devnull@localhost>2006-12-28 22:16:54 +0000
committerChristian Wyglendowski <devnull@localhost>2006-12-28 22:16:54 +0000
commitd9090a6fc343195b3014f566cde5f1d9faf89cd2 (patch)
tree9ac77da87645a55afa4b3ebfc38de5972a00fd2a
parente0078b45167db6f6927011140753bebe602b157d (diff)
downloadcherrypy-d9090a6fc343195b3014f566cde5f1d9faf89cd2.tar.gz
Backport of [1187] to 2.x branch. (Age header in cached responses). See #567.
-rw-r--r--cherrypy/filters/cachefilter.py22
-rw-r--r--cherrypy/test/test_cache_filter.py29
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