From ac029fe4c91c96c66ea8c1c4cf3b74859f7199c4 Mon Sep 17 00:00:00 2001 From: "Gordon P. Hemsley" Date: Sat, 9 Jun 2012 19:01:59 -0400 Subject: [PATCH] Bug 672448 - Clamp quality factor ('q') values to 3 decimal places. r=biesi --- netwerk/protocol/http/nsHttp.h | 6 +- netwerk/protocol/http/nsHttpHandler.cpp | 56 +++++++++---------- .../test/unit/test_header_Accept-Language.js | 44 +++++++++++++++ netwerk/test/unit/xpcshell.ini | 31 +++++----- 4 files changed, 91 insertions(+), 46 deletions(-) create mode 100644 netwerk/test/unit/test_header_Accept-Language.js diff --git a/netwerk/protocol/http/nsHttp.h b/netwerk/protocol/http/nsHttp.h index a1376b810546..99755c810c76 100644 --- a/netwerk/protocol/http/nsHttp.h +++ b/netwerk/protocol/http/nsHttp.h @@ -20,7 +20,7 @@ // 2) #include IPDL boilerplate, and then undef LOG so our LOG wins. // 3) nsNetModule.cpp does its own crazy stuff with #including prlog.h // multiple times; allow it to define ALLOW_LATE_NSHTTP_H_INCLUDE to bypass -// check. +// check. #if defined(PR_LOG) && !defined(ALLOW_LATE_NSHTTP_H_INCLUDE) #error "If nsHttp.h #included it must come before any IPDL-generated files or other files that #include prlog.h" #endif @@ -181,7 +181,7 @@ struct nsHttp } // Declare all atoms - // + // // The atom names and values are stored in nsHttpAtomList.h and are brought // to you by the magic of C preprocessing. Add new atoms to nsHttpAtomList // and all support logic will be auto-generated. @@ -204,7 +204,7 @@ PRTimeToSeconds(PRTime t_usec) #define NowInSeconds() PRTimeToSeconds(PR_Now()) // round q-value to one decimal place; return most significant digit as uint. -#define QVAL_TO_UINT(q) ((unsigned int) ((q + 0.05) * 10.0)) +#define QVAL_TO_UINT(q) ((unsigned int) ((q + 0.0005) * 1000.0)) #define HTTP_LWS " \t" #define HTTP_HEADER_VALUE_SEPS HTTP_LWS "," diff --git a/netwerk/protocol/http/nsHttpHandler.cpp b/netwerk/protocol/http/nsHttpHandler.cpp index 71c948fa77a7..0a026128bb9e 100644 --- a/netwerk/protocol/http/nsHttpHandler.cpp +++ b/netwerk/protocol/http/nsHttpHandler.cpp @@ -234,7 +234,7 @@ nsHttpHandler::Init() if (prefBranch) { prefBranch->AddObserver(HTTP_PREF_PREFIX, this, true); prefBranch->AddObserver(UA_PREF_PREFIX, this, true); - prefBranch->AddObserver(INTL_ACCEPT_LANGUAGES, this, true); + prefBranch->AddObserver(INTL_ACCEPT_LANGUAGES, this, true); prefBranch->AddObserver(NETWORK_ENABLEIDN, this, true); prefBranch->AddObserver(BROWSER_PREF("disk_cache_ssl"), this, true); prefBranch->AddObserver(DONOTTRACK_HEADER_ENABLED, this, true); @@ -290,8 +290,8 @@ nsHttpHandler::Init() // Bring alive the objects in the http-protocol-startup category NS_CreateServicesFromCategory(NS_HTTP_STARTUP_CATEGORY, static_cast(static_cast(this)), - NS_HTTP_STARTUP_TOPIC); - + NS_HTTP_STARTUP_TOPIC); + mObserverService = mozilla::services::GetObserverService(); if (mObserverService) { mObserverService->AddObserver(this, "profile-change-net-teardown", true); @@ -301,7 +301,7 @@ nsHttpHandler::Init() mObserverService->AddObserver(this, "net:prune-dead-connections", true); mObserverService->AddObserver(this, "net:failed-to-process-uri-content", true); } - + return NS_OK; } @@ -363,10 +363,10 @@ nsHttpHandler::AddStandardRequestHeaders(nsHttpHeaderArray *request, // transparent proxies) can result. // // However, we need to send something so that we can use keepalive - // with HTTP/1.0 servers/proxies. We use "Proxy-Connection:" when + // with HTTP/1.0 servers/proxies. We use "Proxy-Connection:" when // we're talking to an http proxy, and "Connection:" otherwise. // We no longer send the Keep-Alive request header. - + NS_NAMED_LITERAL_CSTRING(close, "close"); NS_NAMED_LITERAL_CSTRING(keepAlive, "keep-alive"); @@ -402,7 +402,7 @@ nsHttpHandler::IsAcceptableEncoding(const char *enc) // to accept. if (!PL_strncasecmp(enc, "x-", 2)) enc += 2; - + return nsHttp::FindToken(mAcceptEncodings.get(), enc, HTTP_LWS ",") != nsnull; } @@ -435,7 +435,7 @@ nsHttpHandler::GetCookieService() return mCookieService; } -nsresult +nsresult nsHttpHandler::GetIOService(nsIIOService** result) { NS_ADDREF(*result = mIOService); @@ -452,7 +452,7 @@ nsHttpHandler::Get32BitsOfPseudoRandom() // 15 or 31 bits are common amounts. PR_STATIC_ASSERT(RAND_MAX >= 0xfff); - + #if RAND_MAX < 0xffffU return ((PRUint16) rand() << 20) | (((PRUint16) rand() & 0xfff) << 8) | @@ -523,10 +523,10 @@ nsHttpHandler::BuildUserAgent() // preallocate to worst-case size, which should always be better // than if we didn't preallocate at all. - mUserAgent.SetCapacity(mLegacyAppName.Length() + - mLegacyAppVersion.Length() + + mUserAgent.SetCapacity(mLegacyAppName.Length() + + mLegacyAppVersion.Length() + #ifndef UA_SPARE_PLATFORM - mPlatform.Length() + + mPlatform.Length() + #endif mOscpu.Length() + mMisc.Length() + @@ -672,7 +672,7 @@ nsHttpHandler::InitUserAgentComponents() } #elif defined (XP_UNIX) struct utsname name; - + int ret = uname(&name); if (ret >= 0) { nsCAutoString buf; @@ -1015,7 +1015,7 @@ nsHttpHandler::PrefsChanged(nsIPrefBranch *prefs, const char *pref) if (NS_SUCCEEDED(rv)) SetAccept(accept); } - + if (PREF_CHANGED(HTTP_PREF("accept-encoding"))) { nsXPIDLCString acceptEncodings; rv = prefs->GetCharPref(HTTP_PREF("accept-encoding"), @@ -1068,7 +1068,7 @@ nsHttpHandler::PrefsChanged(nsIPrefBranch *prefs, const char *pref) mEnforceAssocReq = cVar; } - // enable Persistent caching for HTTPS - bug#205921 + // enable Persistent caching for HTTPS - bug#205921 if (PREF_CHANGED(BROWSER_PREF("disk_cache_ssl"))) { cVar = false; rv = prefs->GetBoolPref(BROWSER_PREF("disk_cache_ssl"), &cVar); @@ -1157,7 +1157,7 @@ nsHttpHandler::PrefsChanged(nsIPrefBranch *prefs, const char *pref) pls->ToString(getter_Copies(uval)); if (uval) SetAcceptLanguages(NS_ConvertUTF16toUTF8(uval).get()); - } + } } // @@ -1275,8 +1275,8 @@ PrepareAcceptLanguages(const char *i_AcceptLanguages, nsACString &o_AcceptLangua if (*token != '\0') { comma = n++ != 0 ? "," : ""; // delimiter if not first item PRUint32 u = QVAL_TO_UINT(q); - if (u < 10) - wrote = PR_snprintf(p2, available, "%s%s;q=0.%u", comma, token, u); + if (u < 1000) + wrote = PR_snprintf(p2, available, "%s%s;q=0.%03u", comma, token, u); else wrote = PR_snprintf(p2, available, "%s%s", comma, token); q -= dec; @@ -1294,7 +1294,7 @@ PrepareAcceptLanguages(const char *i_AcceptLanguages, nsACString &o_AcceptLangua } nsresult -nsHttpHandler::SetAcceptLanguages(const char *aAcceptLanguages) +nsHttpHandler::SetAcceptLanguages(const char *aAcceptLanguages) { nsCAutoString buf; nsresult rv = PrepareAcceptLanguages(aAcceptLanguages, buf); @@ -1304,14 +1304,14 @@ nsHttpHandler::SetAcceptLanguages(const char *aAcceptLanguages) } nsresult -nsHttpHandler::SetAccept(const char *aAccept) +nsHttpHandler::SetAccept(const char *aAccept) { mAccept = aAccept; return NS_OK; } nsresult -nsHttpHandler::SetAcceptEncodings(const char *aAcceptEncodings) +nsHttpHandler::SetAcceptEncodings(const char *aAcceptEncodings) { mAcceptEncodings = aAcceptEncodings; return NS_OK; @@ -1385,14 +1385,14 @@ nsHttpHandler::NewChannel(nsIURI *uri, nsIChannel **result) return NS_ERROR_UNEXPECTED; } } - + return NewProxiedChannel(uri, nsnull, result); } -NS_IMETHODIMP +NS_IMETHODIMP nsHttpHandler::AllowPort(PRInt32 port, const char *scheme, bool *_retval) { - // don't override anything. + // don't override anything. *_retval = false; return NS_OK; } @@ -1410,7 +1410,7 @@ nsHttpHandler::NewProxiedChannel(nsIURI *uri, LOG(("nsHttpHandler::NewProxiedChannel [proxyInfo=%p]\n", givenProxyInfo)); - + nsCOMPtr proxyInfo; if (givenProxyInfo) { proxyInfo = do_QueryInterface(givenProxyInfo); @@ -1562,7 +1562,7 @@ nsHttpHandler::Observe(nsISupports *subject, if (uri && mConnMgr) mConnMgr->ReportFailedToProcess(uri); } - + return NS_OK; } @@ -1577,7 +1577,7 @@ nsHttpHandler::SpeculativeConnect(nsIURI *aURI, bool isStsHost = false; if (!stss) return NS_OK; - + nsCOMPtr clone; if (NS_SUCCEEDED(stss->IsStsURI(aURI, &isStsHost)) && isStsHost) { if (NS_SUCCEEDED(aURI->Clone(getter_AddRefs(clone)))) { @@ -1687,7 +1687,7 @@ nsHttpsHandler::NewChannel(nsIURI *aURI, nsIChannel **_retval) NS_IMETHODIMP nsHttpsHandler::AllowPort(PRInt32 aPort, const char *aScheme, bool *_retval) { - // don't override anything. + // don't override anything. *_retval = false; return NS_OK; } diff --git a/netwerk/test/unit/test_header_Accept-Language.js b/netwerk/test/unit/test_header_Accept-Language.js new file mode 100644 index 000000000000..b59313440964 --- /dev/null +++ b/netwerk/test/unit/test_header_Accept-Language.js @@ -0,0 +1,44 @@ +// +// HTTP Accept-Language header test +// + +const Cc = Components.classes; +const Ci = Components.interfaces; + +var testpath = "/bug672448"; + +function run_test() { + test_accepted_languages(); +} + +function test_accepted_languages() { + let channel = setupChannel(testpath); + + let AcceptLanguage = channel.getRequestHeader("Accept-Language"); + + let acceptedLanguages = AcceptLanguage.split(","); + + for( let i = 0; i < acceptedLanguages.length; i++ ) { + let acceptedLanguage, qualityValue; + + try { + [_, acceptedLanguage, qualityValue] = acceptedLanguages[i].trim().match(/^([a-z0-9_-]*?)(?:;q=([0-9.]+))?$/i); + } catch(e) { + do_print("Invalid language tag or quality value: " + e); + } + + if( i == 0 ) { + do_check_eq(qualityValue, undefined); // First language shouldn't have a quality value. + } else { + do_check_eq(qualityValue.length, 5); // All other languages should have quality value of the format '0.123'. + } + } +} + +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); + chan.requestMethod = "GET"; + return chan; +} diff --git a/netwerk/test/unit/xpcshell.ini b/netwerk/test/unit/xpcshell.ini index ffc29534fe6d..dfa361f3f8f4 100644 --- a/netwerk/test/unit/xpcshell.ini +++ b/netwerk/test/unit/xpcshell.ini @@ -1,6 +1,6 @@ [DEFAULT] head = head_channels.js -tail = +tail = [test_307_redirect.js] [test_NetUtil.js] @@ -40,7 +40,7 @@ skip-if = os == "android" [test_bug455311.js] [test_bug455598.js] [test_bug468426.js] -# Bug 675039: test hangs consistently on Android +# Bug 675039: test hangs consistently on Android skip-if = os == "android" [test_bug468594.js] [test_bug470716.js] @@ -51,7 +51,7 @@ skip-if = os == "android" [test_bug490095.js] [test_bug504014.js] [test_bug510359.js] -# Bug 675039: test hangs consistently on Android +# Bug 675039: test hangs consistently on Android skip-if = os == "android" [test_bug515583.js] [test_bug528292.js] @@ -69,16 +69,16 @@ skip-if = os == "android" [test_bug652761.js] [test_bug651100.js] # Bug 675044: test fails consistently on Android -fail-if = os == "android" +fail-if = os == "android" [test_bug654926.js] # Bug 675049: test fails consistently on Android -fail-if = os == "android" +fail-if = os == "android" [test_bug654926_doom_and_read.js] # Bug 675049: test fails consistently on Android -fail-if = os == "android" +fail-if = os == "android" [test_bug654926_test_seek.js] # Bug 675049: test fails consistently on Android -fail-if = os == "android" +fail-if = os == "android" [test_bug659569.js] [test_bug660066.js] [test_bug667907.js] @@ -99,28 +99,28 @@ fail-if = os == "android" [test_event_sink.js] [test_extract_charset_from_content_type.js] [test_fallback_no-cache-entry_canceled.js] -# Bug 675039: test hangs consistently on Android +# Bug 675039: test hangs consistently on Android skip-if = os == "android" [test_fallback_no-cache-entry_passing.js] -# Bug 675039: test hangs consistently on Android +# Bug 675039: test hangs consistently on Android skip-if = os == "android" [test_fallback_redirect-to-different-origin_canceled.js] -# Bug 675039: test hangs consistently on Android +# Bug 675039: test hangs consistently on Android skip-if = os == "android" [test_fallback_redirect-to-different-origin_passing.js] -# Bug 675039: test hangs consistently on Android +# Bug 675039: test hangs consistently on Android skip-if = os == "android" [test_fallback_request-error_canceled.js] -# Bug 675039: test hangs consistently on Android +# Bug 675039: test hangs consistently on Android skip-if = os == "android" [test_fallback_request-error_passing.js] -# Bug 675039: test hangs consistently on Android +# Bug 675039: test hangs consistently on Android skip-if = os == "android" [test_fallback_response-error_canceled.js] -# Bug 675039: test hangs consistently on Android +# Bug 675039: test hangs consistently on Android skip-if = os == "android" [test_fallback_response-error_passing.js] -# Bug 675039: test hangs consistently on Android +# Bug 675039: test hangs consistently on Android skip-if = os == "android" [test_file_partial_inputstream.js] [test_file_protocol.js] @@ -128,6 +128,7 @@ skip-if = os == "android" [test_gre_resources.js] [test_gzipped_206.js] [test_head.js] +[test_header_Accept-Language.js] [test_headers.js] [test_http_headers.js] [test_httpcancel.js]