LCOV - code coverage report
Current view: top level - netwerk/protocol/http - nsHttpHandler.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 264 1194 22.1 %
Date: 2018-08-07 16:35:00 Functions: 0 0 -
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /* vim:set ts=4 sw=4 sts=4 et cin: */
       3             : /* This Source Code Form is subject to the terms of the Mozilla Public
       4             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       5             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
       6             : 
       7             : // HttpLog.h should generally be included first
       8             : #include "HttpLog.h"
       9             : 
      10             : #include "prsystem.h"
      11             : 
      12             : #include "nsError.h"
      13             : #include "nsHttp.h"
      14             : #include "nsHttpHandler.h"
      15             : #include "nsHttpChannel.h"
      16             : #include "nsHttpAuthCache.h"
      17             : #include "nsStandardURL.h"
      18             : #include "nsIDOMWindow.h"
      19             : #include "nsINetworkProperties.h"
      20             : #include "nsIHttpChannel.h"
      21             : #include "nsIStandardURL.h"
      22             : #include "LoadContextInfo.h"
      23             : #include "nsCategoryManagerUtils.h"
      24             : #include "nsIPrefService.h"
      25             : #include "nsIPrefBranch.h"
      26             : #include "nsIPrefLocalizedString.h"
      27             : #include "nsISocketProviderService.h"
      28             : #include "nsISocketProvider.h"
      29             : #include "nsPrintfCString.h"
      30             : #include "nsCOMPtr.h"
      31             : #include "nsNetCID.h"
      32             : #include "mozilla/ClearOnShutdown.h"
      33             : #include "mozilla/Printf.h"
      34             : #include "mozilla/Sprintf.h"
      35             : #include "nsAsyncRedirectVerifyHelper.h"
      36             : #include "nsSocketTransportService2.h"
      37             : #include "nsAlgorithm.h"
      38             : #include "ASpdySession.h"
      39             : #include "EventTokenBucket.h"
      40             : #include "Tickler.h"
      41             : #include "nsIXULAppInfo.h"
      42             : #include "nsICookieService.h"
      43             : #include "nsIObserverService.h"
      44             : #include "nsISiteSecurityService.h"
      45             : #include "nsIStreamConverterService.h"
      46             : #include "nsCRT.h"
      47             : #include "nsIMemoryReporter.h"
      48             : #include "nsIParentalControlsService.h"
      49             : #include "nsPIDOMWindow.h"
      50             : #include "nsINetworkLinkService.h"
      51             : #include "nsHttpChannelAuthProvider.h"
      52             : #include "nsServiceManagerUtils.h"
      53             : #include "nsComponentManagerUtils.h"
      54             : #include "nsSocketTransportService2.h"
      55             : #include "nsIOService.h"
      56             : #include "nsISupportsPrimitives.h"
      57             : #include "nsIXULRuntime.h"
      58             : #include "nsCharSeparatedTokenizer.h"
      59             : #include "nsRFPService.h"
      60             : #include "rust-helper/src/helper.h"
      61             : 
      62             : #include "mozilla/net/NeckoChild.h"
      63             : #include "mozilla/net/NeckoParent.h"
      64             : #include "mozilla/ipc/URIUtils.h"
      65             : #include "mozilla/Telemetry.h"
      66             : #include "mozilla/Unused.h"
      67             : #include "mozilla/BasePrincipal.h"
      68             : 
      69             : #include "mozilla/dom/ContentParent.h"
      70             : #include "mozilla/dom/Navigator.h"
      71             : 
      72             : #include "nsNSSComponent.h"
      73             : 
      74             : #if defined(XP_UNIX)
      75             : #include <sys/utsname.h>
      76             : #endif
      77             : 
      78             : #if defined(XP_WIN)
      79             : #include <windows.h>
      80             : #include "mozilla/WindowsVersion.h"
      81             : #endif
      82             : 
      83             : #if defined(XP_MACOSX)
      84             : #include <CoreServices/CoreServices.h>
      85             : #include "nsCocoaFeatures.h"
      86             : #endif
      87             : 
      88             : #ifdef MOZ_TASK_TRACER
      89             : #include "GeckoTaskTracer.h"
      90             : #endif
      91             : 
      92             : //-----------------------------------------------------------------------------
      93             : #include "mozilla/net/HttpChannelChild.h"
      94             : 
      95             : 
      96             : #define UA_PREF_PREFIX          "general.useragent."
      97             : #ifdef XP_WIN
      98             : #define UA_SPARE_PLATFORM
      99             : #endif
     100             : 
     101             : #define HTTP_PREF_PREFIX        "network.http."
     102             : #define INTL_ACCEPT_LANGUAGES   "intl.accept_languages"
     103             : #define BROWSER_PREF_PREFIX     "browser.cache."
     104             : #define DONOTTRACK_HEADER_ENABLED "privacy.donottrackheader.enabled"
     105             : #define H2MANDATORY_SUITE        "security.ssl3.ecdhe_rsa_aes_128_gcm_sha256"
     106             : #define TELEMETRY_ENABLED        "toolkit.telemetry.enabled"
     107             : #define ALLOW_EXPERIMENTS        "network.allow-experiments"
     108             : #define SAFE_HINT_HEADER_VALUE   "safeHint.enabled"
     109             : #define SECURITY_PREFIX          "security."
     110             : 
     111             : #define TCP_FAST_OPEN_ENABLE         "network.tcp.tcp_fastopen_enable"
     112             : #define TCP_FAST_OPEN_FAILURE_LIMIT  "network.tcp.tcp_fastopen_consecutive_failure_limit"
     113             : #define TCP_FAST_OPEN_STALLS_LIMIT   "network.tcp.tcp_fastopen_http_stalls_limit"
     114             : #define TCP_FAST_OPEN_STALLS_IDLE    "network.tcp.tcp_fastopen_http_check_for_stalls_only_if_idle_for"
     115             : #define TCP_FAST_OPEN_STALLS_TIMEOUT "network.tcp.tcp_fastopen_http_stalls_timeout"
     116             : 
     117             : #define UA_PREF(_pref) UA_PREF_PREFIX _pref
     118             : #define HTTP_PREF(_pref) HTTP_PREF_PREFIX _pref
     119             : #define BROWSER_PREF(_pref) BROWSER_PREF_PREFIX _pref
     120             : 
     121             : #define NS_HTTP_PROTOCOL_FLAGS (URI_STD | ALLOWS_PROXY | ALLOWS_PROXY_HTTP | URI_LOADABLE_BY_ANYONE)
     122             : 
     123             : //-----------------------------------------------------------------------------
     124             : 
     125             : using mozilla::Telemetry::LABELS_NETWORK_HTTP_REDIRECT_TO_SCHEME;
     126             : 
     127             : namespace mozilla {
     128             : namespace net {
     129             : 
     130             : LazyLogModule gHttpLog("nsHttp");
     131             : 
     132             : static nsresult
     133           0 : NewURI(const nsACString &aSpec,
     134             :        const char *aCharset,
     135             :        nsIURI *aBaseURI,
     136             :        int32_t aDefaultPort,
     137             :        nsIURI **aURI)
     138             : {
     139           0 :     nsCOMPtr<nsIURI> base(aBaseURI);
     140           0 :     return NS_MutateURI(new nsStandardURL::Mutator())
     141           0 :         .Apply(NS_MutatorMethod(&nsIStandardURLMutator::Init,
     142             :                                 nsIStandardURL::URLTYPE_AUTHORITY,
     143           0 :                                 aDefaultPort, nsCString(aSpec), aCharset,
     144           0 :                                 base, nullptr))
     145           0 :         .Finalize(aURI);
     146             : }
     147             : 
     148             : #ifdef ANDROID
     149             : static nsCString
     150             : GetDeviceModelId() {
     151             :     // Assumed to be running on the main thread
     152             :     // We need the device property in either case
     153             :     nsAutoCString deviceModelId;
     154             :     nsCOMPtr<nsIPropertyBag2> infoService = do_GetService("@mozilla.org/system-info;1");
     155             :     MOZ_ASSERT(infoService, "Could not find a system info service");
     156             :     nsAutoString androidDevice;
     157             :     nsresult rv = infoService->GetPropertyAsAString(NS_LITERAL_STRING("device"), androidDevice);
     158             :     if (NS_SUCCEEDED(rv)) {
     159             :         deviceModelId = NS_LossyConvertUTF16toASCII(androidDevice);
     160             :     }
     161             :     nsAutoCString deviceString;
     162             :     rv = Preferences::GetCString(UA_PREF("device_string"), deviceString);
     163             :     if (NS_SUCCEEDED(rv)) {
     164             :         deviceString.Trim(" ", true, true);
     165             :         deviceString.ReplaceSubstring(NS_LITERAL_CSTRING("%DEVICEID%"), deviceModelId);
     166             :         return deviceString;
     167             :     }
     168             :     return deviceModelId;
     169             : }
     170             : #endif
     171             : 
     172             : //-----------------------------------------------------------------------------
     173             : // nsHttpHandler <public>
     174             : //-----------------------------------------------------------------------------
     175             : 
     176           0 : StaticRefPtr<nsHttpHandler> gHttpHandler;
     177             : 
     178             : /* static */ already_AddRefed<nsHttpHandler>
     179           0 : nsHttpHandler::GetInstance()
     180             : {
     181           0 :     if (!gHttpHandler) {
     182           0 :         gHttpHandler = new nsHttpHandler();
     183           0 :         DebugOnly<nsresult> rv = gHttpHandler->Init();
     184           0 :         MOZ_ASSERT(NS_SUCCEEDED(rv));
     185           0 :         ClearOnShutdown(&gHttpHandler);
     186             :     }
     187           0 :     RefPtr<nsHttpHandler> httpHandler = gHttpHandler;
     188           0 :     return httpHandler.forget();
     189             : }
     190             : 
     191           0 : nsHttpHandler::nsHttpHandler()
     192             :     : mHttpVersion(HttpVersion::v1_1)
     193             :     , mProxyHttpVersion(HttpVersion::v1_1)
     194             :     , mCapabilities(NS_HTTP_ALLOW_KEEPALIVE)
     195             :     , mReferrerLevel(0xff) // by default we always send a referrer
     196             :     , mSpoofReferrerSource(false)
     197             :     , mHideOnionReferrerSource(false)
     198             :     , mReferrerTrimmingPolicy(0)
     199             :     , mReferrerXOriginTrimmingPolicy(0)
     200             :     , mReferrerXOriginPolicy(0)
     201             :     , mFastFallbackToIPv4(false)
     202           0 :     , mIdleTimeout(PR_SecondsToInterval(10))
     203           0 :     , mSpdyTimeout(PR_SecondsToInterval(180))
     204           0 :     , mResponseTimeout(PR_SecondsToInterval(300))
     205             :     , mResponseTimeoutEnabled(false)
     206             :     , mNetworkChangedTimeout(5000)
     207             :     , mMaxRequestAttempts(6)
     208             :     , mMaxRequestDelay(10)
     209             :     , mIdleSynTimeout(250)
     210             :     , mFallbackSynTimeout(5)
     211             :     , mH2MandatorySuiteEnabled(false)
     212             :     , mMaxUrgentExcessiveConns(3)
     213             :     , mMaxConnections(24)
     214             :     , mMaxPersistentConnectionsPerServer(2)
     215             :     , mMaxPersistentConnectionsPerProxy(4)
     216             :     , mThrottleEnabled(true)
     217             :     , mThrottleVersion(2)
     218             :     , mThrottleSuspendFor(3000)
     219             :     , mThrottleResumeFor(200)
     220             :     , mThrottleReadLimit(8000)
     221             :     , mThrottleReadInterval(500)
     222             :     , mThrottleHoldTime(600)
     223             :     , mThrottleMaxTime(3000)
     224             :     , mUrgentStartEnabled(true)
     225             :     , mTailBlockingEnabled(true)
     226             :     , mTailDelayQuantum(600)
     227             :     , mTailDelayQuantumAfterDCL(100)
     228             :     , mTailDelayMax(6000)
     229             :     , mTailTotalMax(0)
     230             :     , mRedirectionLimit(10)
     231             :     , mPhishyUserPassLength(1)
     232             :     , mQoSBits(0x00)
     233           0 :     , mEnforceAssocReq(false)
     234             :     , mLastUniqueID(NowInSeconds())
     235             :     , mSessionStartTime(0)
     236             :     , mLegacyAppName("Mozilla")
     237             :     , mLegacyAppVersion("5.0")
     238             :     , mProduct("Gecko")
     239             :     , mCompatFirefoxEnabled(false)
     240             :     , mUserAgentIsDirty(true)
     241             :     , mAcceptLanguagesIsDirty(true)
     242             :     , mPromptTempRedirect(true)
     243             :     , mEnablePersistentHttpsCaching(false)
     244             :     , mDoNotTrackEnabled(false)
     245             :     , mSafeHintEnabled(false)
     246             :     , mParentalControlEnabled(false)
     247             :     , mHandlerActive(false)
     248             :     , mTelemetryEnabled(false)
     249             :     , mAllowExperiments(true)
     250             :     , mDebugObservations(false)
     251             :     , mEnableSpdy(false)
     252             :     , mHttp2Enabled(true)
     253             :     , mUseH2Deps(true)
     254             :     , mEnforceHttp2TlsProfile(true)
     255             :     , mCoalesceSpdy(true)
     256             :     , mSpdyPersistentSettings(false)
     257             :     , mAllowPush(true)
     258             :     , mEnableAltSvc(false)
     259             :     , mEnableAltSvcOE(false)
     260             :     , mEnableOriginExtension(false)
     261             :     , mSpdySendingChunkSize(ASpdySession::kSendingChunkSize)
     262             :     , mSpdySendBufferSize(ASpdySession::kTCPSendBufferSize)
     263             :     , mSpdyPushAllowance(131072) // match default pref
     264             :     , mSpdyPullAllowance(ASpdySession::kInitialRwin)
     265           0 :     , mDefaultSpdyConcurrent(ASpdySession::kDefaultMaxConcurrent)
     266           0 :     , mSpdyPingThreshold(PR_SecondsToInterval(58))
     267             :     , mSpdyPingTimeout(PR_SecondsToInterval(8))
     268             :     , mConnectTimeout(90000)
     269             :     , mTLSHandshakeTimeout(30000)
     270             :     , mParallelSpeculativeConnectLimit(6)
     271             :     , mSpeculativeConnectEnabled(true)
     272             :     , mRequestTokenBucketEnabled(true)
     273             :     , mRequestTokenBucketMinParallelism(6)
     274             :     , mRequestTokenBucketHz(100)
     275             :     , mRequestTokenBucketBurst(32)
     276             :     , mCriticalRequestPrioritization(true)
     277             :     , mTCPKeepaliveShortLivedEnabled(false)
     278             :     , mTCPKeepaliveShortLivedTimeS(60)
     279             :     , mTCPKeepaliveShortLivedIdleTimeS(10)
     280             :     , mTCPKeepaliveLongLivedEnabled(false)
     281             :     , mTCPKeepaliveLongLivedIdleTimeS(600)
     282             :     , mEnforceH1Framing(FRAMECHECK_BARELY)
     283             :     , mDefaultHpackBuffer(4096)
     284             :     , mMaxHttpResponseHeaderSize(393216)
     285             :     , mFocusedWindowTransactionRatio(0.9f)
     286             :     , mUseFastOpen(true)
     287             :     , mFastOpenConsecutiveFailureLimit(5)
     288             :     , mFastOpenConsecutiveFailureCounter(0)
     289             :     , mFastOpenStallsLimit(3)
     290             :     , mFastOpenStallsCounter(0)
     291             :     , mFastOpenStallsIdleTime(10)
     292             :     , mFastOpenStallsTimeout(20)
     293             :     , mActiveTabPriority(true)
     294             :     , mProcessId(0)
     295           0 :     , mNextChannelId(1)
     296             :     , mLastActiveTabLoadOptimizationLock("nsHttpConnectionMgr::LastActiveTabLoadOptimization")
     297           0 : {
     298             :     LOG(("Creating nsHttpHandler [this=%p].\n", this));
     299           0 : 
     300             :     mUserAgentOverride.SetIsVoid(true);
     301           0 : 
     302             :     MOZ_ASSERT(!gHttpHandler, "HTTP handler already created!");
     303           0 : 
     304           0 :     nsCOMPtr<nsIXULRuntime> runtime = do_GetService("@mozilla.org/xre/runtime;1");
     305           0 :     if (runtime) {
     306             :         runtime->GetProcessID(&mProcessId);
     307           0 :     }
     308           0 :     SetFastOpenOSSupport();
     309             : }
     310             : 
     311           0 : void
     312             : nsHttpHandler::SetFastOpenOSSupport()
     313           0 : {
     314             :     mFastOpenSupported = false;
     315             : #if !defined(XP_WIN) && !defined(XP_LINUX) && !defined(ANDROID) && !defined(HAS_CONNECTX)
     316             :     return;
     317             : #elif defined(XP_WIN)
     318             :     mFastOpenSupported = IsWindows10BuildOrLater(16299);
     319             : 
     320             :     if (mFastOpenSupported) {
     321             :         // We have some problems with lavasoft software and tcp fast open.
     322             :         if (GetModuleHandleW(L"pmls64.dll") || GetModuleHandleW(L"rlls64.dll")) {
     323             :             mFastOpenSupported = false;
     324             :         }
     325             :     }
     326             : #else
     327           0 : 
     328             :     nsAutoCString version;
     329             :     nsresult rv;
     330             : #ifdef ANDROID
     331             :     nsCOMPtr<nsIPropertyBag2> infoService =
     332             :         do_GetService("@mozilla.org/system-info;1");
     333             :     MOZ_ASSERT(infoService, "Could not find a system info service");
     334             :     rv = infoService->GetPropertyAsACString(
     335             :         NS_LITERAL_STRING("sdk_version"), version);
     336             : #else
     337           0 :     char buf[SYS_INFO_BUFFER_LENGTH];
     338           0 :     if (PR_GetSystemInfo(PR_SI_RELEASE, buf, sizeof(buf)) == PR_SUCCESS) {
     339           0 :         version = buf;
     340             :         rv = NS_OK;
     341             :     } else {
     342             :         rv = NS_ERROR_FAILURE;
     343             :     }
     344             : #endif
     345           0 : 
     346             :     LOG(("nsHttpHandler::SetFastOpenOSSupport version %s", version.get()));
     347           0 : 
     348             :     if (NS_SUCCEEDED(rv)) {
     349             :         // set min version minus 1.
     350             : #if XP_MACOSX
     351             :         int min_version[] = {17, 5}; // High Sierra 10.13.4
     352             : #elif ANDROID
     353             :         int min_version[] = {4, 4};
     354           0 : #elif XP_LINUX
     355             :         int min_version[] = {3, 6};
     356           0 : #endif
     357             :         int inx = 0;
     358           0 :         nsCCharSeparatedTokenizer tokenizer(version, '.');
     359           0 :         while ((inx < 2) && tokenizer.hasMoreTokens()) {
     360           0 :             nsAutoCString token(tokenizer.nextToken());
     361           0 :             const char* nondigit = NS_strspnp("0123456789", token.get());
     362             :             if (nondigit && *nondigit) {
     363             :                 break;
     364             :             }
     365           0 :             nsresult rv;
     366           0 :             int32_t ver = token.ToInteger(&rv);
     367             :             if (NS_FAILED(rv)) {
     368             :                 break;
     369           0 :             }
     370           0 :             if (ver > min_version[inx]) {
     371             :                 mFastOpenSupported = true;
     372           0 :                 break;
     373           0 :             } else if (ver == min_version[inx] && inx == 1) {
     374           0 :                 mFastOpenSupported = true;
     375             :             } else if (ver < min_version[inx]) {
     376             :                 break;
     377           0 :             }
     378             :             inx++;
     379             :         }
     380             :     }
     381           0 : #endif
     382             :     LOG(("nsHttpHandler::SetFastOpenOSSupport %s supported.\n",
     383           0 :          mFastOpenSupported ? "" : "not"));
     384             : }
     385             : 
     386           0 : void
     387             : nsHttpHandler::EnsureUAOverridesInit()
     388           0 : {
     389           0 :     MOZ_ASSERT(XRE_IsParentProcess());
     390             :     MOZ_ASSERT(NS_IsMainThread());
     391             : 
     392             :     nsresult rv;
     393           0 :     nsCOMPtr<nsISupports> bootstrapper
     394           0 :         = do_GetService("@mozilla.org/network/ua-overrides-bootstrapper;1", &rv);
     395           0 :     MOZ_ASSERT(bootstrapper);
     396           0 :     MOZ_ASSERT(NS_SUCCEEDED(rv));
     397             : }
     398           0 : 
     399             : nsHttpHandler::~nsHttpHandler()
     400           0 : {
     401             :     LOG(("Deleting nsHttpHandler [this=%p]\n", this));
     402             : 
     403           0 :     // make sure the connection manager is shutdown
     404           0 :     if (mConnMgr) {
     405           0 :         nsresult rv = mConnMgr->Shutdown();
     406           0 :         if (NS_FAILED(rv)) {
     407             :             LOG(("nsHttpHandler [this=%p] "
     408             :                  "failed to shutdown connection manager (%08x)\n",
     409             :                  this, static_cast<uint32_t>(rv)));
     410           0 :         }
     411             :         mConnMgr = nullptr;
     412             :     }
     413             : 
     414             :     // Note: don't call NeckoChild::DestroyNeckoChild() here, as it's too late
     415             :     // and it'll segfault.  NeckoChild will get cleaned up by process exit.
     416           0 : 
     417           0 :     nsHttp::DestroyAtomTable();
     418             : }
     419             : 
     420           0 : nsresult
     421             : nsHttpHandler::Init()
     422             : {
     423             :     nsresult rv;
     424           0 : 
     425           0 :     LOG(("nsHttpHandler::Init\n"));
     426             :     MOZ_ASSERT(NS_IsMainThread());
     427           0 : 
     428           0 :     rv = nsHttp::CreateAtomTable();
     429             :     if (NS_FAILED(rv))
     430             :         return rv;
     431           0 : 
     432           0 :     nsCOMPtr<nsIIOService> service = do_GetService(NS_IOSERVICE_CONTRACTID, &rv);
     433           0 :     if (NS_FAILED(rv)) {
     434           0 :         NS_WARNING("unable to continue without io service");
     435             :         return rv;
     436             :     }
     437           0 :     mIOService = new nsMainThreadPtrHolder<nsIIOService>(
     438             :       "nsHttpHandler::mIOService", service);
     439           0 : 
     440           0 :     if (IsNeckoChild())
     441             :         NeckoChild::InitNeckoChild();
     442           0 : 
     443             :     InitUserAgentComponents();
     444             : 
     445           0 :     // This perference is only used in parent process.
     446           0 :     if (!IsNeckoChild()) {
     447           0 :         mActiveTabPriority =
     448             :             Preferences::GetBool(HTTP_PREF("active_tab_priority"), true);
     449             :     }
     450             : 
     451           0 :     // monitor some preference changes
     452           0 :     nsCOMPtr<nsIPrefBranch> prefBranch = do_GetService(NS_PREFSERVICE_CONTRACTID);
     453           0 :     if (prefBranch) {
     454           0 :         prefBranch->AddObserver(HTTP_PREF_PREFIX, this, true);
     455           0 :         prefBranch->AddObserver(UA_PREF_PREFIX, this, true);
     456           0 :         prefBranch->AddObserver(INTL_ACCEPT_LANGUAGES, this, true);
     457           0 :         prefBranch->AddObserver(BROWSER_PREF("disk_cache_ssl"), this, true);
     458           0 :         prefBranch->AddObserver(DONOTTRACK_HEADER_ENABLED, this, true);
     459           0 :         prefBranch->AddObserver(TELEMETRY_ENABLED, this, true);
     460           0 :         prefBranch->AddObserver(H2MANDATORY_SUITE, this, true);
     461           0 :         prefBranch->AddObserver(HTTP_PREF("tcp_keepalive.short_lived_connections"), this, true);
     462           0 :         prefBranch->AddObserver(HTTP_PREF("tcp_keepalive.long_lived_connections"), this, true);
     463           0 :         prefBranch->AddObserver(SAFE_HINT_HEADER_VALUE, this, true);
     464           0 :         prefBranch->AddObserver(SECURITY_PREFIX, this, true);
     465           0 :         prefBranch->AddObserver(TCP_FAST_OPEN_ENABLE, this, true);
     466           0 :         prefBranch->AddObserver(TCP_FAST_OPEN_FAILURE_LIMIT, this, true);
     467           0 :         prefBranch->AddObserver(TCP_FAST_OPEN_STALLS_LIMIT, this, true);
     468           0 :         prefBranch->AddObserver(TCP_FAST_OPEN_STALLS_IDLE, this, true);
     469           0 :         prefBranch->AddObserver(TCP_FAST_OPEN_STALLS_TIMEOUT, this, true);
     470             :         PrefsChanged(prefBranch, nullptr);
     471             :     }
     472           0 : 
     473             :     mMisc.AssignLiteral("rv:" MOZILLA_UAVERSION);
     474           0 : 
     475             :     mCompatFirefox.AssignLiteral("Firefox/" MOZILLA_UAVERSION);
     476             : 
     477           0 :     nsCOMPtr<nsIXULAppInfo> appInfo =
     478             :         do_GetService("@mozilla.org/xre/app-info;1");
     479           0 : 
     480           0 :     mAppName.AssignLiteral(MOZ_APP_UA_NAME);
     481             :     if (mAppName.Length() == 0 && appInfo) {
     482           0 :         // Try to get the UA name from appInfo, falling back to the name
     483           0 :         appInfo->GetUAName(mAppName);
     484           0 :         if (mAppName.Length() == 0) {
     485             :           appInfo->GetName(mAppName);
     486           0 :         }
     487           0 :         appInfo->GetVersion(mAppVersion);
     488             :         mAppName.StripChars(R"( ()<>@,;:\"/[]?={})");
     489           0 :     } else {
     490             :         mAppVersion.AssignLiteral(MOZ_APP_UA_VERSION);
     491             :     }
     492             : 
     493           0 :     // Generating the spoofed User Agent for fingerprinting resistance.
     494           0 :     rv = nsRFPService::GetSpoofedUserAgent(mSpoofedUserAgent);
     495             :     if (NS_FAILED(rv)) {
     496             :       // Empty mSpoofedUserAgent to make sure the unsuccessful spoofed UA string
     497           0 :       // will not be used anywhere.
     498             :       mSpoofedUserAgent.Truncate();
     499             :     }
     500           0 : 
     501           0 :     mSessionStartTime = NowInSeconds();
     502             :     mHandlerActive = true;
     503           0 : 
     504           0 :     rv = InitConnectionMgr();
     505             :     if (NS_FAILED(rv)) return rv;
     506             : 
     507           0 :     mRequestContextService =
     508             :         do_GetService("@mozilla.org/network/request-context-service;1");
     509             : 
     510             : #if defined(ANDROID) || defined(MOZ_MULET)
     511             :     mProductSub.AssignLiteral(MOZILLA_UAVERSION);
     512           0 : #else
     513             :     mProductSub.AssignLiteral(LEGACY_BUILD_ID);
     514             : #endif
     515             : 
     516             : #if DEBUG
     517           0 :     // dump user agent prefs
     518           0 :     LOG(("> legacy-app-name = %s\n", mLegacyAppName.get()));
     519           0 :     LOG(("> legacy-app-version = %s\n", mLegacyAppVersion.get()));
     520           0 :     LOG(("> platform = %s\n", mPlatform.get()));
     521           0 :     LOG(("> oscpu = %s\n", mOscpu.get()));
     522           0 :     LOG(("> misc = %s\n", mMisc.get()));
     523           0 :     LOG(("> product = %s\n", mProduct.get()));
     524           0 :     LOG(("> product-sub = %s\n", mProductSub.get()));
     525           0 :     LOG(("> app-name = %s\n", mAppName.get()));
     526           0 :     LOG(("> app-version = %s\n", mAppVersion.get()));
     527           0 :     LOG(("> compat-firefox = %s\n", mCompatFirefox.get()));
     528             :     LOG(("> user-agent = %s\n", UserAgent().get()));
     529             : #endif
     530             : 
     531             :     // Startup the http category
     532             :     // Bring alive the objects in the http-protocol-startup category
     533             :     NS_CreateServicesFromCategory(NS_HTTP_STARTUP_CATEGORY,
     534           0 :                                   static_cast<nsISupports*>(static_cast<void*>(this)),
     535             :                                   NS_HTTP_STARTUP_TOPIC);
     536           0 : 
     537           0 :     nsCOMPtr<nsIObserverService> obsService = services::GetObserverService();
     538             :     if (obsService) {
     539             :         // register the handler object as a weak callback as we don't need to worry
     540           0 :         // about shutdown ordering.
     541           0 :         obsService->AddObserver(this, "profile-change-net-teardown", true);
     542           0 :         obsService->AddObserver(this, "profile-change-net-restore", true);
     543           0 :         obsService->AddObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID, true);
     544           0 :         obsService->AddObserver(this, "net:clear-active-logins", true);
     545             :         obsService->AddObserver(this, "net:prune-dead-connections", true);
     546           0 :         // Sent by the TorButton add-on in the Tor Browser
     547           0 :         obsService->AddObserver(this, "net:prune-all-connections", true);
     548           0 :         obsService->AddObserver(this, "net:cancel-all-connections", true);
     549           0 :         obsService->AddObserver(this, "last-pb-context-exited", true);
     550           0 :         obsService->AddObserver(this, "browser:purge-session-history", true);
     551           0 :         obsService->AddObserver(this, NS_NETWORK_LINK_TOPIC, true);
     552           0 :         obsService->AddObserver(this, "application-background", true);
     553           0 :         obsService->AddObserver(this, "psm:user-certificate-added", true);
     554           1 :         obsService->AddObserver(this, "psm:user-certificate-deleted", true);
     555             :         obsService->AddObserver(this, "intl:app-locales-changed", true);
     556           0 : 
     557           1 :         if (!IsNeckoChild()) {
     558             :             obsService->AddObserver(this,
     559           1 :                                     "net:current-toplevel-outer-content-windowid",
     560             :                                     true);
     561             :         }
     562           0 : 
     563           0 :         if (mFastOpenSupported) {
     564           1 :             obsService->AddObserver(this, "captive-portal-login", true);
     565             :             obsService->AddObserver(this, "captive-portal-login-success", true);
     566             :         }
     567             : 
     568             :         // disabled as its a nop right now
     569             :         // obsService->AddObserver(this, "net:failed-to-process-uri-content", true);
     570             :     }
     571           0 : 
     572           0 :     MakeNewRequestTokenBucket();
     573           0 :     mWifiTickler = new Tickler();
     574           1 :     if (NS_FAILED(mWifiTickler->Init()))
     575             :         mWifiTickler = nullptr;
     576           0 : 
     577           0 :     nsCOMPtr<nsIParentalControlsService> pc = do_CreateInstance("@mozilla.org/parental-controls-service;1");
     578           1 :     if (pc) {
     579             :         pc->GetParentalControlsEnabled(&mParentalControlEnabled);
     580             :     }
     581             :     return NS_OK;
     582             : }
     583             : 
     584           2 : void
     585             : nsHttpHandler::MakeNewRequestTokenBucket()
     586           2 : {
     587             :     LOG(("nsHttpHandler::MakeNewRequestTokenBucket this=%p child=%d\n",
     588           0 :          this, IsNeckoChild()));
     589           1 :     if (!mConnMgr || IsNeckoChild()) {
     590             :         return;
     591             :     }
     592           3 :     RefPtr<EventTokenBucket> tokenBucket =
     593             :         new EventTokenBucket(RequestTokenBucketHz(), RequestTokenBucketBurst());
     594           0 :     // NOTE The thread or socket may be gone already.
     595           0 :     nsresult rv = mConnMgr->UpdateRequestTokenBucket(tokenBucket);
     596           0 :     if (NS_FAILED(rv)) {
     597             :         LOG(("    failed to update request token bucket\n"));
     598             :     }
     599             : }
     600             : 
     601           1 : nsresult
     602             : nsHttpHandler::InitConnectionMgr()
     603             : {
     604           1 :     // Init ConnectionManager only on parent!
     605             :     if (IsNeckoChild()) {
     606             :         return NS_OK;
     607             :     }
     608             : 
     609             :     nsresult rv;
     610           0 : 
     611           1 :     if (!mConnMgr) {
     612             :         mConnMgr = new nsHttpConnectionMgr();
     613             :     }
     614           0 : 
     615           0 :     rv = mConnMgr->Init(mMaxUrgentExcessiveConns,
     616           0 :                         mMaxConnections,
     617           0 :                         mMaxPersistentConnectionsPerServer,
     618           0 :                         mMaxPersistentConnectionsPerProxy,
     619           1 :                         mMaxRequestDelay,
     620             :                         mThrottleEnabled,
     621             :                         mThrottleVersion,
     622             :                         mThrottleSuspendFor,
     623             :                         mThrottleResumeFor,
     624             :                         mThrottleReadLimit,
     625             :                         mThrottleReadInterval,
     626           0 :                         mThrottleHoldTime,
     627           1 :                         mThrottleMaxTime);
     628             :     return rv;
     629             : }
     630             : 
     631           3 : nsresult
     632             : nsHttpHandler::AddStandardRequestHeaders(nsHttpRequestHead *request, bool isSecure)
     633             : {
     634             :     nsresult rv;
     635             : 
     636           0 :     // Add the "User-Agent" header
     637           0 :     rv = request->SetHeader(nsHttp::User_Agent, UserAgent(),
     638           3 :                             false, nsHttpHeaderArray::eVarietyRequestDefault);
     639             :     if (NS_FAILED(rv)) return rv;
     640             : 
     641             :     // MIME based content negotiation lives!
     642             :     // Add the "Accept" header.  Note, this is set as an override because the
     643             :     // service worker expects to see it.  The other "default" headers are
     644           0 :     // hidden from service worker interception.
     645           0 :     rv = request->SetHeader(nsHttp::Accept, mAccept,
     646           3 :                             false, nsHttpHeaderArray::eVarietyRequestOverride);
     647             :     if (NS_FAILED(rv)) return rv;
     648             : 
     649             :     // Add the "Accept-Language" header.  This header is also exposed to the
     650           0 :     // service worker.
     651           0 :     if (mAcceptLanguagesIsDirty) {
     652           1 :         rv = SetAcceptLanguages();
     653             :         MOZ_ASSERT(NS_SUCCEEDED(rv));
     654             :     }
     655             : 
     656           0 :     // Add the "Accept-Language" header
     657           3 :     if (!mAcceptLanguages.IsEmpty()) {
     658             :         rv = request->SetHeader(nsHttp::Accept_Language, mAcceptLanguages,
     659           0 :                                 false,
     660           3 :                                 nsHttpHeaderArray::eVarietyRequestOverride);
     661             :         if (NS_FAILED(rv)) return rv;
     662             :     }
     663             : 
     664           0 :     // Add the "Accept-Encoding" header
     665           1 :     if (isSecure) {
     666             :         rv = request->SetHeader(nsHttp::Accept_Encoding, mHttpsAcceptEncodings,
     667           1 :                                 false,
     668             :                                 nsHttpHeaderArray::eVarietyRequestDefault);
     669           2 :     } else {
     670             :         rv = request->SetHeader(nsHttp::Accept_Encoding, mHttpAcceptEncodings,
     671           2 :                                 false,
     672             :                                 nsHttpHeaderArray::eVarietyRequestDefault);
     673           3 :     }
     674             :     if (NS_FAILED(rv)) return rv;
     675             : 
     676           1 :     // add the "Send Hint" header
     677           0 :     if (mSafeHintEnabled || mParentalControlEnabled) {
     678             :       rv = request->SetHeader(nsHttp::Prefer, NS_LITERAL_CSTRING("safe"),
     679           0 :                               false,
     680           0 :                               nsHttpHeaderArray::eVarietyRequestDefault);
     681             :       if (NS_FAILED(rv)) return rv;
     682             :     }
     683             :     return NS_OK;
     684             : }
     685             : 
     686           3 : nsresult
     687             : nsHttpHandler::AddConnectionHeader(nsHttpRequestHead *request,
     688             :                                    uint32_t caps)
     689             : {
     690             :     // RFC2616 section 19.6.2 states that the "Connection: keep-alive"
     691             :     // and "Keep-alive" request headers should not be sent by HTTP/1.1
     692             :     // user-agents.  But this is not a problem in practice, and the
     693             :     // alternative proxy-connection is worse. see 570283
     694           0 : 
     695           3 :     NS_NAMED_LITERAL_CSTRING(close, "close");
     696             :     NS_NAMED_LITERAL_CSTRING(keepAlive, "keep-alive");
     697           0 : 
     698           0 :     const nsLiteralCString *connectionType = &close;
     699           3 :     if (caps & NS_HTTP_ALLOW_KEEPALIVE) {
     700             :         connectionType = &keepAlive;
     701             :     }
     702           3 : 
     703             :     return request->SetHeader(nsHttp::Connection, *connectionType);
     704             : }
     705             : 
     706           0 : bool
     707             : nsHttpHandler::IsAcceptableEncoding(const char *enc, bool isSecure)
     708           0 : {
     709             :     if (!enc)
     710             :         return false;
     711             : 
     712             :     // we used to accept x-foo anytime foo was acceptable, but that's just
     713             :     // continuing bad behavior.. so limit it to known x-* patterns
     714           0 :     bool rv;
     715           0 :     if (isSecure) {
     716             :         rv = nsHttp::FindToken(mHttpsAcceptEncodings.get(), enc, HTTP_LWS ",") != nullptr;
     717           0 :     } else {
     718             :         rv = nsHttp::FindToken(mHttpAcceptEncodings.get(), enc, HTTP_LWS ",") != nullptr;
     719             :     }
     720             :     // gzip and deflate are inherently acceptable in modern HTTP - always
     721           0 :     // process them if a stream converter can also be found.
     722           0 :     if (!rv &&
     723           0 :         (!PL_strcasecmp(enc, "gzip") || !PL_strcasecmp(enc, "deflate") ||
     724           0 :          !PL_strcasecmp(enc, "x-gzip") || !PL_strcasecmp(enc, "x-deflate"))) {
     725             :         rv = true;
     726           0 :     }
     727             :     LOG(("nsHttpHandler::IsAceptableEncoding %s https=%d %d\n",
     728             :          enc, isSecure, rv));
     729             :     return rv;
     730             : }
     731             : 
     732           0 : void
     733             : nsHttpHandler::IncrementFastOpenConsecutiveFailureCounter()
     734           0 : {
     735             :     LOG(("nsHttpHandler::IncrementFastOpenConsecutiveFailureCounter - "
     736             :          "failed=%d failure_limit=%d", mFastOpenConsecutiveFailureCounter,
     737           0 :          mFastOpenConsecutiveFailureLimit));
     738           0 :     if (mFastOpenConsecutiveFailureCounter < mFastOpenConsecutiveFailureLimit) {
     739           0 :         mFastOpenConsecutiveFailureCounter++;
     740           0 :         if (mFastOpenConsecutiveFailureCounter == mFastOpenConsecutiveFailureLimit) {
     741             :             LOG(("nsHttpHandler::IncrementFastOpenConsecutiveFailureCounter - "
     742             :                  "Fast open failed too many times"));
     743             :         }
     744           0 :     }
     745             : }
     746             : 
     747           0 : void
     748             : nsHttpHandler::IncrementFastOpenStallsCounter()
     749           0 : {
     750             :   LOG(("nsHttpHandler::IncrementFastOpenStallsCounter - failed=%d "
     751           0 :         "failure_limit=%d", mFastOpenStallsCounter, mFastOpenStallsLimit));
     752           0 :   if (mFastOpenStallsCounter < mFastOpenStallsLimit) {
     753           0 :     mFastOpenStallsCounter++;
     754           0 :     if (mFastOpenStallsCounter == mFastOpenStallsLimit) {
     755             :       LOG(("nsHttpHandler::IncrementFastOpenStallsCounter - "
     756             :            "There are too many stalls involving TFO and TLS."));
     757             :     }
     758           0 :   }
     759             : }
     760             : 
     761           0 : nsresult
     762             : nsHttpHandler::GetStreamConverterService(nsIStreamConverterService **result)
     763           0 : {
     764             :     if (!mStreamConvSvc) {
     765             :         nsresult rv;
     766           0 :         nsCOMPtr<nsIStreamConverterService> service =
     767           0 :             do_GetService(NS_STREAMCONVERTERSERVICE_CONTRACTID, &rv);
     768           0 :         if (NS_FAILED(rv))
     769             :             return rv;
     770           0 :         mStreamConvSvc = new nsMainThreadPtrHolder<nsIStreamConverterService>(
     771             :           "nsHttpHandler::mStreamConvSvc", service);
     772           0 :     }
     773           0 :     *result = mStreamConvSvc;
     774           0 :     NS_ADDREF(*result);
     775             :     return NS_OK;
     776             : }
     777             : 
     778           2 : nsISiteSecurityService*
     779             : nsHttpHandler::GetSSService()
     780           0 : {
     781           2 :     if (!mSSService) {
     782             :         nsCOMPtr<nsISiteSecurityService> service = do_GetService(NS_SSSERVICE_CONTRACTID);
     783           3 :         mSSService = new nsMainThreadPtrHolder<nsISiteSecurityService>(
     784             :           "nsHttpHandler::mSSService", service);
     785           4 :     }
     786             :     return mSSService;
     787             : }
     788             : 
     789           1 : nsICookieService *
     790             : nsHttpHandler::GetCookieService()
     791           0 : {
     792           2 :     if (!mCookieService) {
     793             :         nsCOMPtr<nsICookieService> service = do_GetService(NS_COOKIESERVICE_CONTRACTID);
     794           3 :         mCookieService = new nsMainThreadPtrHolder<nsICookieService>(
     795             :           "nsHttpHandler::mCookieService", service);
     796           2 :     }
     797             :     return mCookieService;
     798             : }
     799             : 
     800           0 : nsresult
     801             : nsHttpHandler::GetIOService(nsIIOService** result)
     802           0 : {
     803             :     NS_ENSURE_ARG_POINTER(result);
     804           0 : 
     805           0 :     NS_ADDREF(*result = mIOService);
     806             :     return NS_OK;
     807             : }
     808             : 
     809           0 : uint32_t
     810             : nsHttpHandler::Get32BitsOfPseudoRandom()
     811             : {
     812           0 :     // only confirm rand seeding on socket thread
     813             :     MOZ_ASSERT(OnSocketThread(), "not on socket thread");
     814             : 
     815             :     // rand() provides different amounts of PRNG on different platforms.
     816             :     // 15 or 31 bits are common amounts.
     817             : 
     818             :     static_assert(RAND_MAX >= 0xfff, "RAND_MAX should be >= 12 bits");
     819             : 
     820             : #if RAND_MAX < 0xffffU
     821             :     return ((uint16_t) rand() << 20) |
     822             :             (((uint16_t) rand() & 0xfff) << 8) |
     823             :             ((uint16_t) rand() & 0xff);
     824           0 : #elif RAND_MAX < 0xffffffffU
     825             :     return ((uint16_t) rand() << 16) | ((uint16_t) rand() & 0xffff);
     826             : #else
     827             :     return (uint32_t) rand();
     828             : #endif
     829             : }
     830             : 
     831          11 : void
     832             : nsHttpHandler::NotifyObservers(nsIHttpChannel *chan, const char *event)
     833           0 : {
     834           0 :     LOG(("nsHttpHandler::NotifyObservers [chan=%p event=\"%s\"]\n", chan, event));
     835           0 :     nsCOMPtr<nsIObserverService> obsService = services::GetObserverService();
     836           0 :     if (obsService)
     837          11 :         obsService->NotifyObservers(chan, event, nullptr);
     838             : }
     839             : 
     840           0 : nsresult
     841             : nsHttpHandler::AsyncOnChannelRedirect(nsIChannel* oldChan,
     842             :                                       nsIChannel* newChan,
     843             :                                       uint32_t flags,
     844             :                                       nsIEventTarget* mainThreadEventTarget)
     845           0 : {
     846             :   MOZ_ASSERT(NS_IsMainThread() && (oldChan && newChan));
     847           0 : 
     848           0 :   nsCOMPtr<nsIURI> newURI;
     849           0 :   newChan->GetURI(getter_AddRefs(newURI));
     850             :   MOZ_ASSERT(newURI);
     851           0 : 
     852           0 :   nsAutoCString scheme;
     853           0 :   newURI->GetScheme(scheme);
     854             :   MOZ_ASSERT(!scheme.IsEmpty());
     855           0 : 
     856             :   Telemetry::AccumulateCategoricalKeyed(
     857           0 :     scheme,
     858             :     oldChan->IsDocument()
     859           0 :       ? LABELS_NETWORK_HTTP_REDIRECT_TO_SCHEME::topLevel
     860             :       : LABELS_NETWORK_HTTP_REDIRECT_TO_SCHEME::subresource);
     861             : 
     862             :   // TODO E10S This helper has to be initialized on the other process
     863           0 :   RefPtr<nsAsyncRedirectVerifyHelper> redirectCallbackHelper =
     864             :     new nsAsyncRedirectVerifyHelper();
     865           0 : 
     866           0 :   return redirectCallbackHelper->Init(
     867             :     oldChan, newChan, flags, mainThreadEventTarget);
     868             : }
     869             : 
     870           3 : /* static */ nsresult
     871             : nsHttpHandler::GenerateHostPort(const nsCString& host, int32_t port,
     872             :                                 nsACString& hostLine)
     873           3 : {
     874             :     return NS_GenerateHostPort(host, port, hostLine);
     875             : }
     876             : 
     877             : //-----------------------------------------------------------------------------
     878             : // nsHttpHandler <private>
     879             : //-----------------------------------------------------------------------------
     880             : 
     881           3 : const nsCString&
     882             : nsHttpHandler::UserAgent()
     883           0 : {
     884           0 :     if (nsContentUtils::ShouldResistFingerprinting() &&
     885           0 :         !mSpoofedUserAgent.IsEmpty()) {
     886           0 :         LOG(("using spoofed userAgent : %s\n", mSpoofedUserAgent.get()));
     887             :         return mSpoofedUserAgent;
     888             :     }
     889           0 : 
     890           0 :     if (!mUserAgentOverride.IsVoid()) {
     891           0 :         LOG(("using general.useragent.override : %s\n", mUserAgentOverride.get()));
     892             :         return mUserAgentOverride;
     893             :     }
     894           0 : 
     895           0 :     if (mUserAgentIsDirty) {
     896           1 :         BuildUserAgent();
     897             :         mUserAgentIsDirty = false;
     898             :     }
     899           3 : 
     900             :     return mUserAgent;
     901             : }
     902             : 
     903           1 : void
     904             : nsHttpHandler::BuildUserAgent()
     905           1 : {
     906             :     LOG(("nsHttpHandler::BuildUserAgent\n"));
     907           3 : 
     908             :     MOZ_ASSERT(!mLegacyAppName.IsEmpty() &&
     909             :                !mLegacyAppVersion.IsEmpty(),
     910             :                "HTTP cannot send practical requests without this much");
     911             : 
     912             :     // preallocate to worst-case size, which should always be better
     913           0 :     // than if we didn't preallocate at all.
     914           2 :     mUserAgent.SetCapacity(mLegacyAppName.Length() +
     915             :                            mLegacyAppVersion.Length() +
     916           2 : #ifndef UA_SPARE_PLATFORM
     917             :                            mPlatform.Length() +
     918           0 : #endif
     919           0 :                            mOscpu.Length() +
     920           0 :                            mMisc.Length() +
     921           0 :                            mProduct.Length() +
     922           0 :                            mProductSub.Length() +
     923           0 :                            mAppName.Length() +
     924           0 :                            mAppVersion.Length() +
     925           0 :                            mCompatFirefox.Length() +
     926           0 :                            mCompatDevice.Length() +
     927           1 :                            mDeviceModelId.Length() +
     928             :                            13);
     929             : 
     930           0 :     // Application portion
     931           0 :     mUserAgent.Assign(mLegacyAppName);
     932           0 :     mUserAgent += '/';
     933           2 :     mUserAgent += mLegacyAppVersion;
     934             :     mUserAgent += ' ';
     935             : 
     936           2 :     // Application comment
     937             :     mUserAgent += '(';
     938           0 : #ifndef UA_SPARE_PLATFORM
     939           0 :     if (!mPlatform.IsEmpty()) {
     940           1 :       mUserAgent += mPlatform;
     941             :       mUserAgent.AppendLiteral("; ");
     942             :     }
     943           1 : #endif
     944           0 :     if (!mCompatDevice.IsEmpty()) {
     945           0 :         mUserAgent += mCompatDevice;
     946             :         mUserAgent.AppendLiteral("; ");
     947           0 :     }
     948           0 :     else if (!mOscpu.IsEmpty()) {
     949           1 :       mUserAgent += mOscpu;
     950             :       mUserAgent.AppendLiteral("; ");
     951           1 :     }
     952           0 :     if (!mDeviceModelId.IsEmpty()) {
     953           0 :         mUserAgent += mDeviceModelId;
     954             :         mUserAgent.AppendLiteral("; ");
     955           0 :     }
     956           2 :     mUserAgent += mMisc;
     957             :     mUserAgent += ')';
     958             : 
     959           0 :     // Product portion
     960           0 :     mUserAgent += ' ';
     961           0 :     mUserAgent += mProduct;
     962           2 :     mUserAgent += '/';
     963             :     mUserAgent += mProductSub;
     964           0 : 
     965           1 :     bool isFirefox = mAppName.EqualsLiteral("Firefox");
     966             :     if (isFirefox || mCompatFirefoxEnabled) {
     967           0 :         // "Firefox/x.y" (compatibility) app token
     968           1 :         mUserAgent += ' ';
     969             :         mUserAgent += mCompatFirefox;
     970           1 :     }
     971             :     if (!isFirefox) {
     972           0 :         // App portion
     973           0 :         mUserAgent += ' ';
     974           0 :         mUserAgent += mAppName;
     975           0 :         mUserAgent += '/';
     976             :         mUserAgent += mAppVersion;
     977           1 :     }
     978             : }
     979             : 
     980             : #ifdef XP_WIN
     981             : #define WNT_BASE "Windows NT %ld.%ld"
     982             : #define W64_PREFIX "; Win64"
     983             : #endif
     984             : 
     985           1 : void
     986             : nsHttpHandler::InitUserAgentComponents()
     987             : {
     988             : #ifndef MOZ_UA_OS_AGNOSTIC
     989           1 :     // Gather platform.
     990             :     mPlatform.AssignLiteral(
     991             : #if defined(ANDROID)
     992             :     "Android"
     993             : #elif defined(XP_WIN)
     994             :     "Windows"
     995             : #elif defined(XP_MACOSX)
     996             :     "Macintosh"
     997             : #elif defined(XP_UNIX)
     998             :     // We historically have always had X11 here,
     999             :     // and there seems little a webpage can sensibly do
    1000             :     // based on it being something else, so use X11 for
    1001             :     // backwards compatibility in all cases.
    1002             :     "X11"
    1003           1 : #endif
    1004             :     );
    1005             : #endif
    1006             : 
    1007             : 
    1008             : #ifdef ANDROID
    1009             :     nsCOMPtr<nsIPropertyBag2> infoService = do_GetService("@mozilla.org/system-info;1");
    1010             :     MOZ_ASSERT(infoService, "Could not find a system info service");
    1011             :     nsresult rv;
    1012             :     // Add the Android version number to the Fennec platform identifier.
    1013             : #if defined MOZ_WIDGET_ANDROID
    1014             : #ifndef MOZ_UA_OS_AGNOSTIC // Don't add anything to mPlatform since it's empty.
    1015             :     nsAutoString androidVersion;
    1016             :     rv = infoService->GetPropertyAsAString(
    1017             :         NS_LITERAL_STRING("release_version"), androidVersion);
    1018             :     if (NS_SUCCEEDED(rv)) {
    1019             :       mPlatform += " ";
    1020             :       // If the 2nd character is a ".", we know the major version is a single
    1021             :       // digit. If we're running on a version below 4 we pretend to be on
    1022             :       // Android KitKat (4.4) to work around scripts sniffing for low versions.
    1023             :       if (androidVersion[1] == 46 && androidVersion[0] < 52) {
    1024             :         mPlatform += "4.4";
    1025             :       } else {
    1026             :         mPlatform += NS_LossyConvertUTF16toASCII(androidVersion);
    1027             :       }
    1028             :     }
    1029             : #endif
    1030             : #endif
    1031             :     // Add the `Mobile` or `Tablet` or `TV` token when running on device.
    1032             :     bool isTablet;
    1033             :     rv = infoService->GetPropertyAsBool(NS_LITERAL_STRING("tablet"), &isTablet);
    1034             :     if (NS_SUCCEEDED(rv) && isTablet) {
    1035             :         mCompatDevice.AssignLiteral("Tablet");
    1036             :     } else {
    1037             :         bool isTV;
    1038             :         rv = infoService->GetPropertyAsBool(NS_LITERAL_STRING("tv"), &isTV);
    1039             :         if (NS_SUCCEEDED(rv) && isTV) {
    1040             :             mCompatDevice.AssignLiteral("TV");
    1041             :         } else {
    1042             :             mCompatDevice.AssignLiteral("Mobile");
    1043             :         }
    1044             :     }
    1045             : 
    1046             :     if (Preferences::GetBool(UA_PREF("use_device"), false)) {
    1047             :         mDeviceModelId = mozilla::net::GetDeviceModelId();
    1048             :     }
    1049             : #endif // ANDROID
    1050             : 
    1051             : #ifdef MOZ_MULET
    1052             :     {
    1053             :         // Add the `Mobile` or `Tablet` or `TV` token when running in the b2g
    1054             :         // desktop simulator via preference.
    1055             :         nsAutoCString deviceType;
    1056             :         nsresult rv = Preferences::GetCString("devtools.useragent.device_type", deviceType);
    1057             :         if (NS_SUCCEEDED(rv)) {
    1058             :             mCompatDevice.Assign(deviceType);
    1059             :         } else {
    1060             :             mCompatDevice.AssignLiteral("Mobile");
    1061             :         }
    1062             :     }
    1063             : #endif // MOZ_MULET
    1064             : 
    1065             : #ifndef MOZ_UA_OS_AGNOSTIC
    1066             :     // Gather OS/CPU.
    1067             : #if defined(XP_WIN)
    1068             :     OSVERSIONINFO info = { sizeof(OSVERSIONINFO) };
    1069             : #pragma warning(push)
    1070             : #pragma warning(disable:4996)
    1071             :     if (GetVersionEx(&info)) {
    1072             : #pragma warning(pop)
    1073             :         const char *format;
    1074             : #if defined _M_IA64
    1075             :         format = WNT_BASE W64_PREFIX "; IA64";
    1076             : #elif defined _M_X64 || defined _M_AMD64
    1077             :         format = WNT_BASE W64_PREFIX "; x64";
    1078             : #else
    1079             :         BOOL isWow64 = FALSE;
    1080             :         if (!IsWow64Process(GetCurrentProcess(), &isWow64)) {
    1081             :             isWow64 = FALSE;
    1082             :         }
    1083             :         format = isWow64
    1084             :           ? WNT_BASE "; WOW64"
    1085             :           : WNT_BASE;
    1086             : #endif
    1087             :         SmprintfPointer buf = mozilla::Smprintf(format,
    1088             :                                                 info.dwMajorVersion,
    1089             :                                                 info.dwMinorVersion);
    1090             :         if (buf) {
    1091             :             mOscpu = buf.get();
    1092             :         }
    1093             :     }
    1094             : #elif defined (XP_MACOSX)
    1095             : #if defined(__ppc__)
    1096             :     mOscpu.AssignLiteral("PPC Mac OS X");
    1097             : #elif defined(__i386__) || defined(__x86_64__)
    1098             :     mOscpu.AssignLiteral("Intel Mac OS X");
    1099             : #endif
    1100             :     SInt32 majorVersion = nsCocoaFeatures::OSXVersionMajor();
    1101             :     SInt32 minorVersion = nsCocoaFeatures::OSXVersionMinor();
    1102             :     mOscpu += nsPrintfCString(" %d.%d", static_cast<int>(majorVersion),
    1103             :                               static_cast<int>(minorVersion));
    1104             : #elif defined (XP_UNIX)
    1105             :     struct utsname name;
    1106           0 : 
    1107           0 :     int ret = uname(&name);
    1108           0 :     if (ret >= 0) {
    1109           1 :         nsAutoCString buf;
    1110             :         buf =  (char*)name.sysname;
    1111             : 
    1112             :         if (strcmp(name.machine, "x86_64") == 0 &&
    1113             :             sizeof(void *) == sizeof(int32_t)) {
    1114             :             // We're running 32-bit code on x86_64. Make this browser
    1115             :             // look like it's running on i686 hardware, but append "
    1116             :             // (x86_64)" to the end of the oscpu identifier to be able
    1117             :             // to differentiate this from someone running 64-bit code
    1118             :             // on x86_64..
    1119             : 
    1120             :             buf += " i686 on x86_64";
    1121           1 :         } else {
    1122             :             buf += ' ';
    1123             : 
    1124             : #ifdef AIX
    1125             :             // AIX uname returns machine specific info in the uname.machine
    1126             :             // field and does not return the cpu type like other platforms.
    1127             :             // We use the AIX version and release numbers instead.
    1128             :             buf += (char*)name.version;
    1129             :             buf += '.';
    1130             :             buf += (char*)name.release;
    1131           1 : #else
    1132             :             buf += (char*)name.machine;
    1133             : #endif
    1134             :         }
    1135           1 : 
    1136             :         mOscpu.Assign(buf);
    1137             :     }
    1138             : #endif
    1139             : #endif
    1140           0 : 
    1141           1 :     mUserAgentIsDirty = true;
    1142             : }
    1143             : 
    1144           4 : uint32_t
    1145             : nsHttpHandler::MaxSocketCount()
    1146             : {
    1147           4 :     PR_CallOnce(&nsSocketTransportService::gMaxCountInitOnce,
    1148             :                 nsSocketTransportService::DiscoverMaxCount);
    1149             :     // Don't use the full max count because sockets can be held in
    1150             :     // the persistent connection pool for a long time and that could
    1151             :     // starve other users.
    1152           0 : 
    1153           4 :     uint32_t maxCount = nsSocketTransportService::gMaxCount;
    1154             :     if (maxCount <= 8)
    1155             :         maxCount = 1;
    1156           4 :     else
    1157             :         maxCount -= 8;
    1158           4 : 
    1159             :     return maxCount;
    1160             : }
    1161             : 
    1162           1 : void
    1163             : nsHttpHandler::PrefsChanged(nsIPrefBranch *prefs, const char *pref)
    1164           1 : {
    1165             :     nsresult rv = NS_OK;
    1166             :     int32_t val;
    1167           1 : 
    1168             :     LOG(("nsHttpHandler::PrefsChanged [pref=%s]\n", pref));
    1169             : 
    1170             : #define PREF_CHANGED(p) ((pref == nullptr) || !PL_strcmp(pref, p))
    1171             : #define MULTI_PREF_CHANGED(p) \
    1172             :   ((pref == nullptr) || !PL_strncmp(pref, p, sizeof(p) - 1))
    1173             : 
    1174           0 :     // If a security pref changed, lets clear our connection pool reuse
    1175           0 :     if (MULTI_PREF_CHANGED(SECURITY_PREFIX)) {
    1176           0 :         LOG(("nsHttpHandler::PrefsChanged Security Pref Changed %s\n", pref));
    1177           0 :         if (mConnMgr) {
    1178           0 :             rv = mConnMgr->DoShiftReloadConnectionCleanup(nullptr);
    1179           0 :             if (NS_FAILED(rv)) {
    1180             :                 LOG(("nsHttpHandler::PrefsChanged "
    1181             :                      "DoShiftReloadConnectionCleanup failed (%08x)\n", static_cast<uint32_t>(rv)));
    1182           0 :             }
    1183           0 :             rv = mConnMgr->PruneDeadConnections();
    1184           0 :             if (NS_FAILED(rv)) {
    1185             :                 LOG(("nsHttpHandler::PrefsChanged "
    1186             :                      "PruneDeadConnections failed (%08x)\n", static_cast<uint32_t>(rv)));
    1187             :             }
    1188             :         }
    1189             :     }
    1190             : 
    1191             :     //
    1192             :     // UA components
    1193             :     //
    1194           1 : 
    1195             :     bool cVar = false;
    1196           0 : 
    1197           0 :     if (PREF_CHANGED(UA_PREF("compatMode.firefox"))) {
    1198           0 :         rv = prefs->GetBoolPref(UA_PREF("compatMode.firefox"), &cVar);
    1199           1 :         mCompatFirefoxEnabled = (NS_SUCCEEDED(rv) && cVar);
    1200             :         mUserAgentIsDirty = true;
    1201             :     }
    1202             : 
    1203           0 :     // general.useragent.override
    1204           0 :     if (PREF_CHANGED(UA_PREF("override"))) {
    1205           1 :         prefs->GetCharPref(UA_PREF("override"), mUserAgentOverride);
    1206             :         mUserAgentIsDirty = true;
    1207             :     }
    1208             : 
    1209             : #ifdef ANDROID
    1210             :     // general.useragent.use_device
    1211             :     if (PREF_CHANGED(UA_PREF("use_device"))) {
    1212             :         if (Preferences::GetBool(UA_PREF("use_device"), false)) {
    1213             :             mDeviceModelId = mozilla::net::GetDeviceModelId();
    1214             :         } else {
    1215             :             mDeviceModelId = EmptyCString();
    1216             :         }
    1217             :         mUserAgentIsDirty = true;
    1218             :     }
    1219             : #endif
    1220             : 
    1221             :     //
    1222             :     // HTTP options
    1223             :     //
    1224           0 : 
    1225           0 :     if (PREF_CHANGED(HTTP_PREF("keep-alive.timeout"))) {
    1226           0 :         rv = prefs->GetIntPref(HTTP_PREF("keep-alive.timeout"), &val);
    1227           1 :         if (NS_SUCCEEDED(rv))
    1228             :             mIdleTimeout = PR_SecondsToInterval(clamped(val, 1, 0xffff));
    1229             :     }
    1230           0 : 
    1231           0 :     if (PREF_CHANGED(HTTP_PREF("request.max-attempts"))) {
    1232           0 :         rv = prefs->GetIntPref(HTTP_PREF("request.max-attempts"), &val);
    1233           1 :         if (NS_SUCCEEDED(rv))
    1234             :             mMaxRequestAttempts = (uint16_t) clamped(val, 1, 0xffff);
    1235             :     }
    1236           0 : 
    1237           0 :     if (PREF_CHANGED(HTTP_PREF("request.max-start-delay"))) {
    1238           0 :         rv = prefs->GetIntPref(HTTP_PREF("request.max-start-delay"), &val);
    1239           0 :         if (NS_SUCCEEDED(rv)) {
    1240           1 :             mMaxRequestDelay = (uint16_t) clamped(val, 0, 0xffff);
    1241           0 :             if (mConnMgr) {
    1242           0 :                 rv = mConnMgr->UpdateParam(nsHttpConnectionMgr::MAX_REQUEST_DELAY,
    1243           0 :                                            mMaxRequestDelay);
    1244           0 :                 if (NS_FAILED(rv)) {
    1245             :                     LOG(("nsHttpHandler::PrefsChanged (request.max-start-delay)"
    1246             :                          "UpdateParam failed (%08x)\n", static_cast<uint32_t>(rv)));
    1247             :                 }
    1248             :             }
    1249             :         }
    1250             :     }
    1251           0 : 
    1252           0 :     if (PREF_CHANGED(HTTP_PREF("response.timeout"))) {
    1253           0 :         rv = prefs->GetIntPref(HTTP_PREF("response.timeout"), &val);
    1254           1 :         if (NS_SUCCEEDED(rv))
    1255             :             mResponseTimeout = PR_SecondsToInterval(clamped(val, 0, 0xffff));
    1256             :     }
    1257           0 : 
    1258           0 :     if (PREF_CHANGED(HTTP_PREF("network-changed.timeout"))) {
    1259           0 :         rv = prefs->GetIntPref(HTTP_PREF("network-changed.timeout"), &val);
    1260           1 :         if (NS_SUCCEEDED(rv))
    1261             :             mNetworkChangedTimeout = clamped(val, 1, 600) * 1000;
    1262             :     }
    1263           0 : 
    1264           0 :     if (PREF_CHANGED(HTTP_PREF("max-connections"))) {
    1265           1 :         rv = prefs->GetIntPref(HTTP_PREF("max-connections"), &val);
    1266             :         if (NS_SUCCEEDED(rv)) {
    1267           0 : 
    1268           4 :             mMaxConnections = (uint16_t) clamped((uint32_t)val,
    1269             :                                                  (uint32_t)1, MaxSocketCount());
    1270           1 : 
    1271           0 :             if (mConnMgr) {
    1272           0 :                 rv = mConnMgr->UpdateParam(nsHttpConnectionMgr::MAX_CONNECTIONS,
    1273           0 :                                            mMaxConnections);
    1274           0 :                 if (NS_FAILED(rv)) {
    1275             :                     LOG(("nsHttpHandler::PrefsChanged (max-connections)"
    1276             :                          "UpdateParam failed (%08x)\n", static_cast<uint32_t>(rv)));
    1277             :                 }
    1278             :             }
    1279             :         }
    1280             :     }
    1281           0 : 
    1282           0 :     if (PREF_CHANGED(HTTP_PREF("max-urgent-start-excessive-connections-per-host"))) {
    1283           0 :         rv = prefs->GetIntPref(HTTP_PREF("max-urgent-start-excessive-connections-per-host"), &val);
    1284           0 :         if (NS_SUCCEEDED(rv)) {
    1285           1 :             mMaxUrgentExcessiveConns = (uint8_t) clamped(val, 1, 0xff);
    1286           0 :             if (mConnMgr) {
    1287           0 :                 rv = mConnMgr->UpdateParam(nsHttpConnectionMgr::MAX_URGENT_START_Q,
    1288           0 :                                            mMaxUrgentExcessiveConns);
    1289           0 :                 if (NS_FAILED(rv)) {
    1290             :                     LOG(("nsHttpHandler::PrefsChanged (max-urgent-start-excessive-connections-per-host)"
    1291             :                          "UpdateParam failed (%08x)\n", static_cast<uint32_t>(rv)));
    1292             :                 }
    1293             :              }
    1294             :           }
    1295             :     }
    1296           0 : 
    1297           0 :     if (PREF_CHANGED(HTTP_PREF("max-persistent-connections-per-server"))) {
    1298           0 :         rv = prefs->GetIntPref(HTTP_PREF("max-persistent-connections-per-server"), &val);
    1299           0 :         if (NS_SUCCEEDED(rv)) {
    1300           1 :             mMaxPersistentConnectionsPerServer = (uint8_t) clamped(val, 1, 0xff);
    1301           0 :             if (mConnMgr) {
    1302           0 :                 rv = mConnMgr->UpdateParam(nsHttpConnectionMgr::MAX_PERSISTENT_CONNECTIONS_PER_HOST,
    1303           0 :                                            mMaxPersistentConnectionsPerServer);
    1304           0 :                 if (NS_FAILED(rv)) {
    1305             :                     LOG(("nsHttpHandler::PrefsChanged (max-persistent-connections-per-server)"
    1306             :                          "UpdateParam failed (%08x)\n", static_cast<uint32_t>(rv)));
    1307             :                 }
    1308             :             }
    1309             :         }
    1310             :     }
    1311           0 : 
    1312           0 :     if (PREF_CHANGED(HTTP_PREF("max-persistent-connections-per-proxy"))) {
    1313           0 :         rv = prefs->GetIntPref(HTTP_PREF("max-persistent-connections-per-proxy"), &val);
    1314           0 :         if (NS_SUCCEEDED(rv)) {
    1315           1 :             mMaxPersistentConnectionsPerProxy = (uint8_t) clamped(val, 1, 0xff);
    1316           0 :             if (mConnMgr) {
    1317           0 :                 rv = mConnMgr->UpdateParam(nsHttpConnectionMgr::MAX_PERSISTENT_CONNECTIONS_PER_PROXY,
    1318           0 :                                            mMaxPersistentConnectionsPerProxy);
    1319           0 :                 if (NS_FAILED(rv)) {
    1320             :                     LOG(("nsHttpHandler::PrefsChanged (max-persistent-connections-per-proxy)"
    1321             :                          "UpdateParam failed (%08x)\n", static_cast<uint32_t>(rv)));
    1322             :                 }
    1323             :             }
    1324             :         }
    1325             :     }
    1326           0 : 
    1327           0 :     if (PREF_CHANGED(HTTP_PREF("sendRefererHeader"))) {
    1328           0 :         rv = prefs->GetIntPref(HTTP_PREF("sendRefererHeader"), &val);
    1329           1 :         if (NS_SUCCEEDED(rv))
    1330             :             mReferrerLevel = (uint8_t) clamped(val, 0, 0xff);
    1331             :     }
    1332           0 : 
    1333           0 :     if (PREF_CHANGED(HTTP_PREF("referer.spoofSource"))) {
    1334           0 :         rv = prefs->GetBoolPref(HTTP_PREF("referer.spoofSource"), &cVar);
    1335           1 :         if (NS_SUCCEEDED(rv))
    1336             :             mSpoofReferrerSource = cVar;
    1337             :     }
    1338           0 : 
    1339           0 :     if (PREF_CHANGED(HTTP_PREF("referer.hideOnionSource"))) {
    1340           0 :         rv = prefs->GetBoolPref(HTTP_PREF("referer.hideOnionSource"), &cVar);
    1341           1 :         if (NS_SUCCEEDED(rv))
    1342             :             mHideOnionReferrerSource = cVar;
    1343             :     }
    1344           0 : 
    1345           0 :     if (PREF_CHANGED(HTTP_PREF("referer.trimmingPolicy"))) {
    1346           0 :         rv = prefs->GetIntPref(HTTP_PREF("referer.trimmingPolicy"), &val);
    1347           1 :         if (NS_SUCCEEDED(rv))
    1348             :             mReferrerTrimmingPolicy = (uint8_t) clamped(val, 0, 2);
    1349             :     }
    1350           0 : 
    1351           0 :     if (PREF_CHANGED(HTTP_PREF("referer.XOriginTrimmingPolicy"))) {
    1352           0 :         rv = prefs->GetIntPref(HTTP_PREF("referer.XOriginTrimmingPolicy"), &val);
    1353           1 :         if (NS_SUCCEEDED(rv))
    1354             :             mReferrerXOriginTrimmingPolicy = (uint8_t) clamped(val, 0, 2);
    1355             :     }
    1356           0 : 
    1357           0 :     if (PREF_CHANGED(HTTP_PREF("referer.XOriginPolicy"))) {
    1358           0 :         rv = prefs->GetIntPref(HTTP_PREF("referer.XOriginPolicy"), &val);
    1359           1 :         if (NS_SUCCEEDED(rv))
    1360             :             mReferrerXOriginPolicy = (uint8_t) clamped(val, 0, 0xff);
    1361             :     }
    1362           0 : 
    1363           0 :     if (PREF_CHANGED(HTTP_PREF("redirection-limit"))) {
    1364           0 :         rv = prefs->GetIntPref(HTTP_PREF("redirection-limit"), &val);
    1365           1 :         if (NS_SUCCEEDED(rv))
    1366             :             mRedirectionLimit = (uint8_t) clamped(val, 0, 0xff);
    1367             :     }
    1368           0 : 
    1369           0 :     if (PREF_CHANGED(HTTP_PREF("connection-retry-timeout"))) {
    1370           0 :         rv = prefs->GetIntPref(HTTP_PREF("connection-retry-timeout"), &val);
    1371           1 :         if (NS_SUCCEEDED(rv))
    1372             :             mIdleSynTimeout = (uint16_t) clamped(val, 0, 3000);
    1373             :     }
    1374           0 : 
    1375           0 :     if (PREF_CHANGED(HTTP_PREF("fast-fallback-to-IPv4"))) {
    1376           0 :         rv = prefs->GetBoolPref(HTTP_PREF("fast-fallback-to-IPv4"), &cVar);
    1377           1 :         if (NS_SUCCEEDED(rv))
    1378             :             mFastFallbackToIPv4 = cVar;
    1379             :     }
    1380           0 : 
    1381           0 :     if (PREF_CHANGED(HTTP_PREF("fallback-connection-timeout"))) {
    1382           0 :         rv = prefs->GetIntPref(HTTP_PREF("fallback-connection-timeout"), &val);
    1383           1 :         if (NS_SUCCEEDED(rv))
    1384             :             mFallbackSynTimeout = (uint16_t) clamped(val, 0, 10 * 60);
    1385             :     }
    1386           0 : 
    1387           0 :     if (PREF_CHANGED(HTTP_PREF("version"))) {
    1388           0 :         nsAutoCString httpVersion;
    1389           0 :         prefs->GetCharPref(HTTP_PREF("version"), httpVersion);
    1390           0 :         if (!httpVersion.IsVoid()) {
    1391           1 :             if (httpVersion.EqualsLiteral("1.1"))
    1392           0 :                 mHttpVersion = HttpVersion::v1_1;
    1393           0 :             else if (httpVersion.EqualsLiteral("0.9"))
    1394             :                 mHttpVersion = HttpVersion::v0_9;
    1395           0 :             else
    1396             :                 mHttpVersion = HttpVersion::v1_0;
    1397             :         }
    1398             :     }
    1399           0 : 
    1400           0 :     if (PREF_CHANGED(HTTP_PREF("proxy.version"))) {
    1401           0 :         nsAutoCString httpVersion;
    1402           0 :         prefs->GetCharPref(HTTP_PREF("proxy.version"), httpVersion);
    1403           0 :         if (!httpVersion.IsVoid()) {
    1404           1 :             if (httpVersion.EqualsLiteral("1.1"))
    1405             :                 mProxyHttpVersion = HttpVersion::v1_1;
    1406           0 :             else
    1407             :                 mProxyHttpVersion = HttpVersion::v1_0;
    1408             :             // it does not make sense to issue a HTTP/0.9 request to a proxy server
    1409             :         }
    1410             :     }
    1411           0 : 
    1412           0 :     if (PREF_CHANGED(HTTP_PREF("qos"))) {
    1413           0 :         rv = prefs->GetIntPref(HTTP_PREF("qos"), &val);
    1414           1 :         if (NS_SUCCEEDED(rv))
    1415             :             mQoSBits = (uint8_t) clamped(val, 0, 0xff);
    1416             :     }
    1417           0 : 
    1418           0 :     if (PREF_CHANGED(HTTP_PREF("accept.default"))) {
    1419           0 :         nsAutoCString accept;
    1420           0 :         rv = prefs->GetCharPref(HTTP_PREF("accept.default"), accept);
    1421           0 :         if (NS_SUCCEEDED(rv)) {
    1422           1 :             rv = SetAccept(accept.get());
    1423             :             MOZ_ASSERT(NS_SUCCEEDED(rv));
    1424             :         }
    1425             :     }
    1426           0 : 
    1427           0 :     if (PREF_CHANGED(HTTP_PREF("accept-encoding"))) {
    1428           0 :         nsAutoCString acceptEncodings;
    1429           0 :         rv = prefs->GetCharPref(HTTP_PREF("accept-encoding"), acceptEncodings);
    1430           0 :         if (NS_SUCCEEDED(rv)) {
    1431           1 :             rv = SetAcceptEncodings(acceptEncodings.get(), false);
    1432             :             MOZ_ASSERT(NS_SUCCEEDED(rv));
    1433             :         }
    1434             :     }
    1435           0 : 
    1436           2 :     if (PREF_CHANGED(HTTP_PREF("accept-encoding.secure"))) {
    1437             :         nsAutoCString acceptEncodings;
    1438           0 :         rv = prefs->GetCharPref(HTTP_PREF("accept-encoding.secure"),
    1439           0 :                                 acceptEncodings);
    1440           0 :         if (NS_SUCCEEDED(rv)) {
    1441           1 :             rv = SetAcceptEncodings(acceptEncodings.get(), true);
    1442             :             MOZ_ASSERT(NS_SUCCEEDED(rv));
    1443             :         }
    1444             :     }
    1445           0 : 
    1446           0 :     if (PREF_CHANGED(HTTP_PREF("default-socket-type"))) {
    1447           0 :         nsAutoCString sval;
    1448           0 :         rv = prefs->GetCharPref(HTTP_PREF("default-socket-type"), sval);
    1449           0 :         if (NS_SUCCEEDED(rv)) {
    1450           1 :             if (sval.IsEmpty())
    1451             :                 mDefaultSocketType.SetIsVoid(true);
    1452             :             else {
    1453             :                 // verify that this socket type is actually valid
    1454           0 :                 nsCOMPtr<nsISocketProviderService> sps(
    1455           0 :                         do_GetService(NS_SOCKETPROVIDERSERVICE_CONTRACTID));
    1456           0 :                 if (sps) {
    1457           0 :                     nsCOMPtr<nsISocketProvider> sp;
    1458           0 :                     rv = sps->GetSocketProvider(sval.get(), getter_AddRefs(sp));
    1459             :                     if (NS_SUCCEEDED(rv)) {
    1460           0 :                         // OK, this looks like a valid socket provider.
    1461             :                         mDefaultSocketType.Assign(sval);
    1462             :                     }
    1463             :                 }
    1464             :             }
    1465             :         }
    1466             :     }
    1467           0 : 
    1468           0 :     if (PREF_CHANGED(HTTP_PREF("prompt-temp-redirect"))) {
    1469           0 :         rv = prefs->GetBoolPref(HTTP_PREF("prompt-temp-redirect"), &cVar);
    1470           1 :         if (NS_SUCCEEDED(rv)) {
    1471             :             mPromptTempRedirect = cVar;
    1472             :         }
    1473             :     }
    1474           0 : 
    1475           0 :     if (PREF_CHANGED(HTTP_PREF("assoc-req.enforce"))) {
    1476           0 :         cVar = false;
    1477           0 :         rv = prefs->GetBoolPref(HTTP_PREF("assoc-req.enforce"), &cVar);
    1478           1 :         if (NS_SUCCEEDED(rv))
    1479             :             mEnforceAssocReq = cVar;
    1480             :     }
    1481             : 
    1482           0 :     // enable Persistent caching for HTTPS - bug#205921
    1483           0 :     if (PREF_CHANGED(BROWSER_PREF("disk_cache_ssl"))) {
    1484           0 :         cVar = false;
    1485           0 :         rv = prefs->GetBoolPref(BROWSER_PREF("disk_cache_ssl"), &cVar);
    1486           1 :         if (NS_SUCCEEDED(rv))
    1487             :             mEnablePersistentHttpsCaching = cVar;
    1488             :     }
    1489           0 : 
    1490           0 :     if (PREF_CHANGED(HTTP_PREF("phishy-userpass-length"))) {
    1491           0 :         rv = prefs->GetIntPref(HTTP_PREF("phishy-userpass-length"), &val);
    1492           1 :         if (NS_SUCCEEDED(rv))
    1493             :             mPhishyUserPassLength = (uint8_t) clamped(val, 0, 0xff);
    1494             :     }
    1495           0 : 
    1496           0 :     if (PREF_CHANGED(HTTP_PREF("spdy.enabled"))) {
    1497           0 :         rv = prefs->GetBoolPref(HTTP_PREF("spdy.enabled"), &cVar);
    1498           1 :         if (NS_SUCCEEDED(rv))
    1499             :             mEnableSpdy = cVar;
    1500             :     }
    1501           0 : 
    1502           0 :     if (PREF_CHANGED(HTTP_PREF("spdy.enabled.http2"))) {
    1503           0 :         rv = prefs->GetBoolPref(HTTP_PREF("spdy.enabled.http2"), &cVar);
    1504           1 :         if (NS_SUCCEEDED(rv))
    1505             :             mHttp2Enabled = cVar;
    1506             :     }
    1507           0 : 
    1508           0 :     if (PREF_CHANGED(HTTP_PREF("spdy.enabled.deps"))) {
    1509           0 :         rv = prefs->GetBoolPref(HTTP_PREF("spdy.enabled.deps"), &cVar);
    1510           1 :         if (NS_SUCCEEDED(rv))
    1511             :             mUseH2Deps = cVar;
    1512             :     }
    1513           0 : 
    1514           0 :     if (PREF_CHANGED(HTTP_PREF("spdy.enforce-tls-profile"))) {
    1515           0 :         rv = prefs->GetBoolPref(HTTP_PREF("spdy.enforce-tls-profile"), &cVar);
    1516           1 :         if (NS_SUCCEEDED(rv))
    1517             :             mEnforceHttp2TlsProfile = cVar;
    1518             :     }
    1519           0 : 
    1520           0 :     if (PREF_CHANGED(HTTP_PREF("spdy.coalesce-hostnames"))) {
    1521           0 :         rv = prefs->GetBoolPref(HTTP_PREF("spdy.coalesce-hostnames"), &cVar);
    1522           1 :         if (NS_SUCCEEDED(rv))
    1523             :             mCoalesceSpdy = cVar;
    1524             :     }
    1525           1 : 
    1526             :     if (PREF_CHANGED(HTTP_PREF("spdy.persistent-settings"))) {
    1527           0 :         rv = prefs->GetBoolPref(HTTP_PREF("spdy.persistent-settings"),
    1528           0 :                                 &cVar);
    1529           1 :         if (NS_SUCCEEDED(rv))
    1530             :             mSpdyPersistentSettings = cVar;
    1531             :     }
    1532           0 : 
    1533           0 :     if (PREF_CHANGED(HTTP_PREF("spdy.timeout"))) {
    1534           0 :         rv = prefs->GetIntPref(HTTP_PREF("spdy.timeout"), &val);
    1535           1 :         if (NS_SUCCEEDED(rv))
    1536             :             mSpdyTimeout = PR_SecondsToInterval(clamped(val, 1, 0xffff));
    1537             :     }
    1538           1 : 
    1539             :     if (PREF_CHANGED(HTTP_PREF("spdy.chunk-size"))) {
    1540           0 :         // keep this within http/2 ranges of 1 to 2^14-1
    1541           0 :         rv = prefs->GetIntPref(HTTP_PREF("spdy.chunk-size"), &val);
    1542           1 :         if (NS_SUCCEEDED(rv))
    1543             :             mSpdySendingChunkSize = (uint32_t) clamped(val, 1, 0x3fff);
    1544             :     }
    1545             : 
    1546             :     // The amount of idle seconds on a spdy connection before initiating a
    1547           0 :     // server ping. 0 will disable.
    1548           0 :     if (PREF_CHANGED(HTTP_PREF("spdy.ping-threshold"))) {
    1549           0 :         rv = prefs->GetIntPref(HTTP_PREF("spdy.ping-threshold"), &val);
    1550           0 :         if (NS_SUCCEEDED(rv))
    1551           2 :             mSpdyPingThreshold =
    1552             :                 PR_SecondsToInterval((uint16_t) clamped(val, 0, 0x7fffffff));
    1553             :     }
    1554             : 
    1555             :     // The amount of seconds to wait for a spdy ping response before
    1556           0 :     // closing the session.
    1557           0 :     if (PREF_CHANGED(HTTP_PREF("spdy.ping-timeout"))) {
    1558           0 :         rv = prefs->GetIntPref(HTTP_PREF("spdy.ping-timeout"), &val);
    1559           0 :         if (NS_SUCCEEDED(rv))
    1560           2 :             mSpdyPingTimeout =
    1561             :                 PR_SecondsToInterval((uint16_t) clamped(val, 0, 0x7fffffff));
    1562             :     }
    1563           1 : 
    1564             :     if (PREF_CHANGED(HTTP_PREF("spdy.allow-push"))) {
    1565           0 :         rv = prefs->GetBoolPref(HTTP_PREF("spdy.allow-push"),
    1566           0 :                                 &cVar);
    1567           1 :         if (NS_SUCCEEDED(rv))
    1568             :             mAllowPush = cVar;
    1569             :     }
    1570           1 : 
    1571             :     if (PREF_CHANGED(HTTP_PREF("altsvc.enabled"))) {
    1572           0 :         rv = prefs->GetBoolPref(HTTP_PREF("altsvc.enabled"),
    1573           0 :                                 &cVar);
    1574           1 :         if (NS_SUCCEEDED(rv))
    1575             :             mEnableAltSvc = cVar;
    1576             :     }
    1577             : 
    1578           1 : 
    1579             :     if (PREF_CHANGED(HTTP_PREF("altsvc.oe"))) {
    1580           0 :         rv = prefs->GetBoolPref(HTTP_PREF("altsvc.oe"),
    1581           0 :                                 &cVar);
    1582           1 :         if (NS_SUCCEEDED(rv))
    1583             :             mEnableAltSvcOE = cVar;
    1584             :     }
    1585           1 : 
    1586             :     if (PREF_CHANGED(HTTP_PREF("originextension"))) {
    1587           0 :         rv = prefs->GetBoolPref(HTTP_PREF("originextension"),
    1588           0 :                                 &cVar);
    1589           1 :         if (NS_SUCCEEDED(rv))
    1590             :             mEnableOriginExtension = cVar;
    1591             :     }
    1592           0 : 
    1593           0 :     if (PREF_CHANGED(HTTP_PREF("spdy.push-allowance"))) {
    1594           0 :         rv = prefs->GetIntPref(HTTP_PREF("spdy.push-allowance"), &val);
    1595           0 :         if (NS_SUCCEEDED(rv)) {
    1596           0 :             mSpdyPushAllowance =
    1597           2 :                 static_cast<uint32_t>
    1598             :                 (clamped(val, 1024, static_cast<int32_t>(ASpdySession::kInitialRwin)));
    1599             :         }
    1600             :     }
    1601           0 : 
    1602           0 :     if (PREF_CHANGED(HTTP_PREF("spdy.pull-allowance"))) {
    1603           0 :         rv = prefs->GetIntPref(HTTP_PREF("spdy.pull-allowance"), &val);
    1604           0 :         if (NS_SUCCEEDED(rv)) {
    1605           2 :             mSpdyPullAllowance =
    1606             :                 static_cast<uint32_t>(clamped(val, 1024, 0x7fffffff));
    1607             :         }
    1608             :     }
    1609           0 : 
    1610           0 :     if (PREF_CHANGED(HTTP_PREF("spdy.default-concurrent"))) {
    1611           0 :         rv = prefs->GetIntPref(HTTP_PREF("spdy.default-concurrent"), &val);
    1612           0 :         if (NS_SUCCEEDED(rv)) {
    1613           4 :             mDefaultSpdyConcurrent =
    1614             :                 static_cast<uint32_t>(std::max<int32_t>(std::min<int32_t>(val, 9999), 1));
    1615             :         }
    1616             :     }
    1617             : 
    1618             :     // The amount of seconds to wait for a spdy ping response before
    1619           0 :     // closing the session.
    1620           0 :     if (PREF_CHANGED(HTTP_PREF("spdy.send-buffer-size"))) {
    1621           0 :         rv = prefs->GetIntPref(HTTP_PREF("spdy.send-buffer-size"), &val);
    1622           1 :         if (NS_SUCCEEDED(rv))
    1623             :             mSpdySendBufferSize = (uint32_t) clamped(val, 1500, 0x7fffffff);
    1624             :     }
    1625             : 
    1626             :     // The maximum amount of time to wait for socket transport to be
    1627           0 :     // established
    1628           0 :     if (PREF_CHANGED(HTTP_PREF("connection-timeout"))) {
    1629           1 :         rv = prefs->GetIntPref(HTTP_PREF("connection-timeout"), &val);
    1630             :         if (NS_SUCCEEDED(rv))
    1631           1 :             // the pref is in seconds, but the variable is in milliseconds
    1632             :             mConnectTimeout = clamped(val, 1, 0xffff) * PR_MSEC_PER_SEC;
    1633             :     }
    1634             : 
    1635           0 :     // The maximum amount of time to wait for a tls handshake to finish.
    1636           0 :     if (PREF_CHANGED(HTTP_PREF("tls-handshake-timeout"))) {
    1637           1 :         rv = prefs->GetIntPref(HTTP_PREF("tls-handshake-timeout"), &val);
    1638             :         if (NS_SUCCEEDED(rv))
    1639           1 :             // the pref is in seconds, but the variable is in milliseconds
    1640             :             mTLSHandshakeTimeout = clamped(val, 1, 0xffff) * PR_MSEC_PER_SEC;
    1641             :     }
    1642             : 
    1643             :     // The maximum number of current global half open sockets allowable
    1644           0 :     // for starting a new speculative connection.
    1645           0 :     if (PREF_CHANGED(HTTP_PREF("speculative-parallel-limit"))) {
    1646           0 :         rv = prefs->GetIntPref(HTTP_PREF("speculative-parallel-limit"), &val);
    1647           1 :         if (NS_SUCCEEDED(rv))
    1648             :             mParallelSpeculativeConnectLimit = (uint32_t) clamped(val, 0, 1024);
    1649             :     }
    1650             : 
    1651             :     // Whether or not to block requests for non head js/css items (e.g. media)
    1652           0 :     // while those elements load.
    1653           0 :     if (PREF_CHANGED(HTTP_PREF("rendering-critical-requests-prioritization"))) {
    1654           0 :         rv = prefs->GetBoolPref(HTTP_PREF("rendering-critical-requests-prioritization"), &cVar);
    1655           1 :         if (NS_SUCCEEDED(rv))
    1656             :             mCriticalRequestPrioritization = cVar;
    1657             :     }
    1658             : 
    1659             :     // on transition of network.http.diagnostics to true print
    1660           1 :     // a bunch of information to the console
    1661           0 :     if (pref && PREF_CHANGED(HTTP_PREF("diagnostics"))) {
    1662           0 :         rv = prefs->GetBoolPref(HTTP_PREF("diagnostics"), &cVar);
    1663           0 :         if (NS_SUCCEEDED(rv) && cVar) {
    1664           0 :             if (mConnMgr)
    1665             :                 mConnMgr->PrintDiagnostics();
    1666             :         }
    1667             :     }
    1668           0 : 
    1669           0 :     if (PREF_CHANGED(HTTP_PREF("max_response_header_size"))) {
    1670           0 :         rv = prefs->GetIntPref(HTTP_PREF("max_response_header_size"), &val);
    1671           1 :         if (NS_SUCCEEDED(rv)) {
    1672             :             mMaxHttpResponseHeaderSize = val;
    1673             :         }
    1674             :     }
    1675           0 : 
    1676           0 :     if (PREF_CHANGED(HTTP_PREF("throttle.enable"))) {
    1677           1 :         rv = prefs->GetBoolPref(HTTP_PREF("throttle.enable"), &mThrottleEnabled);
    1678           0 :         if (NS_SUCCEEDED(rv) && mConnMgr) {
    1679           0 :             Unused << mConnMgr->UpdateParam(nsHttpConnectionMgr::THROTTLING_ENABLED,
    1680             :                                             static_cast<int32_t>(mThrottleEnabled));
    1681             :         }
    1682             :     }
    1683           0 : 
    1684           0 :     if (PREF_CHANGED(HTTP_PREF("throttle.version"))) {
    1685           1 :         rv = prefs->GetIntPref(HTTP_PREF("throttle.version"), &val);
    1686             :         mThrottleVersion = (uint32_t)clamped(val, 1, 2);
    1687             :     }
    1688           0 : 
    1689           0 :     if (PREF_CHANGED(HTTP_PREF("throttle.suspend-for"))) {
    1690           0 :         rv = prefs->GetIntPref(HTTP_PREF("throttle.suspend-for"), &val);
    1691           1 :         mThrottleSuspendFor = (uint32_t)clamped(val, 0, 120000);
    1692           0 :         if (NS_SUCCEEDED(rv) && mConnMgr) {
    1693             :             Unused << mConnMgr->UpdateParam(nsHttpConnectionMgr::THROTTLING_SUSPEND_FOR,
    1694             :                                             mThrottleSuspendFor);
    1695             :         }
    1696             :     }
    1697           0 : 
    1698           0 :     if (PREF_CHANGED(HTTP_PREF("throttle.resume-for"))) {
    1699           0 :         rv = prefs->GetIntPref(HTTP_PREF("throttle.resume-for"), &val);
    1700           1 :         mThrottleResumeFor = (uint32_t)clamped(val, 0, 120000);
    1701           0 :         if (NS_SUCCEEDED(rv) && mConnMgr) {
    1702             :             Unused << mConnMgr->UpdateParam(nsHttpConnectionMgr::THROTTLING_RESUME_FOR,
    1703             :                                             mThrottleResumeFor);
    1704             :         }
    1705             :     }
    1706           0 : 
    1707           0 :     if (PREF_CHANGED(HTTP_PREF("throttle.read-limit-bytes"))) {
    1708           0 :         rv = prefs->GetIntPref(HTTP_PREF("throttle.read-limit-bytes"), &val);
    1709           1 :         mThrottleReadLimit = (uint32_t)clamped(val, 0, 500000);
    1710           0 :         if (NS_SUCCEEDED(rv) && mConnMgr) {
    1711             :             Unused << mConnMgr->UpdateParam(nsHttpConnectionMgr::THROTTLING_READ_LIMIT,
    1712             :                                             mThrottleReadLimit);
    1713             :         }
    1714             :     }
    1715           0 : 
    1716           0 :     if (PREF_CHANGED(HTTP_PREF("throttle.read-interval-ms"))) {
    1717           0 :         rv = prefs->GetIntPref(HTTP_PREF("throttle.read-interval-ms"), &val);
    1718           1 :         mThrottleReadInterval = (uint32_t)clamped(val, 0, 120000);
    1719           0 :         if (NS_SUCCEEDED(rv) && mConnMgr) {
    1720             :             Unused << mConnMgr->UpdateParam(nsHttpConnectionMgr::THROTTLING_READ_INTERVAL,
    1721             :                                             mThrottleReadInterval);
    1722             :         }
    1723             :     }
    1724           0 : 
    1725           0 :     if (PREF_CHANGED(HTTP_PREF("throttle.hold-time-ms"))) {
    1726           0 :         rv = prefs->GetIntPref(HTTP_PREF("throttle.hold-time-ms"), &val);
    1727           1 :         mThrottleHoldTime = (uint32_t)clamped(val, 0, 120000);
    1728           0 :         if (NS_SUCCEEDED(rv) && mConnMgr) {
    1729             :             Unused << mConnMgr->UpdateParam(nsHttpConnectionMgr::THROTTLING_HOLD_TIME,
    1730             :                                             mThrottleHoldTime);
    1731             :         }
    1732             :     }
    1733           0 : 
    1734           0 :     if (PREF_CHANGED(HTTP_PREF("throttle.max-time-ms"))) {
    1735           0 :       rv = prefs->GetIntPref(HTTP_PREF("throttle.max-time-ms"), &val);
    1736           1 :       mThrottleMaxTime = (uint32_t)clamped(val, 0, 120000);
    1737           0 :       if (NS_SUCCEEDED(rv) && mConnMgr) {
    1738             :         Unused << mConnMgr->UpdateParam(nsHttpConnectionMgr::THROTTLING_MAX_TIME,
    1739             :                                         mThrottleMaxTime);
    1740             :       }
    1741             :     }
    1742           0 : 
    1743           1 :     if (PREF_CHANGED(HTTP_PREF("on_click_priority"))) {
    1744             :         Unused << prefs->GetBoolPref(HTTP_PREF("on_click_priority"), &mUrgentStartEnabled);
    1745             :     }
    1746           0 : 
    1747           1 :     if (PREF_CHANGED(HTTP_PREF("tailing.enabled"))) {
    1748             :         Unused << prefs->GetBoolPref(HTTP_PREF("tailing.enabled"), &mTailBlockingEnabled);
    1749           0 :     }
    1750           0 :     if (PREF_CHANGED(HTTP_PREF("tailing.delay-quantum"))) {
    1751           1 :         Unused << prefs->GetIntPref(HTTP_PREF("tailing.delay-quantum"), &val);
    1752             :         mTailDelayQuantum = (uint32_t)clamped(val, 0, 60000);
    1753           0 :     }
    1754           0 :     if (PREF_CHANGED(HTTP_PREF("tailing.delay-quantum-after-domcontentloaded"))) {
    1755           1 :         Unused << prefs->GetIntPref(HTTP_PREF("tailing.delay-quantum-after-domcontentloaded"), &val);
    1756             :         mTailDelayQuantumAfterDCL = (uint32_t)clamped(val, 0, 60000);
    1757           0 :     }
    1758           0 :     if (PREF_CHANGED(HTTP_PREF("tailing.delay-max"))) {
    1759           1 :         Unused << prefs->GetIntPref(HTTP_PREF("tailing.delay-max"), &val);
    1760             :         mTailDelayMax = (uint32_t)clamped(val, 0, 60000);
    1761           0 :     }
    1762           0 :     if (PREF_CHANGED(HTTP_PREF("tailing.total-max"))) {
    1763           1 :         Unused << prefs->GetIntPref(HTTP_PREF("tailing.total-max"), &val);
    1764             :         mTailTotalMax = (uint32_t)clamped(val, 0, 60000);
    1765             :     }
    1766           0 : 
    1767           0 :     if (PREF_CHANGED(HTTP_PREF("focused_window_transaction_ratio"))) {
    1768           0 :         float ratio = 0;
    1769           0 :         rv = prefs->GetFloatPref(HTTP_PREF("focused_window_transaction_ratio"), &ratio);
    1770           0 :         if (NS_SUCCEEDED(rv)) {
    1771           1 :             if (ratio > 0 && ratio < 1) {
    1772             :                 mFocusedWindowTransactionRatio = ratio;
    1773           0 :             } else {
    1774             :                 NS_WARNING("Wrong value for focused_window_transaction_ratio");
    1775             :             }
    1776             :         }
    1777             :     }
    1778             : 
    1779             :     //
    1780             :     // INTL options
    1781             :     //
    1782           1 : 
    1783             :     if (PREF_CHANGED(INTL_ACCEPT_LANGUAGES)) {
    1784             :         // We don't want to set the new accept languages here since
    1785             :         // this pref is a complex type and it may be racy with flushing
    1786           1 :         // string resources.
    1787             :         mAcceptLanguagesIsDirty = true;
    1788             :     }
    1789             : 
    1790             :     //
    1791             :     // Tracking options
    1792             :     //
    1793           0 : 
    1794           0 :     if (PREF_CHANGED(DONOTTRACK_HEADER_ENABLED)) {
    1795           0 :         cVar = false;
    1796           0 :         rv = prefs->GetBoolPref(DONOTTRACK_HEADER_ENABLED, &cVar);
    1797           1 :         if (NS_SUCCEEDED(rv)) {
    1798             :             mDoNotTrackEnabled = cVar;
    1799             :         }
    1800             :     }
    1801           0 :     // Hint option
    1802           0 :     if (PREF_CHANGED(SAFE_HINT_HEADER_VALUE)) {
    1803           0 :         cVar = false;
    1804           1 :         rv = prefs->GetBoolPref(SAFE_HINT_HEADER_VALUE, &cVar);
    1805           0 :         if (NS_SUCCEEDED(rv)) {
    1806             :             mSafeHintEnabled = cVar;
    1807             :         }
    1808             :     }
    1809             : 
    1810             :     // toggle to true anytime a token bucket related pref is changed.. that
    1811           1 :     // includes telemetry and allow-experiments because of the abtest profile
    1812             :     bool requestTokenBucketUpdated = false;
    1813             : 
    1814             :     //
    1815             :     // Telemetry
    1816             :     //
    1817           0 : 
    1818           0 :     if (PREF_CHANGED(TELEMETRY_ENABLED)) {
    1819           0 :         cVar = false;
    1820           0 :         requestTokenBucketUpdated = true;
    1821           0 :         rv = prefs->GetBoolPref(TELEMETRY_ENABLED, &cVar);
    1822           1 :         if (NS_SUCCEEDED(rv)) {
    1823             :             mTelemetryEnabled = cVar;
    1824             :         }
    1825             :     }
    1826             : 
    1827             :     // "security.ssl3.ecdhe_rsa_aes_128_gcm_sha256" is the required h2 interop
    1828             :     // suite.
    1829           0 : 
    1830           0 :     if (PREF_CHANGED(H2MANDATORY_SUITE)) {
    1831           0 :         cVar = false;
    1832           0 :         rv = prefs->GetBoolPref(H2MANDATORY_SUITE, &cVar);
    1833           1 :         if (NS_SUCCEEDED(rv)) {
    1834             :             mH2MandatorySuiteEnabled = cVar;
    1835             :         }
    1836             :     }
    1837             : 
    1838             :     //
    1839             :     // network.allow-experiments
    1840           0 :     //
    1841           0 :     if (PREF_CHANGED(ALLOW_EXPERIMENTS)) {
    1842           0 :         cVar = true;
    1843           0 :         requestTokenBucketUpdated = true;
    1844           0 :         rv = prefs->GetBoolPref(ALLOW_EXPERIMENTS, &cVar);
    1845           1 :         if (NS_SUCCEEDED(rv)) {
    1846             :             mAllowExperiments = cVar;
    1847             :         }
    1848             :     }
    1849             : 
    1850           0 :     // network.http.debug-observations
    1851           0 :     if (PREF_CHANGED("network.http.debug-observations")) {
    1852           0 :         cVar = false;
    1853           0 :         rv = prefs->GetBoolPref("network.http.debug-observations", &cVar);
    1854           0 :         if (NS_SUCCEEDED(rv)) {
    1855             :             mDebugObservations = cVar;
    1856             :         }
    1857             :     }
    1858           0 : 
    1859           0 :     if (PREF_CHANGED(HTTP_PREF("pacing.requests.enabled"))) {
    1860           0 :         rv = prefs->GetBoolPref(HTTP_PREF("pacing.requests.enabled"), &cVar);
    1861           0 :         if (NS_SUCCEEDED(rv)) {
    1862           1 :             mRequestTokenBucketEnabled = cVar;
    1863             :             requestTokenBucketUpdated = true;
    1864             :         }
    1865           0 :     }
    1866           0 :     if (PREF_CHANGED(HTTP_PREF("pacing.requests.min-parallelism"))) {
    1867           0 :         rv = prefs->GetIntPref(HTTP_PREF("pacing.requests.min-parallelism"), &val);
    1868           0 :         if (NS_SUCCEEDED(rv)) {
    1869           1 :             mRequestTokenBucketMinParallelism = static_cast<uint16_t>(clamped(val, 1, 1024));
    1870             :             requestTokenBucketUpdated = true;
    1871             :         }
    1872           0 :     }
    1873           0 :     if (PREF_CHANGED(HTTP_PREF("pacing.requests.hz"))) {
    1874           0 :         rv = prefs->GetIntPref(HTTP_PREF("pacing.requests.hz"), &val);
    1875           0 :         if (NS_SUCCEEDED(rv)) {
    1876           1 :             mRequestTokenBucketHz = static_cast<uint32_t>(clamped(val, 1, 10000));
    1877             :             requestTokenBucketUpdated = true;
    1878             :         }
    1879           0 :     }
    1880           0 :     if (PREF_CHANGED(HTTP_PREF("pacing.requests.burst"))) {
    1881           0 :         rv = prefs->GetIntPref(HTTP_PREF("pacing.requests.burst"), &val);
    1882           0 :         if (NS_SUCCEEDED(rv)) {
    1883           1 :             mRequestTokenBucketBurst = val ? val : 1;
    1884             :             requestTokenBucketUpdated = true;
    1885             :         }
    1886           0 :     }
    1887           1 :     if (requestTokenBucketUpdated) {
    1888             :         MakeNewRequestTokenBucket();
    1889             :     }
    1890             : 
    1891           1 :     // Keepalive values for initial and idle connections.
    1892             :     if (PREF_CHANGED(HTTP_PREF("tcp_keepalive.short_lived_connections"))) {
    1893           0 :         rv = prefs->GetBoolPref(
    1894           0 :             HTTP_PREF("tcp_keepalive.short_lived_connections"), &cVar);
    1895           1 :         if (NS_SUCCEEDED(rv) && cVar != mTCPKeepaliveShortLivedEnabled) {
    1896             :             mTCPKeepaliveShortLivedEnabled = cVar;
    1897             :         }
    1898             :     }
    1899           1 : 
    1900             :     if (PREF_CHANGED(HTTP_PREF("tcp_keepalive.short_lived_time"))) {
    1901           0 :         rv = prefs->GetIntPref(
    1902           0 :             HTTP_PREF("tcp_keepalive.short_lived_time"), &val);
    1903           1 :         if (NS_SUCCEEDED(rv) && val > 0)
    1904             :             mTCPKeepaliveShortLivedTimeS = clamped(val, 1, 300); // Max 5 mins.
    1905             :     }
    1906           1 : 
    1907             :     if (PREF_CHANGED(HTTP_PREF("tcp_keepalive.short_lived_idle_time"))) {
    1908           0 :         rv = prefs->GetIntPref(
    1909           0 :             HTTP_PREF("tcp_keepalive.short_lived_idle_time"), &val);
    1910           0 :         if (NS_SUCCEEDED(rv) && val > 0)
    1911           2 :             mTCPKeepaliveShortLivedIdleTimeS = clamped(val,
    1912             :                                                        1, kMaxTCPKeepIdle);
    1913             :     }
    1914             : 
    1915           1 :     // Keepalive values for Long-lived Connections.
    1916             :     if (PREF_CHANGED(HTTP_PREF("tcp_keepalive.long_lived_connections"))) {
    1917           0 :         rv = prefs->GetBoolPref(
    1918           0 :             HTTP_PREF("tcp_keepalive.long_lived_connections"), &cVar);
    1919           1 :         if (NS_SUCCEEDED(rv) && cVar != mTCPKeepaliveLongLivedEnabled) {
    1920             :             mTCPKeepaliveLongLivedEnabled = cVar;
    1921             :         }
    1922             :     }
    1923           1 : 
    1924             :     if (PREF_CHANGED(HTTP_PREF("tcp_keepalive.long_lived_idle_time"))) {
    1925           0 :         rv = prefs->GetIntPref(
    1926           0 :             HTTP_PREF("tcp_keepalive.long_lived_idle_time"), &val);
    1927           0 :         if (NS_SUCCEEDED(rv) && val > 0)
    1928           2 :             mTCPKeepaliveLongLivedIdleTimeS = clamped(val,
    1929             :                                                       1, kMaxTCPKeepIdle);
    1930             :     }
    1931           0 : 
    1932           0 :     if (PREF_CHANGED(HTTP_PREF("enforce-framing.http1")) ||
    1933           0 :         PREF_CHANGED(HTTP_PREF("enforce-framing.soft")) ) {
    1934           0 :         rv = prefs->GetBoolPref(HTTP_PREF("enforce-framing.http1"), &cVar);
    1935           0 :         if (NS_SUCCEEDED(rv) && cVar) {
    1936             :             mEnforceH1Framing = FRAMECHECK_STRICT;
    1937           0 :         } else {
    1938           0 :             rv = prefs->GetBoolPref(HTTP_PREF("enforce-framing.soft"), &cVar);
    1939           1 :             if (NS_SUCCEEDED(rv) && cVar) {
    1940             :                 mEnforceH1Framing = FRAMECHECK_BARELY;
    1941           0 :             } else {
    1942             :                 mEnforceH1Framing = FRAMECHECK_LAX;
    1943             :             }
    1944             :         }
    1945             :     }
    1946           0 : 
    1947           0 :     if (PREF_CHANGED(TCP_FAST_OPEN_ENABLE)) {
    1948           0 :         rv = prefs->GetBoolPref(TCP_FAST_OPEN_ENABLE, &cVar);
    1949           1 :         if (NS_SUCCEEDED(rv)) {
    1950             :             mUseFastOpen = cVar;
    1951             :         }
    1952             :     }
    1953           0 : 
    1954           0 :     if (PREF_CHANGED(TCP_FAST_OPEN_FAILURE_LIMIT)) {
    1955           0 :         rv = prefs->GetIntPref(TCP_FAST_OPEN_FAILURE_LIMIT, &val);
    1956           1 :         if (NS_SUCCEEDED(rv)) {
    1957           0 :             if (val < 0) {
    1958             :                 val = 0;
    1959           1 :             }
    1960             :             mFastOpenConsecutiveFailureLimit = val;
    1961             :         }
    1962             :     }
    1963           0 : 
    1964           0 :     if (PREF_CHANGED(TCP_FAST_OPEN_STALLS_LIMIT)) {
    1965           0 :         rv = prefs->GetIntPref(TCP_FAST_OPEN_STALLS_LIMIT, &val);
    1966           1 :         if (NS_SUCCEEDED(rv)) {
    1967           0 :             if (val < 0) {
    1968             :                 val = 0;
    1969           1 :             }
    1970             :             mFastOpenStallsLimit = val;
    1971             :         }
    1972             :     }
    1973           0 : 
    1974           0 :     if (PREF_CHANGED(TCP_FAST_OPEN_STALLS_TIMEOUT)) {
    1975           0 :         rv = prefs->GetIntPref(TCP_FAST_OPEN_STALLS_TIMEOUT, &val);
    1976           1 :         if (NS_SUCCEEDED(rv)) {
    1977           0 :             if (val < 0) {
    1978             :                 val = 0;
    1979           1 :             }
    1980             :             mFastOpenStallsTimeout = val;
    1981             :         }
    1982             :     }
    1983           0 : 
    1984           0 :     if (PREF_CHANGED(TCP_FAST_OPEN_STALLS_IDLE)) {
    1985           0 :         rv = prefs->GetIntPref(TCP_FAST_OPEN_STALLS_IDLE, &val);
    1986           1 :         if (NS_SUCCEEDED(rv)) {
    1987           0 :             if (val < 0) {
    1988             :                 val = 0;
    1989           1 :             }
    1990             :             mFastOpenStallsIdleTime = val;
    1991             :         }
    1992             :     }
    1993           0 : 
    1994           0 :     if (PREF_CHANGED(HTTP_PREF("spdy.hpack-default-buffer"))) {
    1995           0 :         rv = prefs->GetIntPref(HTTP_PREF("spdy.default-hpack-buffer"), &val);
    1996           1 :         if (NS_SUCCEEDED(rv)) {
    1997             :             mDefaultHpackBuffer = val;
    1998             :         }
    1999             :     }
    2000             : 
    2001           0 :     // Enable HTTP response timeout if TCP Keepalives are disabled.
    2002           0 :     mResponseTimeoutEnabled = !mTCPKeepaliveShortLivedEnabled &&
    2003             :                               !mTCPKeepaliveLongLivedEnabled;
    2004             : 
    2005             : #undef PREF_CHANGED
    2006           1 : #undef MULTI_PREF_CHANGED
    2007             : }
    2008             : 
    2009             : /**
    2010             :  *  Allocates a C string into that contains a ISO 639 language list
    2011             :  *  notated with HTTP "q" values for output with a HTTP Accept-Language
    2012             :  *  header. Previous q values will be stripped because the order of
    2013             :  *  the langs imply the q value. The q values are calculated by dividing
    2014             :  *  1.0 amongst the number of languages present.
    2015             :  *
    2016             :  *  Ex: passing: "en, ja"
    2017             :  *      returns: "en,ja;q=0.5"
    2018             :  *
    2019             :  *      passing: "en, ja, fr_CA"
    2020             :  *      returns: "en,ja;q=0.7,fr_CA;q=0.3"
    2021             :  */
    2022           1 : static nsresult
    2023             : PrepareAcceptLanguages(const char *i_AcceptLanguages, nsACString &o_AcceptLanguages)
    2024           1 : {
    2025             :     if (!i_AcceptLanguages)
    2026             :         return NS_OK;
    2027           1 : 
    2028             :     const nsAutoCString ns_accept_languages(i_AcceptLanguages);
    2029           1 :     return rust_prepare_accept_languages(&ns_accept_languages,
    2030             :                                          &o_AcceptLanguages);
    2031             : }
    2032             : 
    2033           1 : nsresult
    2034             : nsHttpHandler::SetAcceptLanguages()
    2035           1 : {
    2036             :     mAcceptLanguagesIsDirty = false;
    2037           0 : 
    2038           1 :     nsAutoCString acceptLanguages;
    2039             :     Preferences::GetLocalizedCString(INTL_ACCEPT_LANGUAGES, acceptLanguages);
    2040           0 : 
    2041           0 :     nsAutoCString buf;
    2042           0 :     nsresult rv = PrepareAcceptLanguages(acceptLanguages.get(), buf);
    2043           1 :     if (NS_SUCCEEDED(rv)) {
    2044             :         mAcceptLanguages.Assign(buf);
    2045           2 :     }
    2046             :     return rv;
    2047             : }
    2048             : 
    2049           0 : nsresult
    2050             : nsHttpHandler::SetAccept(const char *aAccept)
    2051           1 : {
    2052           0 :     mAccept = aAccept;
    2053             :     return NS_OK;
    2054             : }
    2055             : 
    2056           2 : nsresult
    2057             : nsHttpHandler::SetAcceptEncodings(const char *aAcceptEncodings, bool isSecure)
    2058           0 : {
    2059           1 :     if (isSecure) {
    2060             :         mHttpsAcceptEncodings = aAcceptEncodings;
    2061             :     } else {
    2062           0 :         // use legacy list if a secure override is not specified
    2063           0 :         mHttpAcceptEncodings = aAcceptEncodings;
    2064           1 :         if (mHttpsAcceptEncodings.IsEmpty()) {
    2065             :             mHttpsAcceptEncodings = aAcceptEncodings;
    2066             :         }
    2067             :     }
    2068           2 : 
    2069             :     return NS_OK;
    2070             : }
    2071             : 
    2072             : //-----------------------------------------------------------------------------
    2073             : // nsHttpHandler::nsISupports
    2074             : //-----------------------------------------------------------------------------
    2075         536 : 
    2076             : NS_IMPL_ISUPPORTS(nsHttpHandler,
    2077             :                   nsIHttpProtocolHandler,
    2078             :                   nsIProxiedProtocolHandler,
    2079             :                   nsIProtocolHandler,
    2080             :                   nsIObserver,
    2081             :                   nsISupportsWeakReference,
    2082             :                   nsISpeculativeConnect)
    2083             : 
    2084             : //-----------------------------------------------------------------------------
    2085             : // nsHttpHandler::nsIProtocolHandler
    2086             : //-----------------------------------------------------------------------------
    2087             : 
    2088           0 : NS_IMETHODIMP
    2089             : nsHttpHandler::GetScheme(nsACString &aScheme)
    2090           0 : {
    2091           0 :     aScheme.AssignLiteral("http");
    2092             :     return NS_OK;
    2093             : }
    2094             : 
    2095           2 : NS_IMETHODIMP
    2096             : nsHttpHandler::GetDefaultPort(int32_t *result)
    2097           0 : {
    2098           2 :     *result = NS_HTTP_DEFAULT_PORT;
    2099             :     return NS_OK;
    2100             : }
    2101             : 
    2102          14 : NS_IMETHODIMP
    2103             : nsHttpHandler::GetProtocolFlags(uint32_t *result)
    2104           0 : {
    2105          14 :     *result = NS_HTTP_PROTOCOL_FLAGS;
    2106             :     return NS_OK;
    2107             : }
    2108             : 
    2109           3 : NS_IMETHODIMP
    2110             : nsHttpHandler::NewURI(const nsACString &aSpec,
    2111             :                       const char *aCharset,
    2112             :                       nsIURI *aBaseURI,
    2113             :                       nsIURI **aURI)
    2114           3 : {
    2115             :     return mozilla::net::NewURI(aSpec, aCharset, aBaseURI, NS_HTTP_DEFAULT_PORT, aURI);
    2116             : }
    2117             : 
    2118           0 : NS_IMETHODIMP
    2119             : nsHttpHandler::NewChannel2(nsIURI* uri,
    2120             :                            nsILoadInfo* aLoadInfo,
    2121             :                            nsIChannel** result)
    2122           0 : {
    2123             :     LOG(("nsHttpHandler::NewChannel\n"));
    2124           0 : 
    2125           0 :     NS_ENSURE_ARG_POINTER(uri);
    2126             :     NS_ENSURE_ARG_POINTER(result);
    2127           0 : 
    2128             :     bool isHttp = false, isHttps = false;
    2129             : 
    2130           0 :     // Verify that we have been given a valid scheme
    2131           0 :     nsresult rv = uri->SchemeIs("http", &isHttp);
    2132           0 :     if (NS_FAILED(rv)) return rv;
    2133           0 :     if (!isHttp) {
    2134           0 :         rv = uri->SchemeIs("https", &isHttps);
    2135           0 :         if (NS_FAILED(rv)) return rv;
    2136           0 :         if (!isHttps) {
    2137           0 :             NS_WARNING("Invalid URI scheme");
    2138             :             return NS_ERROR_UNEXPECTED;
    2139             :         }
    2140             :     }
    2141           0 : 
    2142             :     return NewProxiedChannel2(uri, nullptr, 0, nullptr, aLoadInfo, result);
    2143             : }
    2144             : 
    2145           0 : NS_IMETHODIMP
    2146             : nsHttpHandler::NewChannel(nsIURI *uri, nsIChannel **result)
    2147           0 : {
    2148             :     return NewChannel2(uri, nullptr, result);
    2149             : }
    2150             : 
    2151           0 : NS_IMETHODIMP
    2152             : nsHttpHandler::AllowPort(int32_t port, const char *scheme, bool *_retval)
    2153             : {
    2154           0 :     // don't override anything.
    2155           0 :     *_retval = false;
    2156             :     return NS_OK;
    2157             : }
    2158             : 
    2159             : //-----------------------------------------------------------------------------
    2160             : // nsHttpHandler::nsIProxiedProtocolHandler
    2161             : //-----------------------------------------------------------------------------
    2162             : 
    2163           3 : NS_IMETHODIMP
    2164             : nsHttpHandler::NewProxiedChannel2(nsIURI *uri,
    2165             :                                   nsIProxyInfo* givenProxyInfo,
    2166             :                                   uint32_t proxyResolveFlags,
    2167             :                                   nsIURI *proxyURI,
    2168             :                                   nsILoadInfo* aLoadInfo,
    2169             :                                   nsIChannel** result)
    2170           6 : {
    2171             :     RefPtr<HttpBaseChannel> httpChannel;
    2172           3 : 
    2173             :     LOG(("nsHttpHandler::NewProxiedChannel [proxyInfo=%p]\n",
    2174             :         givenProxyInfo));
    2175             : 
    2176             : #ifdef MOZ_TASK_TRACER
    2177             :     if (tasktracer::IsStartLogging()) {
    2178             :         nsAutoCString urispec;
    2179             :         uri->GetSpec(urispec);
    2180             :         tasktracer::AddLabel("nsHttpHandler::NewProxiedChannel2 %s", urispec.get());
    2181             :     }
    2182             : #endif
    2183           0 : 
    2184           0 :     nsCOMPtr<nsProxyInfo> proxyInfo;
    2185           0 :     if (givenProxyInfo) {
    2186           0 :         proxyInfo = do_QueryInterface(givenProxyInfo);
    2187             :         NS_ENSURE_ARG(proxyInfo);
    2188             :     }
    2189             : 
    2190           0 :     bool https;
    2191           3 :     nsresult rv = uri->SchemeIs("https", &https);
    2192             :     if (NS_FAILED(rv))
    2193             :         return rv;
    2194           0 : 
    2195           0 :     if (IsNeckoChild()) {
    2196             :         httpChannel = new HttpChannelChild();
    2197           3 :     } else {
    2198             :         httpChannel = new nsHttpChannel();
    2199             :     }
    2200           3 : 
    2201             :     uint32_t caps = mCapabilities;
    2202           3 : 
    2203             :     if (!IsNeckoChild()) {
    2204           3 :         // HACK: make sure PSM gets initialized on the main thread.
    2205             :         net_EnsurePSMInit();
    2206             :     }
    2207           3 : 
    2208             :     if (XRE_IsParentProcess()) {
    2209           3 :         // Load UserAgentOverrides.jsm before any HTTP request is issued.
    2210             :         EnsureUAOverridesInit();
    2211             :     }
    2212             : 
    2213           0 :     uint64_t channelId;
    2214           3 :     rv = NewChannelId(channelId);
    2215             :     NS_ENSURE_SUCCESS(rv, rv);
    2216           0 : 
    2217           3 :     rv = httpChannel->Init(uri, caps, proxyInfo, proxyResolveFlags, proxyURI, channelId);
    2218             :     if (NS_FAILED(rv))
    2219             :         return rv;
    2220             : 
    2221           0 :     // set the loadInfo on the new channel
    2222           3 :     rv = httpChannel->SetLoadInfo(aLoadInfo);
    2223             :     if (NS_FAILED(rv)) {
    2224             :         return rv;
    2225             :     }
    2226           0 : 
    2227           3 :     httpChannel.forget(result);
    2228             :     return NS_OK;
    2229             : }
    2230             : 
    2231           0 : NS_IMETHODIMP
    2232             : nsHttpHandler::NewProxiedChannel(nsIURI *uri,
    2233             :                                  nsIProxyInfo* givenProxyInfo,
    2234             :                                  uint32_t proxyResolveFlags,
    2235             :                                  nsIURI *proxyURI,
    2236             :                                  nsIChannel **result)
    2237             : {
    2238             :     return NewProxiedChannel2(uri, givenProxyInfo,
    2239           0 :                               proxyResolveFlags, proxyURI,
    2240             :                               nullptr, result);
    2241             : }
    2242             : 
    2243             : //-----------------------------------------------------------------------------
    2244             : // nsHttpHandler::nsIHttpProtocolHandler
    2245             : //-----------------------------------------------------------------------------
    2246             : 
    2247           0 : NS_IMETHODIMP
    2248             : nsHttpHandler::GetUserAgent(nsACString &value)
    2249           0 : {
    2250           0 :     value = UserAgent();
    2251             :     return NS_OK;
    2252             : }
    2253             : 
    2254           0 : NS_IMETHODIMP
    2255             : nsHttpHandler::GetAppName(nsACString &value)
    2256           0 : {
    2257           0 :     value = mLegacyAppName;
    2258             :     return NS_OK;
    2259             : }
    2260             : 
    2261           1 : NS_IMETHODIMP
    2262             : nsHttpHandler::GetAppVersion(nsACString &value)
    2263           0 : {
    2264           1 :     value = mLegacyAppVersion;
    2265             :     return NS_OK;
    2266             : }
    2267             : 
    2268           1 : NS_IMETHODIMP
    2269             : nsHttpHandler::GetPlatform(nsACString &value)
    2270           0 : {
    2271           1 :     value = mPlatform;
    2272             :     return NS_OK;
    2273             : }
    2274             : 
    2275           2 : NS_IMETHODIMP
    2276             : nsHttpHandler::GetOscpu(nsACString &value)
    2277           0 : {
    2278           2 :     value = mOscpu;
    2279             :     return NS_OK;
    2280             : }
    2281             : 
    2282           0 : NS_IMETHODIMP
    2283             : nsHttpHandler::GetMisc(nsACString &value)
    2284           0 : {
    2285           0 :     value = mMisc;
    2286             :     return NS_OK;
    2287             : }
    2288             : 
    2289             : //-----------------------------------------------------------------------------
    2290             : // nsHttpHandler::nsIObserver
    2291             : //-----------------------------------------------------------------------------
    2292             : 
    2293             : static bool CanEnableSpeculativeConnect(); // forward declaration
    2294             : 
    2295           2 : NS_IMETHODIMP
    2296             : nsHttpHandler::Observe(nsISupports *subject,
    2297             :                        const char *topic,
    2298             :                        const char16_t *data)
    2299           0 : {
    2300           2 :     MOZ_ASSERT(NS_IsMainThread());
    2301             :     LOG(("nsHttpHandler::Observe [topic=\"%s\"]\n", topic));
    2302             : 
    2303           0 :     nsresult rv;
    2304           0 :     if (!strcmp(topic, NS_PREFBRANCH_PREFCHANGE_TOPIC_ID)) {
    2305           0 :         nsCOMPtr<nsIPrefBranch> prefBranch = do_QueryInterface(subject);
    2306           0 :         if (prefBranch)
    2307           0 :             PrefsChanged(prefBranch, NS_ConvertUTF16toUTF8(data).get());
    2308           2 :     } else if (!strcmp(topic, "profile-change-net-teardown") ||
    2309             :                !strcmp(topic, NS_XPCOM_SHUTDOWN_OBSERVER_ID) ) {
    2310           0 : 
    2311             :         mHandlerActive = false;
    2312             : 
    2313           0 :         // clear cache of all authentication credentials.
    2314           0 :         Unused << mAuthCache.ClearAll();
    2315           0 :         Unused << mPrivateAuthCache.ClearAll();
    2316           0 :         if (mWifiTickler)
    2317             :             mWifiTickler->Cancel();
    2318             : 
    2319           0 :         // Inform nsIOService that network is tearing down.
    2320             :         gIOService->SetHttpHandlerAlreadyShutingDown();
    2321           0 : 
    2322             :         ShutdownConnectionManager();
    2323             : 
    2324             :         // need to reset the session start time since cache validation may
    2325           0 :         // depend on this value.
    2326             :         mSessionStartTime = NowInSeconds();
    2327           0 : 
    2328           0 :         if (!mDoNotTrackEnabled) {
    2329             :             Telemetry::Accumulate(Telemetry::DNT_USAGE, 2);
    2330           0 :         } else {
    2331             :             Telemetry::Accumulate(Telemetry::DNT_USAGE, 1);
    2332             :         }
    2333           0 : 
    2334           0 :         if (UseFastOpen()) {
    2335           0 :             Telemetry::Accumulate(Telemetry::TCP_FAST_OPEN_STATUS, 0);
    2336           0 :         } else if (!mFastOpenSupported) {
    2337           0 :             Telemetry::Accumulate(Telemetry::TCP_FAST_OPEN_STATUS, 1);
    2338           0 :         } else if (!mUseFastOpen) {
    2339           0 :             Telemetry::Accumulate(Telemetry::TCP_FAST_OPEN_STATUS, 2);
    2340           0 :         } else if (mFastOpenConsecutiveFailureCounter >= mFastOpenConsecutiveFailureLimit) {
    2341             :             Telemetry::Accumulate(Telemetry::TCP_FAST_OPEN_STATUS, 3);
    2342           0 :         } else {
    2343             :             Telemetry::Accumulate(Telemetry::TCP_FAST_OPEN_STATUS, 4);
    2344           2 :         }
    2345             :     } else if (!strcmp(topic, "profile-change-net-restore")) {
    2346           0 :         // initialize connection manager
    2347           0 :         rv = InitConnectionMgr();
    2348           0 :         MOZ_ASSERT(NS_SUCCEEDED(rv));
    2349           0 :     } else if (!strcmp(topic, "net:clear-active-logins")) {
    2350           0 :         Unused << mAuthCache.ClearAll();
    2351           0 :         Unused << mPrivateAuthCache.ClearAll();
    2352           0 :     } else if (!strcmp(topic, "net:cancel-all-connections")) {
    2353           0 :         if (mConnMgr) {
    2354             :             mConnMgr->AbortAndCloseAllConnections(0, nullptr);
    2355           0 :         }
    2356           0 :     } else if (!strcmp(topic, "net:prune-dead-connections")) {
    2357           0 :         if (mConnMgr) {
    2358           0 :             rv = mConnMgr->PruneDeadConnections();
    2359           0 :             if (NS_FAILED(rv)) {
    2360             :                 LOG(("    PruneDeadConnections failed (%08x)\n",
    2361             :                      static_cast<uint32_t>(rv)));
    2362             :             }
    2363           1 :         }
    2364           0 :     } else if (!strcmp(topic, "net:prune-all-connections")) {
    2365           0 :         if (mConnMgr) {
    2366           0 :             rv = mConnMgr->DoShiftReloadConnectionCleanup(nullptr);
    2367           0 :             if (NS_FAILED(rv)) {
    2368             :                 LOG(("    DoShiftReloadConnectionCleanup failed (%08x)\n",
    2369             :                      static_cast<uint32_t>(rv)));
    2370           0 :             }
    2371           0 :             rv = mConnMgr->PruneDeadConnections();
    2372           0 :             if (NS_FAILED(rv)) {
    2373             :                 LOG(("    PruneDeadConnections failed (%08x)\n",
    2374             :                      static_cast<uint32_t>(rv)));
    2375             :             }
    2376             :         }
    2377             : #if 0
    2378             :     } else if (!strcmp(topic, "net:failed-to-process-uri-content")) {
    2379             :          // nop right now - we used to cancel h1 pipelines based on this,
    2380             :          // but those are no longer implemented
    2381             :          nsCOMPtr<nsIURI> uri = do_QueryInterface(subject);
    2382           0 : #endif
    2383           0 :     } else if (!strcmp(topic, "last-pb-context-exited")) {
    2384           0 :         Unused << mPrivateAuthCache.ClearAll();
    2385           0 :         if (mConnMgr) {
    2386             :             mConnMgr->ClearAltServiceMappings();
    2387           0 :         }
    2388           0 :     } else if (!strcmp(topic, "browser:purge-session-history")) {
    2389           0 :         if (mConnMgr) {
    2390           0 :             if (gSocketTransportService) {
    2391             :               nsCOMPtr<nsIRunnable> event = NewRunnableMethod(
    2392             :                 "net::nsHttpConnectionMgr::ClearConnectionHistory",
    2393           0 :                 mConnMgr,
    2394           0 :                 &nsHttpConnectionMgr::ClearConnectionHistory);
    2395             :               gSocketTransportService->Dispatch(event, NS_DISPATCH_NORMAL);
    2396           0 :             }
    2397             :             mConnMgr->ClearAltServiceMappings();
    2398           0 :         }
    2399           0 :     } else if (!strcmp(topic, NS_NETWORK_LINK_TOPIC)) {
    2400           0 :         nsAutoCString converted = NS_ConvertUTF16toUTF8(data);
    2401           0 :         if (!strcmp(converted.get(), NS_NETWORK_LINK_DATA_CHANGED)) {
    2402           0 :             if (mConnMgr) {
    2403           0 :                 rv = mConnMgr->PruneDeadConnections();
    2404           0 :                 if (NS_FAILED(rv)) {
    2405             :                     LOG(("    PruneDeadConnections failed (%08x)\n",
    2406             :                          static_cast<uint32_t>(rv)));
    2407           0 :                 }
    2408           0 :                 rv = mConnMgr->VerifyTraffic();
    2409           0 :                 if (NS_FAILED(rv)) {
    2410             :                     LOG(("    VerifyTraffic failed (%08x)\n",
    2411             :                          static_cast<uint32_t>(rv)));
    2412             :                 }
    2413             :             }
    2414           2 :         }
    2415             :     } else if (!strcmp(topic, "application-background")) {
    2416             :         // going to the background on android means we should close
    2417           0 :         // down idle connections for power conservation
    2418           0 :         if (mConnMgr) {
    2419           0 :             rv = mConnMgr->DoShiftReloadConnectionCleanup(nullptr);
    2420           0 :             if (NS_FAILED(rv)) {
    2421             :                 LOG(("    DoShiftReloadConnectionCleanup failed (%08x)\n",
    2422             :                      static_cast<uint32_t>(rv)));
    2423             :             }
    2424           0 :         }
    2425           0 :     } else if (!strcmp(topic, "net:current-toplevel-outer-content-windowid")) {
    2426           2 :         nsCOMPtr<nsISupportsPRUint64> wrapper = do_QueryInterface(subject);
    2427             :         MOZ_RELEASE_ASSERT(wrapper);
    2428           0 : 
    2429           0 :         uint64_t windowId = 0;
    2430           2 :         wrapper->GetData(&windowId);
    2431             :         MOZ_ASSERT(windowId);
    2432             : 
    2433           0 :         static uint64_t sCurrentTopLevelOuterContentWindowId = 0;
    2434           0 :         if (sCurrentTopLevelOuterContentWindowId != windowId) {
    2435           0 :             sCurrentTopLevelOuterContentWindowId = windowId;
    2436           0 :             if (mConnMgr) {
    2437           2 :                 mConnMgr->UpdateCurrentTopLevelOuterContentWindowId(
    2438             :                     sCurrentTopLevelOuterContentWindowId);
    2439             :             }
    2440           0 :         }
    2441           0 :     } else if (!strcmp(topic, "captive-portal-login") ||
    2442             :                !strcmp(topic, "captive-portal-login-success")) {
    2443             :          // We have detected a captive portal and we will reset the Fast Open
    2444           0 :          // failure counter.
    2445           0 :          ResetFastOpenConsecutiveFailureCounter();
    2446             :     } else if (!strcmp(topic, "psm:user-certificate-added")) {
    2447             :         // A user certificate has just been added.
    2448           0 :         // We should immediately disable speculative connect
    2449           0 :         mSpeculativeConnectEnabled = false;
    2450             :     } else if (!strcmp(topic, "psm:user-certificate-deleted")) {
    2451             :         // If a user certificate has been removed, we need to check if there
    2452           0 :         // are others installed
    2453           0 :         mSpeculativeConnectEnabled = CanEnableSpeculativeConnect();
    2454             :     } else if (!strcmp(topic, "intl:app-locales-changed")) {
    2455           0 :         // If the locale changed, there's a chance the accept language did too
    2456             :         mAcceptLanguagesIsDirty = true;
    2457             :     }
    2458           2 : 
    2459             :     return NS_OK;
    2460             : }
    2461             : 
    2462             : // nsISpeculativeConnect
    2463             : 
    2464           0 : static bool
    2465             : CanEnableSpeculativeConnect()
    2466           0 : {
    2467             :   MOZ_ASSERT(NS_IsMainThread(), "Main thread only");
    2468           0 : 
    2469           0 :   nsCOMPtr<nsINSSComponent> component(do_GetService(PSM_COMPONENT_CONTRACTID));
    2470             :   if (!component) {
    2471             :     return false;
    2472             :   }
    2473             : 
    2474             :   // Check if any 3rd party PKCS#11 module are installed, as they may produce
    2475           0 :   // client certificates
    2476           0 :   bool activeSmartCards = false;
    2477           0 :   nsresult rv = component->HasActiveSmartCards(activeSmartCards);
    2478             :   if (NS_FAILED(rv) || activeSmartCards) {
    2479             :     return false;
    2480             :   }
    2481             : 
    2482             :   // If there are any client certificates installed, we can't enable speculative
    2483           0 :   // connect, as it may pop up the certificate chooser at any time.
    2484           0 :   bool hasUserCerts = false;
    2485           0 :   rv = component->HasUserCertsInstalled(hasUserCerts);
    2486             :   if (NS_FAILED(rv) || hasUserCerts) {
    2487             :     return false;
    2488             :   }
    2489           0 : 
    2490             :   return true;
    2491             : }
    2492             : 
    2493           0 : nsresult
    2494             : nsHttpHandler::SpeculativeConnectInternal(nsIURI *aURI,
    2495             :                                           nsIPrincipal *aPrincipal,
    2496             :                                           nsIInterfaceRequestor *aCallbacks,
    2497             :                                           bool anonymous)
    2498           0 : {
    2499           0 :     if (IsNeckoChild()) {
    2500           0 :         ipc::URIParams params;
    2501           0 :         SerializeURI(aURI, params);
    2502           0 :         gNeckoChild->SendSpeculativeConnect(params,
    2503           0 :                                             IPC::Principal(aPrincipal),
    2504             :                                             anonymous);
    2505             :         return NS_OK;
    2506             :     }
    2507           0 : 
    2508             :     if (!mHandlerActive)
    2509             :         return NS_OK;
    2510           0 : 
    2511           0 :     MOZ_ASSERT(NS_IsMainThread());
    2512           0 :     nsCOMPtr<nsIObserverService> obsService = services::GetObserverService();
    2513             :     if (mDebugObservations && obsService) {
    2514             :         // this is basically used for test coverage of an otherwise 'hintable'
    2515           0 :         // feature
    2516           0 :         obsService->NotifyObservers(nullptr, "speculative-connect-request",
    2517           0 :                                     nullptr);
    2518           0 :         for (auto* cp : dom::ContentParent::AllProcesses(dom::ContentParent::eLive)) {
    2519           0 :             PNeckoParent* neckoParent = SingleManagedOrNull(cp->ManagedPNeckoParent());
    2520             :             if (!neckoParent) {
    2521             :                 continue;
    2522           0 :             }
    2523             :             Unused << neckoParent->SendSpeculativeConnectRequest();
    2524             :         }
    2525             :     }
    2526           0 : 
    2527           0 :     nsISiteSecurityService* sss = gHttpHandler->GetSSService();
    2528           0 :     bool isStsHost = false;
    2529             :     if (!sss)
    2530             :         return NS_OK;
    2531           0 : 
    2532           0 :     nsCOMPtr<nsILoadContext> loadContext = do_GetInterface(aCallbacks);
    2533           0 :     uint32_t flags = 0;
    2534           0 :     if (loadContext && loadContext->UsePrivateBrowsing())
    2535             :         flags |= nsISocketProvider::NO_PERMANENT_STORAGE;
    2536           0 : 
    2537             :     OriginAttributes originAttributes;
    2538             :     // If the principal is given, we use the originAttributes from this
    2539             :     // principal. Otherwise, we use the originAttributes from the
    2540           0 :     // loadContext.
    2541           0 :     if (aPrincipal) {
    2542           0 :         originAttributes = aPrincipal->OriginAttributesRef();
    2543           0 :     } else if (loadContext) {
    2544             :         loadContext->GetOriginAttributes(originAttributes);
    2545             :     }
    2546           0 : 
    2547           0 :     nsCOMPtr<nsIURI> clone;
    2548             :     if (NS_SUCCEEDED(sss->IsSecureURI(nsISiteSecurityService::HEADER_HSTS,
    2549           0 :                                       aURI, flags, originAttributes,
    2550             :                                       nullptr, nullptr, &isStsHost)) &&
    2551           0 :                                       isStsHost) {
    2552             :         if (NS_SUCCEEDED(NS_GetSecureUpgradedURI(aURI,
    2553           0 :                                                  getter_AddRefs(clone)))) {
    2554             :             aURI = clone.get();
    2555             :             // (NOTE: We better make sure |clone| stays alive until the end
    2556             :             // of the function now, since our aURI arg now points to it!)
    2557             :         }
    2558             :     }
    2559           0 : 
    2560           0 :     nsAutoCString scheme;
    2561           0 :     nsresult rv = aURI->GetScheme(scheme);
    2562             :     if (NS_FAILED(rv))
    2563             :         return rv;
    2564             : 
    2565             :     // If this is HTTPS, make sure PSM is initialized as the channel
    2566           0 :     // creation path may have been bypassed
    2567           0 :     if (scheme.EqualsLiteral("https")) {
    2568             :         if (!IsNeckoChild()) {
    2569           0 :             // make sure PSM gets initialized on the main thread.
    2570             :             net_EnsurePSMInit();
    2571             :         }
    2572             :     }
    2573           0 :     // Ensure that this is HTTP or HTTPS, otherwise we don't do preconnect here
    2574             :     else if (!scheme.EqualsLiteral("http"))
    2575             :         return NS_ERROR_UNEXPECTED;
    2576             : 
    2577           0 :     // Construct connection info object
    2578           0 :     bool usingSSL = false;
    2579           0 :     rv = aURI->SchemeIs("https", &usingSSL);
    2580             :     if (NS_FAILED(rv))
    2581             :         return rv;
    2582             : 
    2583           0 :     static bool sCheckedIfSpeculativeEnabled = false;
    2584           0 :     if (!sCheckedIfSpeculativeEnabled) {
    2585           0 :         sCheckedIfSpeculativeEnabled = true;
    2586             :         mSpeculativeConnectEnabled = CanEnableSpeculativeConnect();
    2587             :     }
    2588           0 : 
    2589             :     if (usingSSL && !mSpeculativeConnectEnabled) {
    2590             :         return NS_ERROR_UNEXPECTED;
    2591             :     }
    2592           0 : 
    2593           0 :     nsAutoCString host;
    2594           0 :     rv = aURI->GetAsciiHost(host);
    2595             :     if (NS_FAILED(rv))
    2596             :         return rv;
    2597           0 : 
    2598           0 :     int32_t port = -1;
    2599           0 :     rv = aURI->GetPort(&port);
    2600             :     if (NS_FAILED(rv))
    2601             :         return rv;
    2602           0 : 
    2603           0 :     nsAutoCString username;
    2604             :     aURI->GetUsername(username);
    2605             : 
    2606           0 :     auto *ci =
    2607           0 :         new nsHttpConnectionInfo(host, port, EmptyCString(), username, nullptr,
    2608           0 :                                  originAttributes, usingSSL);
    2609             :     ci->SetAnonymous(anonymous);
    2610           0 : 
    2611             :     return SpeculativeConnect(ci, aCallbacks);
    2612             : }
    2613             : 
    2614           0 : NS_IMETHODIMP
    2615             : nsHttpHandler::SpeculativeConnect(nsIURI *aURI,
    2616             :                                   nsIInterfaceRequestor *aCallbacks)
    2617           0 : {
    2618             :     return SpeculativeConnectInternal(aURI, nullptr, aCallbacks, false);
    2619             : }
    2620             : 
    2621           0 : NS_IMETHODIMP
    2622             : nsHttpHandler::SpeculativeConnect2(nsIURI *aURI,
    2623             :                                    nsIPrincipal *aPrincipal,
    2624             :                                    nsIInterfaceRequestor *aCallbacks)
    2625           0 : {
    2626             :     return SpeculativeConnectInternal(aURI, aPrincipal, aCallbacks, false);
    2627             : }
    2628             : 
    2629           0 : NS_IMETHODIMP
    2630             : nsHttpHandler::SpeculativeAnonymousConnect(nsIURI *aURI,
    2631             :                                            nsIInterfaceRequestor *aCallbacks)
    2632           0 : {
    2633             :     return SpeculativeConnectInternal(aURI, nullptr, aCallbacks, true);
    2634             : }
    2635             : 
    2636           0 : NS_IMETHODIMP
    2637             : nsHttpHandler::SpeculativeAnonymousConnect2(nsIURI *aURI,
    2638             :                                             nsIPrincipal *aPrincipal,
    2639             :                                             nsIInterfaceRequestor *aCallbacks)
    2640           0 : {
    2641             :     return SpeculativeConnectInternal(aURI, aPrincipal, aCallbacks, true);
    2642             : }
    2643             : 
    2644           3 : void
    2645             : nsHttpHandler::TickleWifi(nsIInterfaceRequestor *cb)
    2646           6 : {
    2647           3 :     if (!cb || !mWifiTickler)
    2648             :         return;
    2649             : 
    2650             :     // If B2G requires a similar mechanism nsINetworkManager, currently only avail
    2651             :     // on B2G, contains the necessary information on wifi and gateway
    2652           0 : 
    2653           0 :     nsCOMPtr<nsIDOMWindow> domWindow = do_GetInterface(cb);
    2654           0 :     nsCOMPtr<nsPIDOMWindowOuter> piWindow = do_QueryInterface(domWindow);
    2655           0 :     if (!piWindow)
    2656             :         return;
    2657           0 : 
    2658           0 :     RefPtr<dom::Navigator> navigator = piWindow->GetNavigator();
    2659           0 :     if (!navigator)
    2660             :         return;
    2661             : 
    2662           0 :     nsCOMPtr<nsINetworkProperties> networkProperties =
    2663           0 :         navigator->GetNetworkProperties();
    2664           0 :     if (!networkProperties)
    2665             :         return;
    2666             : 
    2667             :     uint32_t gwAddress;
    2668             :     bool isWifi;
    2669             :     nsresult rv;
    2670           0 : 
    2671           0 :     rv = networkProperties->GetDhcpGateway(&gwAddress);
    2672           0 :     if (NS_SUCCEEDED(rv))
    2673           0 :         rv = networkProperties->GetIsWifi(&isWifi);
    2674             :     if (NS_FAILED(rv))
    2675             :         return;
    2676           0 : 
    2677             :     if (!gwAddress || !isWifi)
    2678             :         return;
    2679           0 : 
    2680           0 :     mWifiTickler->SetIPV4Address(gwAddress);
    2681             :     mWifiTickler->Tickle();
    2682             : }
    2683             : 
    2684             : //-----------------------------------------------------------------------------
    2685             : // nsHttpsHandler implementation
    2686             : //-----------------------------------------------------------------------------
    2687        2684 : 
    2688             : NS_IMPL_ISUPPORTS(nsHttpsHandler,
    2689             :                   nsIHttpProtocolHandler,
    2690             :                   nsIProxiedProtocolHandler,
    2691             :                   nsIProtocolHandler,
    2692             :                   nsISupportsWeakReference,
    2693             :                   nsISpeculativeConnect)
    2694             : 
    2695           0 : nsresult
    2696             : nsHttpsHandler::Init()
    2697             : {
    2698           2 :     nsCOMPtr<nsIProtocolHandler> httpHandler(
    2699           1 :             do_GetService(NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "http"));
    2700           1 :     MOZ_ASSERT(httpHandler.get() != nullptr);
    2701             :     return NS_OK;
    2702             : }
    2703             : 
    2704           0 : NS_IMETHODIMP
    2705             : nsHttpsHandler::GetScheme(nsACString &aScheme)
    2706           0 : {
    2707           0 :     aScheme.AssignLiteral("https");
    2708             :     return NS_OK;
    2709             : }
    2710             : 
    2711           1 : NS_IMETHODIMP
    2712             : nsHttpsHandler::GetDefaultPort(int32_t *aPort)
    2713           1 : {
    2714           0 :     *aPort = NS_HTTPS_DEFAULT_PORT;
    2715             :     return NS_OK;
    2716             : }
    2717             : 
    2718         163 : NS_IMETHODIMP
    2719             : nsHttpsHandler::GetProtocolFlags(uint32_t *aProtocolFlags)
    2720         163 : {
    2721           0 :     *aProtocolFlags = NS_HTTP_PROTOCOL_FLAGS | URI_IS_POTENTIALLY_TRUSTWORTHY;
    2722             :     return NS_OK;
    2723             : }
    2724             : 
    2725          87 : NS_IMETHODIMP
    2726             : nsHttpsHandler::NewURI(const nsACString &aSpec,
    2727             :                        const char *aOriginCharset,
    2728             :                        nsIURI *aBaseURI,
    2729             :                        nsIURI **_retval)
    2730           1 : {
    2731             :     return mozilla::net::NewURI(aSpec, aOriginCharset, aBaseURI, NS_HTTPS_DEFAULT_PORT, _retval);
    2732             : }
    2733             : 
    2734           0 : NS_IMETHODIMP
    2735             : nsHttpsHandler::NewChannel2(nsIURI* aURI,
    2736             :                             nsILoadInfo* aLoadInfo,
    2737             :                             nsIChannel** _retval)
    2738           0 : {
    2739           0 :     MOZ_ASSERT(gHttpHandler);
    2740             :     if (!gHttpHandler)
    2741           0 :       return NS_ERROR_UNEXPECTED;
    2742             :     return gHttpHandler->NewChannel2(aURI, aLoadInfo, _retval);
    2743             : }
    2744             : 
    2745           0 : NS_IMETHODIMP
    2746             : nsHttpsHandler::NewChannel(nsIURI *aURI, nsIChannel **_retval)
    2747           0 : {
    2748             :     return NewChannel2(aURI, nullptr, _retval);
    2749             : }
    2750             : 
    2751           0 : NS_IMETHODIMP
    2752             : nsHttpsHandler::AllowPort(int32_t aPort, const char *aScheme, bool *_retval)
    2753             : {
    2754           0 :     // don't override anything.
    2755           0 :     *_retval = false;
    2756             :     return NS_OK;
    2757             : }
    2758             : 
    2759           0 : void
    2760             : nsHttpHandler::ShutdownConnectionManager()
    2761             : {
    2762           0 :     // ensure connection manager is shutdown
    2763           0 :     if (mConnMgr) {
    2764           0 :         nsresult rv = mConnMgr->Shutdown();
    2765           0 :         if (NS_FAILED(rv)) {
    2766             :             LOG(("nsHttpHandler::ShutdownConnectionManager\n"
    2767             :                  "    failed to shutdown connection manager\n"));
    2768             :         }
    2769           0 :     }
    2770             : }
    2771             : 
    2772           0 : nsresult
    2773             : nsHttpHandler::NewChannelId(uint64_t& channelId)
    2774           3 : {
    2775           3 :   MOZ_ASSERT(NS_IsMainThread());
    2776           0 :   channelId = ((static_cast<uint64_t>(mProcessId) << 32) & 0xFFFFFFFF00000000LL) | mNextChannelId++;
    2777             :   return NS_OK;
    2778             : }
    2779             : 
    2780           0 : void
    2781             : nsHttpHandler::NotifyActiveTabLoadOptimization()
    2782           0 : {
    2783           0 :   SetLastActiveTabLoadOptimizationHit(TimeStamp::Now());
    2784             : }
    2785           0 : 
    2786             : TimeStamp const nsHttpHandler::GetLastActiveTabLoadOptimizationHit()
    2787           0 : {
    2788             :   MutexAutoLock lock(mLastActiveTabLoadOptimizationLock);
    2789           0 : 
    2790             :   return mLastActiveTabLoadOptimizationHit;
    2791             : }
    2792             : 
    2793           0 : void
    2794             : nsHttpHandler::SetLastActiveTabLoadOptimizationHit(TimeStamp const &when)
    2795           0 : {
    2796             :   MutexAutoLock lock(mLastActiveTabLoadOptimizationLock);
    2797           0 : 
    2798           0 :   if (mLastActiveTabLoadOptimizationHit.IsNull() ||
    2799           0 :       (!when.IsNull() && mLastActiveTabLoadOptimizationHit < when)) {
    2800             :     mLastActiveTabLoadOptimizationHit = when;
    2801           0 :   }
    2802             : }
    2803             : 
    2804           0 : bool
    2805             : nsHttpHandler::IsBeforeLastActiveTabLoadOptimization(TimeStamp const &when)
    2806           0 : {
    2807             :   MutexAutoLock lock(mLastActiveTabLoadOptimizationLock);
    2808           0 : 
    2809           0 :   return !mLastActiveTabLoadOptimizationHit.IsNull() &&
    2810             :          when <= mLastActiveTabLoadOptimizationHit;
    2811             : }
    2812             : 
    2813             : } // namespace net
    2814             : } // namespace mozilla

Generated by: LCOV version 1.13-14-ga5dd952