diff options
author | Flavio Curella <flavio.curella@gmail.com> | 2019-09-26 13:58:14 -0700 |
---|---|---|
committer | Mariusz Felisiak <felisiak.mariusz@gmail.com> | 2019-10-10 19:30:51 +0200 |
commit | ed112fadc1cfa400dbee6080bf82fd7536ea4c72 (patch) | |
tree | dc96114d797f815577a61c12abc899dbb8307277 /django/utils/cache.py | |
parent | 2a6f45e08e8cb8c7e5157915c378b453109424d2 (diff) | |
download | django-ed112fadc1cfa400dbee6080bf82fd7536ea4c72.tar.gz |
Fixed #23755 -- Added support for multiple field names in the no-cache Cache-Control directive to patch_cache_control().
https://tools.ietf.org/html/rfc7234#section-5.2.2.2
Diffstat (limited to 'django/utils/cache.py')
-rw-r--r-- | django/utils/cache.py | 34 |
1 files changed, 27 insertions, 7 deletions
diff --git a/django/utils/cache.py b/django/utils/cache.py index 3ee01a1e94..14e8256b94 100644 --- a/django/utils/cache.py +++ b/django/utils/cache.py @@ -19,6 +19,7 @@ An example: i18n middleware would need to distinguish caches by the import hashlib import re import time +from collections import defaultdict from django.conf import settings from django.core.cache import caches @@ -53,17 +54,21 @@ def patch_cache_control(response, **kwargs): else: return (t[0].lower(), True) - def dictvalue(t): + def dictvalue(*t): if t[1] is True: return t[0] else: return '%s=%s' % (t[0], t[1]) + cc = defaultdict(set) if response.get('Cache-Control'): - cc = cc_delim_re.split(response['Cache-Control']) - cc = dict(dictitem(el) for el in cc) - else: - cc = {} + for field in cc_delim_re.split(response['Cache-Control']): + directive, value = dictitem(field) + if directive == 'no-cache': + # no-cache supports multiple field names. + cc[directive].add(value) + else: + cc[directive] = value # If there's already a max-age header but we're being asked to set a new # max-age, use the minimum of the two ages. In practice this happens when @@ -78,8 +83,23 @@ def patch_cache_control(response, **kwargs): del cc['public'] for (k, v) in kwargs.items(): - cc[k.replace('_', '-')] = v - cc = ', '.join(dictvalue(el) for el in cc.items()) + directive = k.replace('_', '-') + if directive == 'no-cache': + # no-cache supports multiple field names. + cc[directive].add(v) + else: + cc[directive] = v + + directives = [] + for directive, values in cc.items(): + if isinstance(values, set): + if True in values: + # True takes precedence. + values = {True} + directives.extend([dictvalue(directive, value) for value in values]) + else: + directives.append(dictvalue(directive, values)) + cc = ', '.join(directives) response['Cache-Control'] = cc |