diff options
author | Malcolm Tredinnick <malcolm.tredinnick@gmail.com> | 2007-11-29 16:57:18 +0000 |
---|---|---|
committer | Malcolm Tredinnick <malcolm.tredinnick@gmail.com> | 2007-11-29 16:57:18 +0000 |
commit | f2f6e70b08b1142055e33e75f58cfe7fbb5d868f (patch) | |
tree | a47081520721e1f9c6d7e728e30421e65a89caa0 /django | |
parent | 0171f007613d42cf26eb2742cfe73ea82fd4b43d (diff) | |
download | django-f2f6e70b08b1142055e33e75f58cfe7fbb5d868f.tar.gz |
Fixed #5813 -- Taught the CacheMiddleware to respect any max-age HTTP header
when setting the expiry time. Thanks, SmileyChris.
git-svn-id: http://code.djangoproject.com/svn/django/trunk@6736 bcc190cf-cafb-0310-a4f2-bffc1f526a37
Diffstat (limited to 'django')
-rw-r--r-- | django/middleware/cache.py | 23 | ||||
-rw-r--r-- | django/utils/cache.py | 22 |
2 files changed, 40 insertions, 5 deletions
diff --git a/django/middleware/cache.py b/django/middleware/cache.py index a88b4956b2..23a907f8be 100644 --- a/django/middleware/cache.py +++ b/django/middleware/cache.py @@ -1,14 +1,18 @@ from django.conf import settings from django.core.cache import cache -from django.utils.cache import get_cache_key, learn_cache_key, patch_response_headers +from django.utils.cache import get_cache_key, learn_cache_key, patch_response_headers, get_max_age class CacheMiddleware(object): """ Cache middleware. If this is enabled, each Django-powered page will be - cached for CACHE_MIDDLEWARE_SECONDS seconds. Cache is based on URLs. + cached (based on URLs). Only parameter-less GET or HEAD-requests with status code 200 are cached. + The number of seconds each page is stored for is set by the + "max-age" section of the response's "Cache-Control" header, falling back to + the CACHE_MIDDLEWARE_SECONDS setting if the section was not found. + If CACHE_MIDDLEWARE_ANONYMOUS_ONLY is set to True, only anonymous requests (i.e., those not made by a logged-in user) will be cached. This is a simple and effective way of avoiding the caching of the Django admin (and @@ -78,7 +82,16 @@ class CacheMiddleware(object): return response if not response.status_code == 200: return response - patch_response_headers(response, self.cache_timeout) - cache_key = learn_cache_key(request, response, self.cache_timeout, self.key_prefix) - cache.set(cache_key, response, self.cache_timeout) + # Try to get the timeout from the "max-age" section of the "Cache- + # Control" header before reverting to using the default cache_timeout + # length. + timeout = get_max_age(response) + if timeout == None: + timeout = self.cache_timeout + elif timeout == 0: + # max-age was set to 0, don't bother caching. + return response + patch_response_headers(response, timeout) + cache_key = learn_cache_key(request, response, timeout, self.key_prefix) + cache.set(cache_key, response, timeout) return response diff --git a/django/utils/cache.py b/django/utils/cache.py index 5654bed7aa..4fcf493944 100644 --- a/django/utils/cache.py +++ b/django/utils/cache.py @@ -74,6 +74,21 @@ def patch_cache_control(response, **kwargs): cc = ', '.join([dictvalue(el) for el in cc.items()]) response['Cache-Control'] = cc +def get_max_age(response): + """ + Returns the max-age from the response Cache-Control header as an integer + (or ``None`` if it wasn't found or wasn't an integer. + """ + if not response.has_header('Cache-Control'): + return + cc = dict([_to_tuple(el) for el in + cc_delim_re.split(response['Cache-Control'])]) + if 'max-age' in cc: + try: + return int(cc['max-age']) + except (ValueError, TypeError): + pass + def patch_response_headers(response, cache_timeout=None): """ Adds some useful headers to the given HttpResponse object: @@ -180,3 +195,10 @@ def learn_cache_key(request, response, cache_timeout=None, key_prefix=None): # for the request.path cache.set(cache_key, [], cache_timeout) return _generate_cache_key(request, [], key_prefix) + + +def _to_tuple(s): + t = s.split('=',1) + if len(t) == 2: + return t[0].lower(), t[1] + return t[0].lower(), True |