Fixed #18191 -- Don't consider Accept-Language redundantly in cache key.
Thanks to choongmin for the original patch.
This commit is contained in:
parent
e76147a83a
commit
6a057e1595
|
@ -236,8 +236,18 @@ def learn_cache_key(request, response, cache_timeout=None, key_prefix=None, cach
|
||||||
if cache is None:
|
if cache is None:
|
||||||
cache = get_cache(settings.CACHE_MIDDLEWARE_ALIAS)
|
cache = get_cache(settings.CACHE_MIDDLEWARE_ALIAS)
|
||||||
if response.has_header('Vary'):
|
if response.has_header('Vary'):
|
||||||
headerlist = ['HTTP_'+header.upper().replace('-', '_')
|
is_accept_language_redundant = settings.USE_I18N or settings.USE_L10N
|
||||||
for header in cc_delim_re.split(response['Vary'])]
|
# If i18n or l10n are used, the generated cache key will be suffixed
|
||||||
|
# with the current locale. Adding the raw value of Accept-Language is
|
||||||
|
# redundant in that case and would result in storing the same content
|
||||||
|
# under multiple keys in the cache. See #18191 for details.
|
||||||
|
headerlist = []
|
||||||
|
for header in cc_delim_re.split(response['Vary']):
|
||||||
|
header = header.upper().replace('-', '_')
|
||||||
|
if header == 'ACCEPT_LANGUAGE' and is_accept_language_redundant:
|
||||||
|
continue
|
||||||
|
headerlist.append('HTTP_' + header)
|
||||||
|
headerlist.sort()
|
||||||
cache.set(cache_key, headerlist, cache_timeout)
|
cache.set(cache_key, headerlist, cache_timeout)
|
||||||
return _generate_cache_key(request, request.method, headerlist, key_prefix)
|
return _generate_cache_key(request, request.method, headerlist, key_prefix)
|
||||||
else:
|
else:
|
||||||
|
|
|
@ -1324,6 +1324,73 @@ class CacheI18nTest(TestCase):
|
||||||
key2 = get_cache_key(request)
|
key2 = get_cache_key(request)
|
||||||
self.assertEqual(key, key2)
|
self.assertEqual(key, key2)
|
||||||
|
|
||||||
|
def check_accept_language_vary(self, accept_language, vary, reference_key):
|
||||||
|
request = self._get_request()
|
||||||
|
request.META['HTTP_ACCEPT_LANGUAGE'] = accept_language
|
||||||
|
request.META['HTTP_ACCEPT_ENCODING'] = 'gzip;q=1.0, identity; q=0.5, *;q=0'
|
||||||
|
response = HttpResponse()
|
||||||
|
response['Vary'] = vary
|
||||||
|
key = learn_cache_key(request, response)
|
||||||
|
key2 = get_cache_key(request)
|
||||||
|
self.assertEqual(key, reference_key)
|
||||||
|
self.assertEqual(key2, reference_key)
|
||||||
|
|
||||||
|
@override_settings(USE_I18N=True, USE_L10N=False, USE_TZ=False)
|
||||||
|
def test_cache_key_i18n_translation_accept_language(self):
|
||||||
|
lang = translation.get_language()
|
||||||
|
self.assertEqual(lang, 'en')
|
||||||
|
request = self._get_request()
|
||||||
|
request.META['HTTP_ACCEPT_ENCODING'] = 'gzip;q=1.0, identity; q=0.5, *;q=0'
|
||||||
|
response = HttpResponse()
|
||||||
|
response['Vary'] = 'accept-encoding'
|
||||||
|
key = learn_cache_key(request, response)
|
||||||
|
self.assertIn(lang, key, "Cache keys should include the language name when translation is active")
|
||||||
|
self.check_accept_language_vary(
|
||||||
|
'en-us',
|
||||||
|
'cookie, accept-language, accept-encoding',
|
||||||
|
key
|
||||||
|
)
|
||||||
|
self.check_accept_language_vary(
|
||||||
|
'en-US',
|
||||||
|
'cookie, accept-encoding, accept-language',
|
||||||
|
key
|
||||||
|
)
|
||||||
|
self.check_accept_language_vary(
|
||||||
|
'en-US,en;q=0.8',
|
||||||
|
'accept-encoding, accept-language, cookie',
|
||||||
|
key
|
||||||
|
)
|
||||||
|
self.check_accept_language_vary(
|
||||||
|
'en-US,en;q=0.8,ko;q=0.6',
|
||||||
|
'accept-language, cookie, accept-encoding',
|
||||||
|
key
|
||||||
|
)
|
||||||
|
self.check_accept_language_vary(
|
||||||
|
'ko-kr,ko;q=0.8,en-us;q=0.5,en;q=0.3 ',
|
||||||
|
'accept-encoding, cookie, accept-language',
|
||||||
|
key
|
||||||
|
)
|
||||||
|
self.check_accept_language_vary(
|
||||||
|
'ko-KR,ko;q=0.8,en-US;q=0.6,en;q=0.4',
|
||||||
|
'accept-language, accept-encoding, cookie',
|
||||||
|
key
|
||||||
|
)
|
||||||
|
self.check_accept_language_vary(
|
||||||
|
'ko;q=1.0,en;q=0.5',
|
||||||
|
'cookie, accept-language, accept-encoding',
|
||||||
|
key
|
||||||
|
)
|
||||||
|
self.check_accept_language_vary(
|
||||||
|
'ko, en',
|
||||||
|
'cookie, accept-encoding, accept-language',
|
||||||
|
key
|
||||||
|
)
|
||||||
|
self.check_accept_language_vary(
|
||||||
|
'ko-KR, en-US',
|
||||||
|
'accept-encoding, accept-language, cookie',
|
||||||
|
key
|
||||||
|
)
|
||||||
|
|
||||||
@override_settings(USE_I18N=False, USE_L10N=True, USE_TZ=False)
|
@override_settings(USE_I18N=False, USE_L10N=True, USE_TZ=False)
|
||||||
def test_cache_key_i18n_formatting(self):
|
def test_cache_key_i18n_formatting(self):
|
||||||
request = self._get_request()
|
request = self._get_request()
|
||||||
|
|
Loading…
Reference in New Issue