Commits

Robert Brewer committed edbb108

Comments (0)

Files changed (2)

cherrypy/lib/caching.py

         self.store.pop(self.key(), None)
 
 
-def get(invalid_methods=("POST", "PUT", "DELETE"), **kwargs):
+def get(invalid_methods=("POST", "PUT", "DELETE"), debug=False, **kwargs):
     """Try to obtain cached output. If fresh enough, raise HTTPError(304).
     
     If POST, PUT, or DELETE:
     # POST, PUT, DELETE should invalidate (delete) the cached copy.
     # See http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html#sec13.10.
     if request.method in invalid_methods:
+        if debug:
+            cherrypy.log('request.method %r in invalid_methods %r' %
+                         (request.method, invalid_methods), 'TOOLS.CACHING')
         cherrypy._cache.delete()
         request.cached = False
         request.cacheable = False
     request.cached = c = bool(cache_data)
     request.cacheable = not c
     if c:
+        if debug:
+            cherrypy.log('Reading response from cache', 'TOOLS.CACHING')
         s, h, b, create_time, original_req_headers = cache_data
         
         # Copy the response headers. See http://www.cherrypy.org/ticket/721.
         # serve it & get out from the request
         response.status = s
         response.body = b
+    else:
+        if debug:
+            cherrypy.log('request is not cached', 'TOOLS.CACHING')
     return c
 
 
     response.body = tee(response.body)
 
 
-def expires(secs=0, force=False):
+def expires(secs=0, force=False, debug=False):
     """Tool for influencing cache mechanisms using the 'Expires' header.
     
     'secs' must be either an int or a datetime.timedelta, and indicates the
                 cacheable = True
                 break
     
-    if not cacheable:
+    if not cacheable and not force:
+        if debug:
+            cherrypy.log('request is not cacheable', 'TOOLS.EXPIRES')
+    else:
+        if debug:
+            cherrypy.log('request is cacheable', 'TOOLS.EXPIRES')
         if isinstance(secs, datetime.timedelta):
             secs = (86400 * secs.days) + secs.seconds
         
         if secs == 0:
-            if force or "Pragma" not in headers:
+            if force or ("Pragma" not in headers):
                 headers["Pragma"] = "no-cache"
             if cherrypy.serving.request.protocol >= (1, 1):
                 if force or "Cache-Control" not in headers:

cherrypy/test/test_caching.py

     
     class UnCached(object):
         _cp_config = {'tools.expires.on': True,
+                      'tools.expires.secs': 60,
                       'tools.staticdir.on': True,
                       'tools.staticdir.dir': 'static',
                       'tools.staticdir.root': curdir,
                       }
 
         def force(self):
+            cherrypy.response.headers['Etag'] = 'bibbitybobbityboo'
             self._cp_config['tools.expires.force'] = True
+            self._cp_config['tools.expires.secs'] = 0
             return "being forceful"
         force.exposed = True
+        force._cp_config = {'tools.expires.secs': 0}
 
         def dynamic(self):
+            cherrypy.response.headers['Etag'] = 'bibbitybobbityboo'
             cherrypy.response.headers['Cache-Control'] = 'private'
             return "D-d-d-dynamic!"
         dynamic.exposed = True
         cacheable.exposed = True
 
         def specific(self):
+            cherrypy.response.headers['Etag'] = 'need_this_to_make_me_cacheable'
             return "I am being specific"
         specific.exposed = True
         specific._cp_config = {'tools.expires.secs': 86400}
         class Foo(object):pass
         
         def wrongtype(self):
+            cherrypy.response.headers['Etag'] = 'need_this_to_make_me_cacheable'
             return "Woops"
         wrongtype.exposed = True
         wrongtype._cp_config = {'tools.expires.secs': Foo()}
         self.assertBody('visit #1')
         
     def testExpiresTool(self):
-        
         # test setting an expires header
         self.getPage("/expires/specific")
         self.assertStatus("200 OK")
         self.assertStatus("200 OK")
         self.assertNoHeader("Pragma")
         self.assertNoHeader("Cache-Control")
+        self.assertHeader("Expires")
         
         # dynamic content that sets indicators should not have
         # "cache prevention" headers
         self.assertStatus("200 OK")
         self.assertNoHeader("Pragma")
         self.assertNoHeader("Cache-Control")
+        self.assertHeader("Expires")
         
         self.getPage('/expires/dynamic')
         self.assertBody("D-d-d-dynamic!")
         # the Cache-Control header should be untouched
         self.assertHeader("Cache-Control", "private")
+        self.assertHeader("Expires")
         
         # configure the tool to ignore indicators and replace existing headers
         self.getPage("/expires/force")