Changeset 1796
- Timestamp:
- 10/28/07 13:28:42
- Files:
-
- trunk/cherrypy/lib/caching.py (modified) (2 diffs)
- trunk/cherrypy/test/test_caching.py (modified) (3 diffs)
- trunk/cherrypy/test/test_encoding.py (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/cherrypy/lib/caching.py
r1795 r1796 124 124 if c: 125 125 response = cherrypy.response 126 s, h, b, create_time = cache_data 127 128 # Make a copy. See http://www.cherrypy.org/ticket/721 126 s, h, b, create_time, original_req_headers = cache_data 127 128 # Check 'Vary' selecting headers. If any headers mentioned in "Vary" 129 # differ between the cached and current request, bail out and 130 # let the rest of CP handle the request. This should properly 131 # mimic the behavior of isolated caches as RFC 2616 assumes: 132 # "If the selecting request header fields for the cached entry 133 # do not match the selecting request header fields of the new 134 # request, then the cache MUST NOT use a cached entry to satisfy 135 # the request unless it first relays the new request to the origin 136 # server in a conditional request and the server responds with 137 # 304 (Not Modified), including an entity tag or Content-Location 138 # that indicates the entity to be used. 139 # TODO: can we store multiple variants based on Vary'd headers? 140 for header_element in h.elements('Vary'): 141 key = header_element.value 142 if original_req_headers[key] != request.headers.get(key, 'missing'): 143 request.cached = False 144 request.cacheable = True 145 return False 146 147 # Copy the response headers. See http://www.cherrypy.org/ticket/721. 129 148 response.headers = rh = http.HeaderMap() 130 149 for k in h: … … 162 181 # save the cache data 163 182 body = ''.join(output) 183 vary = [he.value for he in 184 cherrypy.response.headers.elements('Vary')] 185 if vary: 186 sel_headers = dict([(k, v) for k, v 187 in cherrypy.request.headers.iteritems() 188 if k in vary]) 189 else: 190 sel_headers = {} 164 191 cherrypy._cache.put((response.status, response.headers or {}, 165 body, response.time ))192 body, response.time, sel_headers)) 166 193 167 194 response = cherrypy.response trunk/cherrypy/test/test_caching.py
r1790 r1796 2 2 test.prefer_parent_path() 3 3 4 import gzip 4 5 import os 5 6 curdir = os.path.join(os.getcwd(), os.path.dirname(__file__)) 7 import StringIO 6 8 7 9 import cherrypy … … 69 71 cherrypy.tree.mount(Root()) 70 72 cherrypy.tree.mount(UnCached(), "/expires") 71 cherrypy.config.update({'environment': 'test_suite'}) 73 cherrypy.config.update({'environment': 'test_suite', 74 'tools.gzip.on': True}) 72 75 73 76 … … 100 103 self.getPage("/", method="DELETE") 101 104 self.assertBody('visit #4') 105 102 106 # The previous request should have invalidated the cache, 103 107 # so this request will recalc the response. 108 zbuf = StringIO.StringIO() 109 zfile = gzip.GzipFile(mode='wb', fileobj=zbuf, compresslevel=9) 110 zfile.write("visit #5") 111 zfile.close() 112 113 self.getPage("/", method="GET", headers=[('Accept-Encoding', 'gzip')]) 114 self.assertHeader('Content-Encoding', 'gzip') 115 self.assertInBody(zbuf.getvalue()[:3]) 116 117 # Now check that a second request gets the gzip header and gzipped body 118 self.getPage("/", method="GET", headers=[('Accept-Encoding', 'gzip')]) 119 self.assertHeader('Content-Encoding', 'gzip') 120 self.assertInBody(zbuf.getvalue()[:3]) 121 122 # Now check that a third request that doesn't accept gzip 123 # gets another hit. 104 124 self.getPage("/", method="GET") 105 self.assertBody('visit #5') 125 self.assertNoHeader('Content-Encoding') 126 self.assertBody('visit #6') 106 127 107 128 def testExpiresTool(self): trunk/cherrypy/test/test_encoding.py
r1384 r1796 118 118 self.assertInBody(zbuf.getvalue()[:3]) 119 119 self.assertHeader("Vary", "Accept-Encoding") 120 self.assertHeader("Content-Encoding", "gzip") 120 121 121 122 # Test when gzip is denied.

