Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

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

  • Loading branch information...
commit 539900f117dce5d9b51e2b9e8ff225c423060d52 1 parent e329626
Łukasz Langa authored February 23, 2013
26  django/middleware/locale.py
@@ -17,6 +17,14 @@ class LocaleMiddleware(object):
17 17
     is available, of course).
18 18
     """
19 19
 
  20
+    def __init__(self):
  21
+        self._supported_languages = dict(settings.LANGUAGES)
  22
+        self._is_language_prefix_patterns_used = False
  23
+        for url_pattern in get_resolver(None).url_patterns:
  24
+            if isinstance(url_pattern, LocaleRegexURLResolver):
  25
+                self._is_language_prefix_patterns_used = True
  26
+                break
  27
+
20 28
     def process_request(self, request):
21 29
         check_path = self.is_language_prefix_patterns_used()
22 30
         language = translation.get_language_from_request(
@@ -26,9 +34,11 @@ def process_request(self, request):
26 34
 
27 35
     def process_response(self, request, response):
28 36
         language = translation.get_language()
29  
-        if (response.status_code == 404 and
30  
-                not translation.get_language_from_path(request.path_info)
31  
-                    and self.is_language_prefix_patterns_used()):
  37
+        language_from_path = translation.get_language_from_path(
  38
+                request.path_info, supported=self._supported_languages
  39
+        )
  40
+        if (response.status_code == 404 and not language_from_path
  41
+                and self.is_language_prefix_patterns_used()):
32 42
             urlconf = getattr(request, 'urlconf', None)
33 43
             language_path = '/%s%s' % (language, request.path_info)
34 44
             path_valid = is_valid_path(language_path, urlconf)
@@ -42,8 +52,9 @@ def process_response(self, request, response):
42 52
                     request.get_host(), language, request.get_full_path())
43 53
                 return HttpResponseRedirect(language_url)
44 54
         translation.deactivate()
45  
-
46  
-        patch_vary_headers(response, ('Accept-Language',))
  55
+        if not (self.is_language_prefix_patterns_used()
  56
+                and language_from_path):
  57
+            patch_vary_headers(response, ('Accept-Language',))
47 58
         if 'Content-Language' not in response:
48 59
             response['Content-Language'] = language
49 60
         return response
@@ -53,7 +64,4 @@ def is_language_prefix_patterns_used(self):
53 64
         Returns `True` if the `LocaleRegexURLResolver` is used
54 65
         at root level of the urlpatterns, else it returns `False`.
55 66
         """
56  
-        for url_pattern in get_resolver(None).url_patterns:
57  
-            if isinstance(url_pattern, LocaleRegexURLResolver):
58  
-                return True
59  
-        return False
  67
+        return self._is_language_prefix_patterns_used
4  django/utils/translation/__init__.py
@@ -165,8 +165,8 @@ def to_locale(language):
165 165
 def get_language_from_request(request, check_path=False):
166 166
     return _trans.get_language_from_request(request, check_path)
167 167
 
168  
-def get_language_from_path(path):
169  
-    return _trans.get_language_from_path(path)
  168
+def get_language_from_path(path, supported=None):
  169
+    return _trans.get_language_from_path(path, supported=supported)
170 170
 
171 171
 def templatize(src, origin=None):
172 172
     return _trans.templatize(src, origin)
2  django/utils/translation/trans_null.py
@@ -58,6 +58,6 @@ def to_locale(language):
58 58
 def get_language_from_request(request, check_path=False):
59 59
     return settings.LANGUAGE_CODE
60 60
 
61  
-def get_language_from_path(request):
  61
+def get_language_from_path(request, supported=None):
62 62
     return None
63 63
 
20  tests/regressiontests/i18n/patterns/tests.py
@@ -172,6 +172,26 @@ def test_pt_br_redirect(self):
172 172
         self.assertEqual(response.status_code, 200)
173 173
 
174 174
 
  175
+class URLVaryAcceptLanguageTests(URLTestCaseBase):
  176
+    """
  177
+    Tests that 'Accept-Language' is not added to the Vary header when using
  178
+    prefixed URLs. 
  179
+    """
  180
+    def test_no_prefix_response(self):
  181
+        response = self.client.get('/not-prefixed/')
  182
+        self.assertEqual(response.status_code, 200)
  183
+        self.assertEqual(response.get('Vary'), 'Accept-Language')
  184
+
  185
+    def test_en_redirect(self):
  186
+        response = self.client.get('/account/register/', HTTP_ACCEPT_LANGUAGE='en')
  187
+        self.assertRedirects(response, '/en/account/register/')
  188
+        self.assertFalse(response.get('Vary'))
  189
+
  190
+        response = self.client.get(response['location'])
  191
+        self.assertEqual(response.status_code, 200)
  192
+        self.assertFalse(response.get('Vary'))
  193
+
  194
+
175 195
 class URLRedirectWithoutTrailingSlashTests(URLTestCaseBase):
176 196
     """
177 197
     Tests the redirect when the requested URL doesn't end with a slash
3  tests/regressiontests/i18n/tests.py
@@ -48,7 +48,8 @@
48 48
 from .patterns.tests import (URLRedirectWithoutTrailingSlashTests,
49 49
     URLTranslationTests, URLDisabledTests, URLTagTests, URLTestCaseBase,
50 50
     URLRedirectWithoutTrailingSlashSettingTests, URLNamespaceTests,
51  
-    URLPrefixTests, URLResponseTests, URLRedirectTests, PathUnusedTests)
  51
+    URLPrefixTests, URLResponseTests, URLRedirectTests, PathUnusedTests,
  52
+    URLVaryAcceptLanguageTests)
52 53
 
53 54
 
54 55
 here = os.path.dirname(os.path.abspath(upath(__file__)))

0 notes on commit 539900f

Please sign in to comment.
Something went wrong with that request. Please try again.