Skip to content

Commit c9db69c

Browse files
authored
Merge pull request #202 from TheJokr/vary-star-no-cache
Removed unnecessary caching of Vary: * responses
2 parents 5933c82 + 0234b80 commit c9db69c

File tree

3 files changed

+19
-0
lines changed

3 files changed

+19
-0
lines changed

cachecontrol/controller.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -293,6 +293,15 @@ def cache_response(self, request, response, body=None, status_codes=None):
293293
if no_store:
294294
return
295295

296+
# https://tools.ietf.org/html/rfc7234#section-4.1:
297+
# A Vary header field-value of "*" always fails to match.
298+
# Storing such a response leads to a deserialization warning
299+
# during cache lookup and is not allowed to ever be served,
300+
# so storing it can be avoided.
301+
if "*" in response_headers.get("vary", ""):
302+
logger.debug('Response header has "Vary: *"')
303+
return
304+
296305
# If we've been given an etag, then keep the response
297306
if self.cache_etags and "etag" in response_headers:
298307
logger.debug("Caching due to etag")

cachecontrol/serialize.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,8 @@ def prepare_response(self, request, cached):
107107
"""
108108
# Special case the '*' Vary value as it means we cannot actually
109109
# determine if the cached response is suitable for this request.
110+
# This case is also handled in the controller code when creating
111+
# a cache entry, but is left here for backwards compatibility.
110112
if "*" in cached.get("vary", {}):
111113
return
112114

tests/test_cache_control.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,14 @@ def test_cache_response_no_store_with_etag(self, cc):
112112

113113
assert not cc.cache.set.called
114114

115+
def test_no_cache_with_vary_star(self, cc):
116+
# Vary: * indicates that the response can never be served
117+
# from the cache, so storing it can be avoided.
118+
resp = self.resp({"vary": "*"})
119+
cc.cache_response(self.req(), resp)
120+
121+
assert not cc.cache.set.called
122+
115123
def test_update_cached_response_with_valid_headers(self):
116124
cached_resp = Mock(headers={"ETag": "jfd9094r808", "Content-Length": 100})
117125

0 commit comments

Comments
 (0)