From a032f44b4b8e1d89c61cc5338ffc63fb920f2b17 Mon Sep 17 00:00:00 2001 From: awake Date: Thu, 27 Nov 2014 15:23:00 +0100 Subject: [PATCH] Bug 1054739 - Normalize language tags when setting the Accept-Language header. r=gerv,mcmanus --- netwerk/protocol/http/nsHttpHandler.cpp | 21 ++++++++++++ .../unit/test_header_Accept-Language_case.js | 32 +++++++++++++++++++ netwerk/test/unit/xpcshell.ini | 1 + 3 files changed, 54 insertions(+) create mode 100644 netwerk/test/unit/test_header_Accept-Language_case.js diff --git a/netwerk/protocol/http/nsHttpHandler.cpp b/netwerk/protocol/http/nsHttpHandler.cpp index a3a6d312a447..1ef14cdf1bc7 100644 --- a/netwerk/protocol/http/nsHttpHandler.cpp +++ b/netwerk/protocol/http/nsHttpHandler.cpp @@ -1519,6 +1519,25 @@ nsHttpHandler::TimerCallback(nsITimer * aTimer, void * aClosure) thisObject->mCapabilities &= ~NS_HTTP_ALLOW_PIPELINING; } +static void +NormalizeLanguageTag(char *code) +{ + bool is_region = false; + while (*code != '\0') + { + if (*code == '-') { + is_region = true; + } else { + if (is_region) { + *code = nsCRT::ToUpper(*code); + } else { + *code = nsCRT::ToLower(*code); + } + } + code++; + } +} + /** * Allocates a C string into that contains a ISO 639 language list * notated with HTTP "q" values for output with a HTTP Accept-Language @@ -1574,6 +1593,8 @@ PrepareAcceptLanguages(const char *i_AcceptLanguages, nsACString &o_AcceptLangua *trim = '\0'; if (*token != '\0') { + NormalizeLanguageTag(token); + comma = count_n++ != 0 ? "," : ""; // delimiter if not first item uint32_t u = QVAL_TO_UINT(q); diff --git a/netwerk/test/unit/test_header_Accept-Language_case.js b/netwerk/test/unit/test_header_Accept-Language_case.js new file mode 100644 index 000000000000..c13494dbb7af --- /dev/null +++ b/netwerk/test/unit/test_header_Accept-Language_case.js @@ -0,0 +1,32 @@ +var testpath = "/bug1054739"; + +function run_test() { + let intlPrefs = Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefService).getBranch("intl."); + + let oldAcceptLangPref = intlPrefs.getCharPref("accept_languages"); + + let testData = [ + ["de, en-US, en", "de,en-US;q=0.7,en;q=0.3"], + ["de,en-us,en", "de,en-US;q=0.7,en;q=0.3"], + ["en-US, en", "en-US,en;q=0.5"], + ["EN-US;q=0.2, EN", "en-US,en;q=0.5"], + ]; + + for (let i = 0; i < testData.length; i++) { + let acceptLangPref = testData[i][0]; + let expectedHeader = testData[i][1]; + + intlPrefs.setCharPref("accept_languages", acceptLangPref); + let acceptLangHeader = setupChannel(testpath).getRequestHeader("Accept-Language"); + equal(acceptLangHeader, expectedHeader); + } + + intlPrefs.setCharPref("accept_languages", oldAcceptLangPref); +} + +function setupChannel(path) { + let ios = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService); + let chan = ios.newChannel("http://localhost:4444" + path, "", null); + chan.QueryInterface(Ci.nsIHttpChannel); + return chan; +} diff --git a/netwerk/test/unit/xpcshell.ini b/netwerk/test/unit/xpcshell.ini index 1510577028b4..54df63810940 100644 --- a/netwerk/test/unit/xpcshell.ini +++ b/netwerk/test/unit/xpcshell.ini @@ -198,6 +198,7 @@ skip-if = bits != 32 [test_gzipped_206.js] [test_head.js] [test_header_Accept-Language.js] +[test_header_Accept-Language_case.js] [test_headers.js] [test_http_headers.js] [test_httpauth.js]