Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Fixes #17866: Vary: Accept-Language header when language prefix used

  • Loading branch information...
commit 539900f117dce5d9b51e2b9e8ff225c423060d52 1 parent e329626
@ambv ambv authored
View
26 django/middleware/locale.py
@@ -17,6 +17,14 @@ class LocaleMiddleware(object):
is available, of course).
"""
+ def __init__(self):
+ self._supported_languages = dict(settings.LANGUAGES)
+ self._is_language_prefix_patterns_used = False
+ for url_pattern in get_resolver(None).url_patterns:
+ if isinstance(url_pattern, LocaleRegexURLResolver):
+ self._is_language_prefix_patterns_used = True
+ break
+
def process_request(self, request):
check_path = self.is_language_prefix_patterns_used()
language = translation.get_language_from_request(
@@ -26,9 +34,11 @@ def process_request(self, request):
def process_response(self, request, response):
language = translation.get_language()
- if (response.status_code == 404 and
- not translation.get_language_from_path(request.path_info)
- and self.is_language_prefix_patterns_used()):
+ language_from_path = translation.get_language_from_path(
+ request.path_info, supported=self._supported_languages
+ )
+ if (response.status_code == 404 and not language_from_path
+ and self.is_language_prefix_patterns_used()):
urlconf = getattr(request, 'urlconf', None)
language_path = '/%s%s' % (language, request.path_info)
path_valid = is_valid_path(language_path, urlconf)
@@ -42,8 +52,9 @@ def process_response(self, request, response):
request.get_host(), language, request.get_full_path())
return HttpResponseRedirect(language_url)
translation.deactivate()
-
- patch_vary_headers(response, ('Accept-Language',))
+ if not (self.is_language_prefix_patterns_used()
+ and language_from_path):
+ patch_vary_headers(response, ('Accept-Language',))
if 'Content-Language' not in response:
response['Content-Language'] = language
return response
@@ -53,7 +64,4 @@ def is_language_prefix_patterns_used(self):
Returns `True` if the `LocaleRegexURLResolver` is used
at root level of the urlpatterns, else it returns `False`.
"""
- for url_pattern in get_resolver(None).url_patterns:
- if isinstance(url_pattern, LocaleRegexURLResolver):
- return True
- return False
+ return self._is_language_prefix_patterns_used
View
4 django/utils/translation/__init__.py
@@ -165,8 +165,8 @@ def to_locale(language):
def get_language_from_request(request, check_path=False):
return _trans.get_language_from_request(request, check_path)
-def get_language_from_path(path):
- return _trans.get_language_from_path(path)
+def get_language_from_path(path, supported=None):
+ return _trans.get_language_from_path(path, supported=supported)
def templatize(src, origin=None):
return _trans.templatize(src, origin)
View
2  django/utils/translation/trans_null.py
@@ -58,6 +58,6 @@ def to_locale(language):
def get_language_from_request(request, check_path=False):
return settings.LANGUAGE_CODE
-def get_language_from_path(request):
+def get_language_from_path(request, supported=None):
return None
View
20 tests/regressiontests/i18n/patterns/tests.py
@@ -172,6 +172,26 @@ def test_pt_br_redirect(self):
self.assertEqual(response.status_code, 200)
+class URLVaryAcceptLanguageTests(URLTestCaseBase):
+ """
+ Tests that 'Accept-Language' is not added to the Vary header when using
+ prefixed URLs.
+ """
+ def test_no_prefix_response(self):
+ response = self.client.get('/not-prefixed/')
+ self.assertEqual(response.status_code, 200)
+ self.assertEqual(response.get('Vary'), 'Accept-Language')
+
+ def test_en_redirect(self):
+ response = self.client.get('/account/register/', HTTP_ACCEPT_LANGUAGE='en')
+ self.assertRedirects(response, '/en/account/register/')
+ self.assertFalse(response.get('Vary'))
+
+ response = self.client.get(response['location'])
+ self.assertEqual(response.status_code, 200)
+ self.assertFalse(response.get('Vary'))
+
+
class URLRedirectWithoutTrailingSlashTests(URLTestCaseBase):
"""
Tests the redirect when the requested URL doesn't end with a slash
View
3  tests/regressiontests/i18n/tests.py
@@ -48,7 +48,8 @@
from .patterns.tests import (URLRedirectWithoutTrailingSlashTests,
URLTranslationTests, URLDisabledTests, URLTagTests, URLTestCaseBase,
URLRedirectWithoutTrailingSlashSettingTests, URLNamespaceTests,
- URLPrefixTests, URLResponseTests, URLRedirectTests, PathUnusedTests)
+ URLPrefixTests, URLResponseTests, URLRedirectTests, PathUnusedTests,
+ URLVaryAcceptLanguageTests)
here = os.path.dirname(os.path.abspath(upath(__file__)))
Please sign in to comment.
Something went wrong with that request. Please try again.