Fixed #23689 -- Made parsing HTTP Accept-Language header case-insensitive.

Thank you Daniel Samuels for test project.
This commit is contained in:
Zainab Amir 2022-06-16 00:11:36 +05:00 committed by Mariusz Felisiak
parent d19a53d8e3
commit 901a169198
3 changed files with 10 additions and 5 deletions

View File

@ -61,7 +61,7 @@ def get_language_from_path(request):
def get_supported_language_variant(lang_code, strict=False): def get_supported_language_variant(lang_code, strict=False):
if lang_code == settings.LANGUAGE_CODE: if lang_code and lang_code.lower() == settings.LANGUAGE_CODE.lower():
return lang_code return lang_code
else: else:
raise LookupError(lang_code) raise LookupError(lang_code)

View File

@ -478,8 +478,9 @@ def check_for_language(lang_code):
def get_languages(): def get_languages():
""" """
Cache of settings.LANGUAGES in a dictionary for easy lookups by key. Cache of settings.LANGUAGES in a dictionary for easy lookups by key.
Convert keys to lowercase as they should be treated as case-insensitive.
""" """
return dict(settings.LANGUAGES) return {key.lower(): value for key, value in dict(settings.LANGUAGES).items()}
@functools.lru_cache(maxsize=1000) @functools.lru_cache(maxsize=1000)
@ -510,7 +511,7 @@ def get_supported_language_variant(lang_code, strict=False):
supported_lang_codes = get_languages() supported_lang_codes = get_languages()
for code in possible_lang_codes: for code in possible_lang_codes:
if code in supported_lang_codes and check_for_language(code): if code.lower() in supported_lang_codes and check_for_language(code):
return code return code
if not strict: if not strict:
# if fr-fr is not supported, try fr-ca. # if fr-fr is not supported, try fr-ca.

View File

@ -1902,9 +1902,10 @@ class MiscTests(SimpleTestCase):
USE_I18N=True, USE_I18N=True,
LANGUAGES=[ LANGUAGES=[
("en", "English"), ("en", "English"),
("ar-dz", "Algerian Arabic"),
("de", "German"), ("de", "German"),
("de-at", "Austrian German"), ("de-at", "Austrian German"),
("pt-br", "Portuguese (Brazil)"), ("pt-BR", "Portuguese (Brazil)"),
], ],
) )
def test_get_supported_language_variant_real(self): def test_get_supported_language_variant_real(self):
@ -1915,8 +1916,11 @@ class MiscTests(SimpleTestCase):
self.assertEqual(g("de-at"), "de-at") self.assertEqual(g("de-at"), "de-at")
self.assertEqual(g("de-ch"), "de") self.assertEqual(g("de-ch"), "de")
self.assertEqual(g("pt-br"), "pt-br") self.assertEqual(g("pt-br"), "pt-br")
self.assertEqual(g("pt-BR"), "pt-BR")
self.assertEqual(g("pt"), "pt-br") self.assertEqual(g("pt"), "pt-br")
self.assertEqual(g("pt-pt"), "pt-br") self.assertEqual(g("pt-pt"), "pt-br")
self.assertEqual(g("ar-dz"), "ar-dz")
self.assertEqual(g("ar-DZ"), "ar-DZ")
with self.assertRaises(LookupError): with self.assertRaises(LookupError):
g("pt", strict=True) g("pt", strict=True)
with self.assertRaises(LookupError): with self.assertRaises(LookupError):
@ -1946,7 +1950,6 @@ class MiscTests(SimpleTestCase):
LANGUAGES=[ LANGUAGES=[
("en", "English"), ("en", "English"),
("en-latn-us", "Latin English"), ("en-latn-us", "Latin English"),
("en-Latn-US", "BCP 47 case format"),
("de", "German"), ("de", "German"),
("de-1996", "German, orthography of 1996"), ("de-1996", "German, orthography of 1996"),
("de-at", "Austrian German"), ("de-at", "Austrian German"),
@ -1970,6 +1973,7 @@ class MiscTests(SimpleTestCase):
("/de/", "de"), ("/de/", "de"),
("/de-1996/", "de-1996"), ("/de-1996/", "de-1996"),
("/de-at/", "de-at"), ("/de-at/", "de-at"),
("/de-AT/", "de-AT"),
("/de-ch/", "de"), ("/de-ch/", "de"),
("/de-ch-1901/", "de-ch-1901"), ("/de-ch-1901/", "de-ch-1901"),
("/de-simple-page-test/", None), ("/de-simple-page-test/", None),