From 1130647145aadd259cfb14cfd81e5af4b3714985 Mon Sep 17 00:00:00 2001 From: Florian Best Date: Mon, 3 Dec 2018 19:39:36 +0100 Subject: [PATCH 1/2] Enhance parsing of Accept-Language quality values The following cases were not possible: "Accept-Language: en-US; foo=bar; q=0.9" "Accept-Language: en-US; q = 0.9" --- tornado/test/web_test.py | 8 ++++++++ tornado/web.py | 13 ++++++++----- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/tornado/test/web_test.py b/tornado/test/web_test.py index 396ba6dafb..8eeecac2f6 100644 --- a/tornado/test/web_test.py +++ b/tornado/test/web_test.py @@ -3183,6 +3183,14 @@ def test_accept_language(self): response = self.fetch("/", headers={"Accept-Language": "fr-FR; q=0.9"}) self.assertEqual(response.headers["Content-Language"], "fr-FR") + response = self.fetch("/", headers={"Accept-Language": "fr-FR; foo=bar; q=0.9"}) + self.assertEqual(response.headers["Content-Language"], "fr-FR") + + response = self.fetch( + "/", headers={"Accept-Language": "fr-FR; foo=bar; q = 0.9"} + ) + self.assertEqual(response.headers["Content-Language"], "fr-FR") + def test_accept_language_ignore(self): response = self.fetch("/", headers={"Accept-Language": "fr-FR;q=0"}) self.assertEqual(response.headers["Content-Language"], "en-US") diff --git a/tornado/web.py b/tornado/web.py index cd6a81b4b5..2b55740bfa 100644 --- a/tornado/web.py +++ b/tornado/web.py @@ -1292,17 +1292,20 @@ def get_browser_locale(self, default: str = "en_US") -> tornado.locale.Locale: locales = [] for language in languages: parts = language.strip().split(";") - if len(parts) > 1 and parts[1].strip().startswith("q="): + score = 1.0 + for part in parts[1:]: + if "=" not in part or part.split("=", 1)[0].strip() != "q": + continue + part = part.split("=", 1)[1].strip() try: - score = float(parts[1].strip()[2:]) + score = float(part) if score < 0: raise ValueError() except (ValueError, TypeError): score = 0.0 - else: - score = 1.0 + break if score > 0: - locales.append((parts[0], score)) + locales.append((parts[0].strip(), score)) if locales: locales.sort(key=lambda pair: pair[1], reverse=True) codes = [loc[0] for loc in locales] From 7164da5c11b0f0a89ac39bbdb9375f7d4bed132f Mon Sep 17 00:00:00 2001 From: Florian Best Date: Mon, 29 Aug 2022 10:32:03 +0200 Subject: [PATCH 2/2] fixup! Enhance parsing of Accept-Language quality values --- tornado/web.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/tornado/web.py b/tornado/web.py index 2b55740bfa..7579b657d5 100644 --- a/tornado/web.py +++ b/tornado/web.py @@ -1294,9 +1294,13 @@ def get_browser_locale(self, default: str = "en_US") -> tornado.locale.Locale: parts = language.strip().split(";") score = 1.0 for part in parts[1:]: - if "=" not in part or part.split("=", 1)[0].strip() != "q": + try: + pname, part = part.split("=", 1) + except ValueError: + continue + if pname.strip() != "q": continue - part = part.split("=", 1)[1].strip() + part = part.strip() try: score = float(part) if score < 0: