Skip to content

Commit

Permalink
regenerate cache upon 'Cache-Control: max-age=0' received (#7)
Browse files Browse the repository at this point in the history
  • Loading branch information
renskiy committed Aug 14, 2016
1 parent 81e84f0 commit b527629
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 14 deletions.
42 changes: 28 additions & 14 deletions djangocache.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,21 @@ def patch(obj, attr, value, default=None):
setattr(obj, attr, original)


def get_cache_max_age(request):
if 'HTTP_CACHE_CONTROL' not in request.META:
return
request_cache_control = dict(
cache._to_tuple(attr)
for attr in
cache.cc_delim_re.split(request.META['HTTP_CACHE_CONTROL'])
)
if 'max-age' in request_cache_control:
try:
return int(request_cache_control['max-age'])
except (ValueError, TypeError):
pass


class CacheMiddleware(cache_middleware.CacheMiddleware):
"""
Despite of the original one this middleware supports
Expand All @@ -58,25 +73,24 @@ def get_key_prefix(self, request, *args, **kwargs):
return self.key_prefix

def process_request(self, request):
cache_allowed = request.method in ('GET', 'HEAD')
if request.method not in ('GET', 'HEAD'):
return None

if any(map(request.META.__contains__, (
cache_max_age = get_cache_max_age(request)
if cache_max_age == 0 or any(map(request.META.__contains__, (
'HTTP_IF_MODIFIED_SINCE',
'HTTP_IF_NONE_MATCH',
'HTTP_IF_UNMODIFIED_SINCE',
'HTTP_IF_MATCH',
))):
request._cache_update_cache = cache_allowed
request._cache_update_cache = True
return None

if cache_allowed:
response_handle.key_prefix = key_prefix = self.get_key_prefix(
request,
*request.resolver_match.args,
**request.resolver_match.kwargs
)
else:
key_prefix = None
request._cache_key_prefix = key_prefix = self.get_key_prefix(
request,
*request.resolver_match.args,
**request.resolver_match.kwargs
)

with patch(self, 'key_prefix', key_prefix):
response = super(CacheMiddleware, self).process_request(request)
Expand All @@ -102,7 +116,7 @@ def process_response(self, request, response):
last_modified = 'Last-Modified' in response
etag = 'ETag' in response

response_handle.cache_timeout = cache_timeout = self.get_cache_timeout(
request._cache_timeout = cache_timeout = self.get_cache_timeout(
request,
*request.resolver_match.args,
**request.resolver_match.kwargs
Expand Down Expand Up @@ -157,8 +171,8 @@ def update_response_cache(*args, **kwargs):
# all objects are already closed by this time
response._closable_objects = []

cache_timeout = getattr(response_handle, 'cache_timeout', None)
key_prefix = getattr(response_handle, 'key_prefix', None)
cache_timeout = getattr(request, '_cache_timeout', None)
key_prefix = getattr(request, '_cache_key_prefix', None)

with patch(response, 'closed', False):
# reset 'closed' flag before saving response to cache
Expand Down
25 changes: 25 additions & 0 deletions tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,19 @@ def test_dynamic_key_prefix(self):
self.assertEqual('max-age=300', response['Cache-Control'])
mocked_response.reset_mock()

response = client.get(
reverse('dynamic_key_prefix'),
HTTP_CACHE_CONTROL='max-age=0',
)
mocked_response.assert_called_once()
self.assertNotIn('ETag', response)
self.assertNotIn('Last-Modified', response)
self.assertIn('Expires', response)
self.assertIn('Cache-Control', response)
self.assertEqual('Sun, 17 Jul 2016 10:15:00 GMT', response['Expires'])
self.assertEqual('max-age=600', response['Cache-Control'])
mocked_response.reset_mock()

dynamic_key_prefix.key_prefix = 'another_key_prefix'

# Mon, 17 Jul 2016 10:05:00 GMT
Expand Down Expand Up @@ -332,6 +345,18 @@ def test_static(self):
self.assertEqual('Mon, 18 Jul 2016 10:00:00 GMT', response['Expires'])
self.assertEqual('max-age=86100', response['Cache-Control'])

response = client.get(
reverse('static'),
HTTP_CACHE_CONTROL='max-age=0',
)
mocked_response.assert_called_once()
self.assertNotIn('ETag', response)
self.assertNotIn('Last-Modified', response)
self.assertIn('Expires', response)
self.assertIn('Cache-Control', response)
self.assertEqual('Mon, 18 Jul 2016 10:05:00 GMT', response['Expires'])
self.assertEqual('max-age=86400', response['Cache-Control'])

def test_with_last_modified(self):
client = test.Client()

Expand Down

0 comments on commit b527629

Please sign in to comment.