summaryrefslogtreecommitdiff
path: root/django/utils/cache.py
diff options
context:
space:
mode:
authorFlavio Curella <flavio.curella@gmail.com>2019-09-26 13:58:14 -0700
committerMariusz Felisiak <felisiak.mariusz@gmail.com>2019-10-10 19:30:51 +0200
commited112fadc1cfa400dbee6080bf82fd7536ea4c72 (patch)
treedc96114d797f815577a61c12abc899dbb8307277 /django/utils/cache.py
parent2a6f45e08e8cb8c7e5157915c378b453109424d2 (diff)
downloaddjango-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.py34
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