Commit c2a04519 authored by Honza Král's avatar Honza Král
Browse files

Merge pull request #796 from ambv/vary

Fixes #17866: Vary: Accept-Language header when language prefix used
parents 9b97f01d 539900f1
Loading
Loading
Loading
Loading
+17 −9
Original line number Diff line number Diff line
@@ -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,8 +34,10 @@ class LocaleMiddleware(object):

    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)
        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)
@@ -42,7 +52,8 @@ class LocaleMiddleware(object):
                    request.get_host(), language, request.get_full_path())
                return HttpResponseRedirect(language_url)
        translation.deactivate()

        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
@@ -53,7 +64,4 @@ class LocaleMiddleware(object):
        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
+2 −2
Original line number Diff line number Diff line
@@ -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)
+1 −1
Original line number Diff line number Diff line
@@ -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
+20 −0
Original line number Diff line number Diff line
@@ -172,6 +172,26 @@ class URLRedirectTests(URLTestCaseBase):
        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
+2 −1
Original line number Diff line number Diff line
@@ -48,7 +48,8 @@ from .models import Company, TestModel
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__)))