nsHttpHandler.h (35355B)
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* This Source Code Form is subject to the terms of the Mozilla Public 3 * License, v. 2.0. If a copy of the MPL was not distributed with this 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 5 6 #ifndef nsHttpHandler_h__ 7 #define nsHttpHandler_h__ 8 9 #include <functional> 10 11 #include "nsHttp.h" 12 #include "nsHttpAuthCache.h" 13 #include "nsHttpConnectionMgr.h" 14 #include "AlternateServices.h" 15 #include "ASpdySession.h" 16 #include "HttpTrafficAnalyzer.h" 17 18 #include "mozilla/Mutex.h" 19 #include "mozilla/StaticPtr.h" 20 #include "mozilla/TimeStamp.h" 21 #include "nsString.h" 22 #include "nsCOMPtr.h" 23 #include "nsWeakReference.h" 24 #include "mozilla/net/Dictionary.h" 25 26 #include "nsIHttpProtocolHandler.h" 27 #include "nsIObserver.h" 28 #include "nsISpeculativeConnect.h" 29 #include "nsTHashMap.h" 30 #include "nsTHashSet.h" 31 32 #ifdef DEBUG 33 # include "nsIOService.h" 34 #endif 35 36 // XXX These includes can be replaced by forward declarations by moving the On* 37 // method implementations to the cpp file 38 #include "nsIChannel.h" 39 #include "nsIHttpChannel.h" 40 #include "nsSocketTransportService2.h" 41 42 class nsIHttpActivityDistributor; 43 class nsIHttpUpgradeListener; 44 class nsIPrefBranch; 45 class nsICancelable; 46 class nsICookieService; 47 class nsIIOService; 48 class nsIRequestContextService; 49 class nsISiteSecurityService; 50 class nsIStreamConverterService; 51 52 namespace mozilla::net { 53 54 class ATokenBucketEvent; 55 class EventTokenBucket; 56 class Tickler; 57 class nsHttpConnection; 58 class nsHttpConnectionInfo; 59 class HttpBaseChannel; 60 class HttpHandlerInitArgs; 61 class HttpTransactionShell; 62 class AltSvcMapping; 63 class DNSUtils; 64 class TRRServiceChannel; 65 class SocketProcessChild; 66 67 /* 68 * FRAMECHECK_LAX - no check 69 * FRAMECHECK_BARELY - allows: 70 * 1) that chunk-encoding does not have the last 0-size 71 * chunk. So, if a chunked-encoded transfer ends on exactly 72 * a chunk boundary we consider that fine. This will allows 73 * us to accept buggy servers that do not send the last 74 * chunk. It will make us not detect a certain amount of 75 * cut-offs. 76 * 2) When receiving a gzipped response, we consider a 77 * gzip stream that doesn't end fine according to the gzip 78 * decompressing state machine to be a partial transfer. 79 * If a gzipped transfer ends fine according to the 80 * decompressor, we do not check for size unalignments. 81 * This allows to allow HTTP gzipped responses where the 82 * Content-Length is not the same as the actual contents. 83 * 3) When receiving HTTP that isn't 84 * content-encoded/compressed (like in case 2) and not 85 * chunked (like in case 1), perform the size comparison 86 * between Content-Length: and the actual size received 87 * and consider a mismatch to mean a 88 * NS_ERROR_NET_PARTIAL_TRANSFER error. 89 * FRAMECHECK_STRICT_CHUNKED - This is the same as FRAMECHECK_BARELY only we 90 * enforce that the last 0-size chunk is received 91 * in case 1). 92 * FRAMECHECK_STRICT - we also do not allow case 2) and 3) from 93 * FRAMECHECK_BARELY. 94 */ 95 enum FrameCheckLevel { 96 FRAMECHECK_LAX, 97 FRAMECHECK_BARELY, 98 FRAMECHECK_STRICT_CHUNKED, 99 FRAMECHECK_STRICT 100 }; 101 102 //----------------------------------------------------------------------------- 103 // nsHttpHandler - protocol handler for HTTP and HTTPS 104 //----------------------------------------------------------------------------- 105 106 class nsHttpHandler final : public nsIHttpProtocolHandler, 107 public nsIObserver, 108 public nsSupportsWeakReference, 109 public nsISpeculativeConnect { 110 public: 111 NS_DECL_THREADSAFE_ISUPPORTS 112 NS_DECL_NSIPROTOCOLHANDLER 113 NS_DECL_NSIPROXIEDPROTOCOLHANDLER 114 NS_DECL_NSIHTTPPROTOCOLHANDLER 115 NS_DECL_NSIOBSERVER 116 NS_DECL_NSISPECULATIVECONNECT 117 118 static already_AddRefed<nsHttpHandler> GetInstance(); 119 120 [[nodiscard]] nsresult AddAcceptAndDictionaryHeaders( 121 nsIURI* aURI, ExtContentPolicyType aType, nsHttpRequestHead* aRequest, 122 bool aSecure, nsHttpChannel* aChan, void (*aSuspend)(nsHttpChannel*), 123 const std::function<bool(bool, DictionaryCacheEntry*)>& aCallback); 124 [[nodiscard]] nsresult AddStandardRequestHeaders( 125 nsHttpRequestHead*, nsIURI* aURI, bool aIsHTTPS, 126 ExtContentPolicyType aContentPolicyType, bool aShouldResistFingerprinting, 127 const nsCString& aLanguageOverride); 128 [[nodiscard]] nsresult AddConnectionHeader(nsHttpRequestHead*, uint32_t caps); 129 bool IsAcceptableEncoding(const char* encoding, bool isSecure); 130 131 const nsCString& UserAgent(bool aShouldResistFingerprinting); 132 133 enum HttpVersion HttpVersion() { return mHttpVersion; } 134 enum HttpVersion ProxyHttpVersion() { return mProxyHttpVersion; } 135 uint8_t RedirectionLimit() { return mRedirectionLimit; } 136 PRIntervalTime IdleTimeout() { return mIdleTimeout; } 137 PRIntervalTime SpdyTimeout() { return mSpdyTimeout; } 138 PRIntervalTime ResponseTimeout() { 139 return mResponseTimeoutEnabled ? mResponseTimeout : 0; 140 } 141 PRIntervalTime ResponseTimeoutEnabled() { return mResponseTimeoutEnabled; } 142 uint32_t NetworkChangedTimeout() { return mNetworkChangedTimeout; } 143 uint16_t MaxRequestAttempts() { return mMaxRequestAttempts; } 144 const nsCString& DefaultSocketType() { return mDefaultSocketType; } 145 uint8_t GetQoSBits() { return mQoSBits; } 146 uint16_t GetIdleSynTimeout() { return mIdleSynTimeout; } 147 uint16_t GetFallbackSynTimeout() { return mFallbackSynTimeout; } 148 bool FastFallbackToIPv4() { return mFastFallbackToIPv4; } 149 uint32_t MaxSocketCount(); 150 bool EnforceAssocReq() { return mEnforceAssocReq; } 151 152 bool IsPersistentHttpsCachingEnabled() { 153 return mEnablePersistentHttpsCaching; 154 } 155 156 uint32_t SpdySendingChunkSize() { return mSpdySendingChunkSize; } 157 uint32_t SpdySendBufferSize() { return mSpdySendBufferSize; } 158 uint32_t SpdyPushAllowance() { return mSpdyPushAllowance; } 159 uint32_t SpdyPullAllowance() { return mSpdyPullAllowance; } 160 uint32_t DefaultSpdyConcurrent() { return mDefaultSpdyConcurrent; } 161 PRIntervalTime SpdyPingThreshold() { return mSpdyPingThreshold; } 162 PRIntervalTime SpdyPingTimeout() { return mSpdyPingTimeout; } 163 bool AllowAltSvc() { return mEnableAltSvc; } 164 bool AllowAltSvcOE() { return mEnableAltSvcOE; } 165 uint32_t ConnectTimeout() { return mConnectTimeout; } 166 uint32_t TLSHandshakeTimeout() { return mTLSHandshakeTimeout; } 167 uint32_t ParallelSpeculativeConnectLimit() { 168 return mParallelSpeculativeConnectLimit; 169 } 170 bool CriticalRequestPrioritization() { 171 return mCriticalRequestPrioritization; 172 } 173 174 uint32_t MaxConnectionsPerOrigin() { 175 return mMaxPersistentConnectionsPerServer; 176 } 177 bool UseRequestTokenBucket() { return mRequestTokenBucketEnabled; } 178 uint16_t RequestTokenBucketMinParallelism() { 179 return mRequestTokenBucketMinParallelism; 180 } 181 uint32_t RequestTokenBucketHz() { return mRequestTokenBucketHz; } 182 uint32_t RequestTokenBucketBurst() { return mRequestTokenBucketBurst; } 183 184 bool PromptTempRedirect() { return mPromptTempRedirect; } 185 bool IsUrgentStartEnabled() { return mUrgentStartEnabled; } 186 bool IsTailBlockingEnabled() { return mTailBlockingEnabled; } 187 uint32_t TailBlockingDelayQuantum(bool aAfterDOMContentLoaded) { 188 return aAfterDOMContentLoaded ? mTailDelayQuantumAfterDCL 189 : mTailDelayQuantum; 190 } 191 uint32_t TailBlockingDelayMax() { return mTailDelayMax; } 192 uint32_t TailBlockingTotalMax() { return mTailTotalMax; } 193 194 uint32_t ThrottlingReadLimit() { return 0; } 195 int32_t SendWindowSize() { return mSendWindowSize * 1024; } 196 197 // TCP Keepalive configuration values. 198 199 // Returns true if TCP keepalive should be enabled for short-lived conns. 200 bool TCPKeepaliveEnabledForShortLivedConns() { 201 return mTCPKeepaliveShortLivedEnabled; 202 } 203 // Return time (secs) that a connection is consider short lived (for TCP 204 // keepalive purposes). After this time, the connection is long-lived. 205 int32_t GetTCPKeepaliveShortLivedTime() { 206 return mTCPKeepaliveShortLivedTimeS; 207 } 208 // Returns time (secs) before first TCP keepalive probes should be sent; 209 // same time used between successful keepalive probes. 210 int32_t GetTCPKeepaliveShortLivedIdleTime() { 211 return mTCPKeepaliveShortLivedIdleTimeS; 212 } 213 214 // Returns true if TCP keepalive should be enabled for long-lived conns. 215 bool TCPKeepaliveEnabledForLongLivedConns() { 216 return mTCPKeepaliveLongLivedEnabled; 217 } 218 // Returns time (secs) before first TCP keepalive probes should be sent; 219 // same time used between successful keepalive probes. 220 int32_t GetTCPKeepaliveLongLivedIdleTime() { 221 return mTCPKeepaliveLongLivedIdleTimeS; 222 } 223 224 // returns the HTTP framing check level preference, as controlled with 225 // network.http.enforce-framing.http1 and network.http.enforce-framing.soft 226 FrameCheckLevel GetEnforceH1Framing() { return mEnforceH1Framing; } 227 228 nsHttpAuthCache* AuthCache(bool aPrivate) { 229 return aPrivate ? mPrivateAuthCache : mAuthCache; 230 } 231 nsHttpConnectionMgr* ConnMgr() { 232 MOZ_ASSERT_IF(nsIOService::UseSocketProcess(), XRE_IsSocketProcess()); 233 return mConnMgr->AsHttpConnectionMgr(); 234 } 235 236 AltSvcCache* AltServiceCache() const { 237 MOZ_ASSERT(XRE_IsParentProcess()); 238 return mAltSvcCache.get(); 239 } 240 241 void ClearHostMapping(nsHttpConnectionInfo* aConnInfo); 242 243 // cache support 244 uint32_t GenerateUniqueID() { return ++mLastUniqueID; } 245 uint32_t SessionStartTime() { return mSessionStartTime; } 246 247 void GenerateIdempotencyKeyForPost(const uint32_t aPostId, 248 nsILoadInfo* aLoadInfo, 249 nsACString& aOutKey); 250 251 // 252 // Connection management methods: 253 // 254 // - the handler only owns idle connections; it does not own active 255 // connections. 256 // 257 // - the handler keeps a count of active connections to enforce the 258 // steady-state max-connections pref. 259 // 260 261 // Called to kick-off a new transaction, by default the transaction 262 // will be put on the pending transaction queue if it cannot be 263 // initiated at this time. Callable from any thread. 264 [[nodiscard]] nsresult InitiateTransaction(HttpTransactionShell* trans, 265 int32_t priority); 266 267 // This function is also called to kick-off a new transaction. But the new 268 // transaction will take a sticky connection from |transWithStickyConn| 269 // and reuse it. 270 [[nodiscard]] nsresult InitiateTransactionWithStickyConn( 271 HttpTransactionShell* trans, int32_t priority, 272 HttpTransactionShell* transWithStickyConn); 273 274 // Called to change the priority of an existing transaction that has 275 // already been initiated. 276 [[nodiscard]] nsresult RescheduleTransaction(HttpTransactionShell* trans, 277 int32_t priority); 278 279 void UpdateClassOfServiceOnTransaction(HttpTransactionShell* trans, 280 const ClassOfService& classOfService); 281 282 // Called to cancel a transaction, which may or may not be assigned to 283 // a connection. Callable from any thread. 284 [[nodiscard]] nsresult CancelTransaction(HttpTransactionShell* trans, 285 nsresult reason); 286 287 // Called when a connection is done processing a transaction. Callable 288 // from any thread. 289 [[nodiscard]] nsresult ReclaimConnection(HttpConnectionBase* conn) { 290 return mConnMgr->ReclaimConnection(conn); 291 } 292 293 [[nodiscard]] nsresult ProcessPendingQ(nsHttpConnectionInfo* cinfo) { 294 return mConnMgr->ProcessPendingQ(cinfo); 295 } 296 297 [[nodiscard]] nsresult ProcessPendingQ() { 298 return mConnMgr->ProcessPendingQ(); 299 } 300 301 [[nodiscard]] nsresult GetSocketThreadTarget(nsIEventTarget** target) { 302 return mConnMgr->GetSocketThreadTarget(target); 303 } 304 305 [[nodiscard]] nsresult MaybeSpeculativeConnectWithHTTPSRR( 306 nsHttpConnectionInfo* ci, nsIInterfaceRequestor* callbacks, uint32_t caps, 307 bool aFetchHTTPSRR) { 308 TickleWifi(callbacks); 309 RefPtr<nsHttpConnectionInfo> clone = ci->Clone(); 310 return mConnMgr->SpeculativeConnect(clone, callbacks, caps, nullptr, 311 aFetchHTTPSRR); 312 } 313 314 [[nodiscard]] nsresult SpeculativeConnect(nsHttpConnectionInfo* ci, 315 nsIInterfaceRequestor* callbacks, 316 uint32_t caps, 317 SpeculativeTransaction* aTrans) { 318 RefPtr<nsHttpConnectionInfo> clone = ci->Clone(); 319 return mConnMgr->SpeculativeConnect(clone, callbacks, caps, aTrans); 320 } 321 322 // Alternate Services Maps are main thread only 323 void UpdateAltServiceMapping(AltSvcMapping* map, nsProxyInfo* proxyInfo, 324 nsIInterfaceRequestor* callbacks, uint32_t caps, 325 const OriginAttributes& originAttributes) { 326 mAltSvcCache->UpdateAltServiceMapping(map, proxyInfo, callbacks, caps, 327 originAttributes); 328 } 329 330 void UpdateAltServiceMappingWithoutValidation( 331 AltSvcMapping* map, nsProxyInfo* proxyInfo, 332 nsIInterfaceRequestor* callbacks, uint32_t caps, 333 const OriginAttributes& originAttributes) { 334 mAltSvcCache->UpdateAltServiceMappingWithoutValidation( 335 map, proxyInfo, callbacks, caps, originAttributes); 336 } 337 338 already_AddRefed<AltSvcMapping> GetAltServiceMapping( 339 const nsACString& scheme, const nsACString& host, int32_t port, bool pb, 340 const OriginAttributes& originAttributes, bool aHttp2Allowed, 341 bool aHttp3Allowed) { 342 return mAltSvcCache->GetAltServiceMapping( 343 scheme, host, port, pb, originAttributes, aHttp2Allowed, aHttp3Allowed); 344 } 345 346 // 347 // The HTTP handler caches pointers to specific XPCOM services, and 348 // provides the following helper routines for accessing those services: 349 // 350 [[nodiscard]] nsresult GetIOService(nsIIOService** result); 351 nsICookieService* GetCookieService(); // not addrefed 352 nsISiteSecurityService* GetSSService(); 353 354 // Called by the channel synchronously during asyncOpen 355 void OnFailedOpeningRequest(nsIHttpChannel* chan) { 356 NotifyObservers(chan, NS_HTTP_ON_FAILED_OPENING_REQUEST_TOPIC); 357 } 358 359 // Called by the channel synchronously during asyncOpen 360 void OnOpeningRequest(nsIHttpChannel* chan) { 361 NotifyObservers(chan, NS_HTTP_ON_OPENING_REQUEST_TOPIC); 362 } 363 364 void OnOpeningDocumentRequest(nsIIdentChannel* chan) { 365 NotifyObservers(chan, NS_DOCUMENT_ON_OPENING_REQUEST_TOPIC); 366 } 367 368 // Called by the channel before writing a request 369 void OnModifyRequest(nsIHttpChannel* chan) { 370 NotifyObservers(chan, NS_HTTP_ON_MODIFY_REQUEST_TOPIC); 371 } 372 373 // Same as OnModifyRequest but before cookie headers are written. 374 void OnModifyRequestBeforeCookies(nsIHttpChannel* chan) { 375 NotifyObservers(chan, NS_HTTP_ON_MODIFY_REQUEST_BEFORE_COOKIES_TOPIC); 376 } 377 378 void OnModifyDocumentRequest(nsIIdentChannel* chan) { 379 NotifyObservers(chan, NS_DOCUMENT_ON_MODIFY_REQUEST_TOPIC); 380 } 381 382 // Called by the channel before calling onStopRequest 383 void OnBeforeStopRequest(nsIHttpChannel* chan) { 384 NotifyObservers(chan, NS_HTTP_ON_BEFORE_STOP_REQUEST_TOPIC); 385 } 386 387 // Called by the channel after calling onStopRequest 388 void OnStopRequest(nsIHttpChannel* chan) { 389 NotifyObservers(chan, NS_HTTP_ON_STOP_REQUEST_TOPIC); 390 } 391 392 // Called by the channel before setting up the transaction 393 void OnBeforeConnect(nsIHttpChannel* chan) { 394 NotifyObservers(chan, NS_HTTP_ON_BEFORE_CONNECT_TOPIC); 395 } 396 397 // Called by the channel once headers are available 398 void OnExamineResponse(nsIHttpChannel* chan) { 399 NotifyObservers(chan, NS_HTTP_ON_EXAMINE_RESPONSE_TOPIC); 400 } 401 402 // Called by the channel once the cookie processing is completed. 403 void OnAfterExamineResponse(nsIHttpChannel* chan) { 404 NotifyObservers(chan, NS_HTTP_ON_AFTER_EXAMINE_RESPONSE_TOPIC); 405 } 406 407 // Called by the channel once headers have been merged with cached headers 408 void OnExamineMergedResponse(nsIHttpChannel* chan) { 409 NotifyObservers(chan, NS_HTTP_ON_EXAMINE_MERGED_RESPONSE_TOPIC); 410 } 411 412 // Called by the channel once it made background cache revalidation 413 void OnBackgroundRevalidation(nsIHttpChannel* chan) { 414 NotifyObservers(chan, NS_HTTP_ON_BACKGROUND_REVALIDATION); 415 } 416 417 // Called by channels before a redirect happens. This notifies both the 418 // channel's and the global redirect observers. 419 [[nodiscard]] nsresult AsyncOnChannelRedirect( 420 nsIChannel* oldChan, nsIChannel* newChan, uint32_t flags, 421 nsIEventTarget* mainThreadEventTarget = nullptr); 422 423 // Called by the channel when the response is read from the cache without 424 // communicating with the server. 425 void OnExamineCachedResponse(nsIHttpChannel* chan) { 426 NotifyObservers(chan, NS_HTTP_ON_EXAMINE_CACHED_RESPONSE_TOPIC); 427 } 428 429 // Called by the channel when the transaction pump is suspended because of 430 // trying to get credentials asynchronously. 431 void OnTransactionSuspendedDueToAuthentication(nsIHttpChannel* chan) { 432 NotifyObservers(chan, "http-on-transaction-suspended-authentication"); 433 } 434 435 // Generates the host:port string for use in the Host: header as well as the 436 // CONNECT line for proxies. This handles IPv6 literals correctly. 437 [[nodiscard]] static nsresult GenerateHostPort(const nsCString& host, 438 int32_t port, 439 nsACString& hostLine); 440 441 static uint8_t UrgencyFromCoSFlags(uint32_t cos, int32_t aSupportsPriority); 442 443 SpdyInformation* SpdyInfo() { return &mSpdyInfo; } 444 bool IsH2MandatorySuiteEnabled() { return mH2MandatorySuiteEnabled; } 445 446 // returns true in between Init and Shutdown states 447 bool Active() { return mHandlerActive; } 448 449 nsIRequestContextService* GetRequestContextService() { 450 return mRequestContextService.get(); 451 } 452 453 void ShutdownConnectionManager(); 454 455 uint32_t DefaultHpackBuffer() const { return mDefaultHpackBuffer; } 456 457 static bool IsHttp3Enabled(); 458 bool IsHttp3VersionSupported(const nsACString& version); 459 460 static bool IsHttp3SupportedByServer(nsHttpResponseHead* aResponseHead); 461 uint32_t DefaultQpackTableSize() const { return mQpackTableSize; } 462 uint16_t DefaultHttp3MaxBlockedStreams() const { 463 return (uint16_t)mHttp3MaxBlockedStreams; 464 } 465 466 const nsCString& Http3QlogDir(); 467 468 float FocusedWindowTransactionRatio() const { 469 return mFocusedWindowTransactionRatio; 470 } 471 472 // Called when an optimization feature affecting active vs background tab load 473 // took place. Called only on the parent process and only updates 474 // mLastActiveTabLoadOptimizationHit timestamp to now. 475 void NotifyActiveTabLoadOptimization(); 476 TimeStamp GetLastActiveTabLoadOptimizationHit(); 477 void SetLastActiveTabLoadOptimizationHit(TimeStamp const& when); 478 bool IsBeforeLastActiveTabLoadOptimization(TimeStamp const& when); 479 480 HttpTrafficAnalyzer* GetHttpTrafficAnalyzer(); 481 482 nsresult CompleteUpgrade(HttpTransactionShell* aTrans, 483 nsIHttpUpgradeListener* aUpgradeListener); 484 485 nsresult DoShiftReloadConnectionCleanupWithConnInfo( 486 nsHttpConnectionInfo* aCI); 487 488 void MaybeAddAltSvcForTesting(nsIURI* aUri, const nsACString& aUsername, 489 bool aPrivateBrowsing, 490 nsIInterfaceRequestor* aCallbacks, 491 const OriginAttributes& aOriginAttributes); 492 493 static bool EchConfigEnabled(bool aIsHttp3 = false); 494 // When EchConfig is enabled and all records with echConfig are failed, this 495 // functon indicate whether we can fallback to the origin server. 496 // In the case an HTTPS RRSet contains some RRs with echConfig and some 497 // without, we always fallback to the origin one. 498 bool FallbackToOriginIfConfigsAreECHAndAllFailed() const; 499 500 // So we can ensure that this is done during process preallocation to 501 // avoid first-use overhead 502 static void PresetAcceptLanguages(); 503 504 bool HttpActivityDistributorActivated(); 505 void ObserveHttpActivityWithArgs(const HttpActivityArgs& aArgs, 506 uint32_t aActivityType, 507 uint32_t aActivitySubtype, PRTime aTimestamp, 508 uint64_t aExtraSizeData, 509 const nsACString& aExtraStringData); 510 511 static bool GetParentalControlsEnabled() { return sParentalControlsEnabled; } 512 static void UpdateParentalControlsEnabled(bool waitForCompletion); 513 514 private: 515 nsHttpHandler(); 516 517 virtual ~nsHttpHandler(); 518 519 [[nodiscard]] nsresult Init(); 520 521 // 522 // Useragent/prefs helper methods 523 // 524 void BuildUserAgent(); 525 void InitUserAgentComponents(); 526 #ifdef XP_MACOSX 527 void InitMSAuthorities(); 528 #endif 529 static void PrefsChanged(const char* pref, void* self); 530 void PrefsChanged(const char* pref); 531 532 [[nodiscard]] nsresult SetAcceptLanguages(); 533 [[nodiscard]] nsresult SetAcceptEncodings(const char*, bool aIsSecure, 534 bool aDictionary); 535 536 [[nodiscard]] nsresult InitConnectionMgr(); 537 538 void NotifyObservers(nsIChannel* chan, const char* event); 539 540 friend class SocketProcessChild; 541 void SetHttpHandlerInitArgs(const HttpHandlerInitArgs& aArgs); 542 void SetDeviceModelId(const nsACString& aModelId); 543 544 // We only allow DNSUtils and TRRServiceChannel itself to create 545 // TRRServiceChannel. 546 friend class TRRServiceChannel; 547 friend class DNSUtils; 548 nsresult CreateTRRServiceChannel(nsIURI* uri, nsIProxyInfo* givenProxyInfo, 549 uint32_t proxyResolveFlags, nsIURI* proxyURI, 550 nsILoadInfo* aLoadInfo, nsIChannel** result); 551 nsresult SetupChannelInternal(HttpBaseChannel* aChannel, nsIURI* uri, 552 nsIProxyInfo* givenProxyInfo, 553 uint32_t proxyResolveFlags, nsIURI* proxyURI, 554 nsILoadInfo* aLoadInfo, nsIChannel** result); 555 556 private: 557 // cached services 558 nsMainThreadPtrHandle<nsIIOService> mIOService; 559 nsMainThreadPtrHandle<nsICookieService> mCookieService; 560 nsMainThreadPtrHandle<nsISiteSecurityService> mSSService; 561 562 // the authentication credentials cache 563 RefPtr<nsHttpAuthCache> mAuthCache; 564 RefPtr<nsHttpAuthCache> mPrivateAuthCache; 565 566 // the connection manager 567 RefPtr<HttpConnectionMgrShell> mConnMgr; 568 569 UniquePtr<AltSvcCache> mAltSvcCache; 570 571 // Pointer to DictionaryCache singleton 572 RefPtr<DictionaryCache> mDictionaryCache; 573 574 // 575 // prefs 576 // 577 578 enum HttpVersion mHttpVersion { HttpVersion::v1_1 }; 579 enum HttpVersion mProxyHttpVersion { HttpVersion::v1_1 }; 580 uint32_t mCapabilities{NS_HTTP_ALLOW_KEEPALIVE}; 581 582 bool mFastFallbackToIPv4{false}; 583 PRIntervalTime mIdleTimeout; 584 PRIntervalTime mSpdyTimeout; 585 PRIntervalTime mResponseTimeout; 586 Atomic<bool, Relaxed> mResponseTimeoutEnabled{false}; 587 uint32_t mNetworkChangedTimeout{5000}; // milliseconds 588 uint16_t mMaxRequestAttempts{6}; 589 uint16_t mMaxRequestDelay{10}; 590 uint16_t mIdleSynTimeout{250}; 591 uint16_t mFallbackSynTimeout{5}; // seconds 592 593 bool mH2MandatorySuiteEnabled{false}; 594 uint16_t mMaxUrgentExcessiveConns{3}; 595 uint16_t mMaxConnections{24}; 596 uint8_t mMaxPersistentConnectionsPerServer{2}; 597 uint8_t mMaxPersistentConnectionsPerProxy{4}; 598 599 bool mThrottleEnabled{true}; 600 uint32_t mThrottleSuspendFor{3000}; 601 uint32_t mThrottleResumeFor{200}; 602 uint32_t mThrottleHoldTime{600}; 603 uint32_t mThrottleMaxTime{3000}; 604 605 int32_t mSendWindowSize{1024}; 606 607 bool mUrgentStartEnabled{true}; 608 bool mTailBlockingEnabled{true}; 609 uint32_t mTailDelayQuantum{600}; 610 uint32_t mTailDelayQuantumAfterDCL{100}; 611 uint32_t mTailDelayMax{6000}; 612 uint32_t mTailTotalMax{0}; 613 614 uint8_t mRedirectionLimit{10}; 615 616 bool mBeConservativeForProxy{true}; 617 618 uint8_t mQoSBits{0x00}; 619 620 bool mEnforceAssocReq{false}; 621 622 nsCString mImageAcceptHeader; 623 nsCString mDocumentAcceptHeader; 624 625 nsCString mAcceptLanguages; 626 nsCString mHttpAcceptEncodings; 627 nsCString mHttpsAcceptEncodings; 628 nsCString mDictionaryAcceptEncodings; 629 630 nsCString mDefaultSocketType; 631 632 // cache support 633 uint32_t mLastUniqueID; 634 Atomic<uint32_t, Relaxed> mSessionStartTime{0}; 635 636 // useragent components 637 nsCString mLegacyAppName{"Mozilla"}; 638 nsCString mLegacyAppVersion{"5.0"}; 639 uint64_t mIdempotencyKeySeed; 640 uint64_t mPrivateBrowsingIdempotencyKeySeed; 641 nsCString mPlatform; 642 nsCString mOscpu; 643 nsCString mMisc; 644 nsCString mProduct{"Gecko"}; 645 nsCString mProductSub; 646 nsCString mAppName; 647 nsCString mAppVersion; 648 nsCString mCompatFirefox; 649 bool mCompatFirefoxEnabled{false}; 650 nsCString mCompatDevice; 651 nsCString mDeviceModelId; 652 653 nsCString mUserAgent; 654 nsCString mSpoofedUserAgent; 655 nsCString mUserAgentOverride; 656 bool mUserAgentIsDirty{true}; // true if mUserAgent should be rebuilt 657 bool mAcceptLanguagesIsDirty{true}; 658 659 bool mPromptTempRedirect{true}; 660 661 // Persistent HTTPS caching flag 662 bool mEnablePersistentHttpsCaching{false}; 663 664 // for broadcasting safe hint; 665 bool mSafeHintEnabled{false}; 666 static Atomic<bool, Relaxed> sParentalControlsEnabled; 667 668 // true in between init and shutdown states 669 Atomic<bool, Relaxed> mHandlerActive{false}; 670 671 // The value of 'hidden' network.http.debug-observations : 1; 672 uint32_t mDebugObservations : 1; 673 674 uint32_t mEnableAltSvc : 1; 675 uint32_t mEnableAltSvcOE : 1; 676 677 // Try to use SPDY features instead of HTTP/1.1 over SSL 678 SpdyInformation mSpdyInfo; 679 680 uint32_t mSpdySendingChunkSize{ASpdySession::kSendingChunkSize}; 681 uint32_t mSpdySendBufferSize{ASpdySession::kTCPSendBufferSize}; 682 uint32_t mSpdyPushAllowance{ 683 ASpdySession::kInitialPushAllowance}; // match default pref 684 uint32_t mSpdyPullAllowance{ASpdySession::kInitialRwin}; 685 uint32_t mDefaultSpdyConcurrent{ASpdySession::kDefaultMaxConcurrent}; 686 PRIntervalTime mSpdyPingThreshold; 687 PRIntervalTime mSpdyPingTimeout; 688 689 // The maximum amount of time to wait for socket transport to be 690 // established. In milliseconds. 691 uint32_t mConnectTimeout{90000}; 692 693 // The maximum amount of time to wait for a tls handshake to be 694 // established. In milliseconds. 695 uint32_t mTLSHandshakeTimeout{30000}; 696 697 // The maximum number of current global half open sockets allowable 698 // when starting a new speculative connection. 699 uint32_t mParallelSpeculativeConnectLimit{6}; 700 701 // For Rate Pacing of HTTP/1 requests through a netwerk/base/EventTokenBucket 702 // Active requests <= *MinParallelism are not subject to the rate pacing 703 bool mRequestTokenBucketEnabled{true}; 704 uint16_t mRequestTokenBucketMinParallelism{6}; 705 uint32_t mRequestTokenBucketHz{100}; // EventTokenBucket HZ 706 uint32_t mRequestTokenBucketBurst{32}; // EventTokenBucket Burst 707 708 // Whether or not to block requests for non head js/css items (e.g. media) 709 // while those elements load. 710 bool mCriticalRequestPrioritization{true}; 711 712 // TCP Keepalive configuration values. 713 714 // True if TCP keepalive is enabled for short-lived conns. 715 bool mTCPKeepaliveShortLivedEnabled{false}; 716 // Time (secs) indicating how long a conn is considered short-lived. 717 int32_t mTCPKeepaliveShortLivedTimeS{60}; 718 // Time (secs) before first keepalive probe; between successful probes. 719 int32_t mTCPKeepaliveShortLivedIdleTimeS{10}; 720 721 // True if TCP keepalive is enabled for long-lived conns. 722 bool mTCPKeepaliveLongLivedEnabled{false}; 723 // Time (secs) before first keepalive probe; between successful probes. 724 int32_t mTCPKeepaliveLongLivedIdleTimeS{600}; 725 726 // if true, generate NS_ERROR_PARTIAL_TRANSFER for h1 responses with 727 // incorrect content lengths or malformed chunked encodings 728 FrameCheckLevel mEnforceH1Framing{FRAMECHECK_BARELY}; 729 730 nsCOMPtr<nsIRequestContextService> mRequestContextService; 731 732 // The default size (in bytes) of the HPACK decompressor table. 733 uint32_t mDefaultHpackBuffer{4096}; 734 735 // Http3 parameters 736 Atomic<uint32_t, Relaxed> mQpackTableSize{4096}; 737 // uint16_t is enough here, but Atomic only supports uint32_t or uint64_t. 738 Atomic<uint32_t, Relaxed> mHttp3MaxBlockedStreams{10}; 739 740 nsCString mHttp3QlogDir; 741 742 // The ratio for dispatching transactions from the focused window. 743 float mFocusedWindowTransactionRatio{0.9f}; 744 745 HttpTrafficAnalyzer mHttpTrafficAnalyzer; 746 747 private: 748 // For Rate Pacing Certain Network Events. Only assign this pointer on 749 // socket thread. 750 void MakeNewRequestTokenBucket(); 751 RefPtr<EventTokenBucket> mRequestTokenBucket; 752 753 public: 754 // Socket thread only 755 [[nodiscard]] nsresult SubmitPacedRequest(ATokenBucketEvent* event, 756 nsICancelable** cancel) { 757 MOZ_ASSERT(OnSocketThread(), "not on socket thread"); 758 if (!mRequestTokenBucket) { 759 return NS_ERROR_NOT_AVAILABLE; 760 } 761 return mRequestTokenBucket->SubmitEvent(event, cancel); 762 } 763 764 // Socket thread only 765 void SetRequestTokenBucket(EventTokenBucket* aTokenBucket) { 766 MOZ_ASSERT(OnSocketThread(), "not on socket thread"); 767 mRequestTokenBucket = aTokenBucket; 768 } 769 770 void StopRequestTokenBucket() { 771 MOZ_ASSERT(OnSocketThread(), "not on socket thread"); 772 if (mRequestTokenBucket) { 773 mRequestTokenBucket->Stop(); 774 mRequestTokenBucket = nullptr; 775 } 776 } 777 778 private: 779 RefPtr<Tickler> mWifiTickler; 780 void TickleWifi(nsIInterfaceRequestor* cb); 781 782 private: 783 [[nodiscard]] nsresult SpeculativeConnectInternal( 784 nsIURI* aURI, nsIPrincipal* aPrincipal, 785 Maybe<OriginAttributes>&& aOriginAttributes, 786 nsIInterfaceRequestor* aCallbacks, bool anonymous); 787 void ExcludeHttp2OrHttp3Internal(const nsHttpConnectionInfo* ci); 788 789 // State for generating channelIds 790 uint64_t mUniqueProcessId{0}; 791 Atomic<uint32_t, Relaxed> mNextChannelId{1}; 792 793 // ProcessId used for logging. 794 uint32_t mProcessId{0}; 795 796 // The last time any of the active tab page load optimization took place. 797 // This is accessed on multiple threads, hence a lock is needed. 798 // On the parent process this is updated to now every time a scheduling 799 // or rate optimization related to the active/background tab is hit. 800 // We carry this value through each http channel's onstoprequest notification 801 // to the parent process. On the content process then we just update this 802 // value from ipc onstoprequest arguments. This is a sufficent way of passing 803 // it down to the content process, since the value will be used only after 804 // onstoprequest notification coming from an http channel. 805 Mutex mLastActiveTabLoadOptimizationLock{ 806 "nsHttpConnectionMgr::LastActiveTabLoadOptimization"}; 807 TimeStamp mLastActiveTabLoadOptimizationHit; 808 809 Mutex mHttpExclusionLock MOZ_UNANNOTATED{"nsHttpHandler::HttpExclusion"}; 810 811 public: 812 [[nodiscard]] uint64_t NewChannelId(); 813 void AddHttpChannel(uint64_t aId, nsISupports* aChannel); 814 void RemoveHttpChannel(uint64_t aId); 815 nsWeakPtr GetWeakHttpChannel(uint64_t aId); 816 817 void ExcludeHttp2(const nsHttpConnectionInfo* ci); 818 [[nodiscard]] bool IsHttp2Excluded(const nsHttpConnectionInfo* ci); 819 void ExcludeHttp3(const nsHttpConnectionInfo* ci); 820 [[nodiscard]] bool IsHttp3Excluded(const nsACString& aRoutedHost); 821 void Exclude0RttTcp(const nsHttpConnectionInfo* ci); 822 [[nodiscard]] bool Is0RttTcpExcluded(const nsHttpConnectionInfo* ci); 823 824 void ExcludeHTTPSRRHost(const nsACString& aHost); 825 [[nodiscard]] bool IsHostExcludedForHTTPSRR(const nsACString& aHost); 826 827 #ifdef XP_MACOSX 828 [[nodiscard]] bool IsHostMSAuthority(const nsACString& aHost); 829 #endif 830 831 private: 832 nsTHashSet<nsCString> mExcludedHttp2Origins; 833 nsTHashSet<nsCString> mExcludedHttp3Origins; 834 nsTHashSet<nsCString> mExcluded0RttTcpOrigins; 835 // A set of hosts that we should not upgrade to HTTPS with HTTPS RR. 836 nsTHashSet<nsCString> mExcludedHostsForHTTPSRRUpgrade; 837 838 #ifdef XP_MACOSX 839 // A list of trusted Microsoft SSO authority URLs 840 nsTHashSet<nsCString> mMSAuthorities; 841 #endif 842 843 // The mapping of channel id and the weak pointer of nsHttpChannel. 844 nsTHashMap<nsUint64HashKey, nsWeakPtr> mIDToHttpChannelMap; 845 846 // This is parsed pref network.http.http3.alt-svc-mapping-for-testing. 847 // The pref set artificial altSvc-s for origin for testing. 848 // This maps an origin to an altSvc. 849 nsClassHashtable<nsCStringHashKey, nsCString> mAltSvcMappingTemptativeMap; 850 851 nsCOMPtr<nsIHttpActivityDistributor> mActivityDistributor; 852 }; 853 854 extern StaticRefPtr<nsHttpHandler> gHttpHandler; 855 856 //----------------------------------------------------------------------------- 857 // nsHttpsHandler - thin wrapper to distinguish the HTTP handler from the 858 // HTTPS handler (even though they share the same impl). 859 //----------------------------------------------------------------------------- 860 861 class nsHttpsHandler : public nsIHttpProtocolHandler, 862 public nsSupportsWeakReference, 863 public nsISpeculativeConnect { 864 virtual ~nsHttpsHandler() = default; 865 866 public: 867 // we basically just want to override GetScheme and GetDefaultPort... 868 // all other methods should be forwarded to the nsHttpHandler instance. 869 870 NS_DECL_THREADSAFE_ISUPPORTS 871 NS_DECL_NSIPROTOCOLHANDLER 872 NS_FORWARD_NSIPROXIEDPROTOCOLHANDLER(gHttpHandler->) 873 NS_FORWARD_NSIHTTPPROTOCOLHANDLER(gHttpHandler->) 874 875 NS_IMETHOD SpeculativeConnect(nsIURI* aURI, nsIPrincipal* aPrincipal, 876 nsIInterfaceRequestor* aCallbacks, 877 bool aAnonymous) override { 878 return gHttpHandler->SpeculativeConnect(aURI, aPrincipal, aCallbacks, 879 aAnonymous); 880 } 881 882 NS_IMETHOD SpeculativeConnectWithOriginAttributes( 883 nsIURI* aURI, JS::Handle<JS::Value> originAttributes, 884 nsIInterfaceRequestor* aCallbacks, bool aAnonymous, 885 JSContext* cx) override { 886 return gHttpHandler->SpeculativeConnectWithOriginAttributes( 887 aURI, originAttributes, aCallbacks, aAnonymous, cx); 888 } 889 890 NS_IMETHOD_(void) 891 SpeculativeConnectWithOriginAttributesNative( 892 nsIURI* aURI, mozilla::OriginAttributes&& originAttributes, 893 nsIInterfaceRequestor* aCallbacks, bool aAnonymous) override { 894 gHttpHandler->SpeculativeConnectWithOriginAttributesNative( 895 aURI, std::move(originAttributes), aCallbacks, aAnonymous); 896 } 897 898 nsHttpsHandler() = default; 899 900 [[nodiscard]] nsresult Init(); 901 }; 902 903 //----------------------------------------------------------------------------- 904 // HSTSDataCallbackWrapper - A threadsafe helper class to wrap the callback. 905 // 906 // We need this because dom::promise and EnsureHSTSDataResolver are not 907 // threadsafe. 908 //----------------------------------------------------------------------------- 909 class HSTSDataCallbackWrapper final { 910 public: 911 NS_INLINE_DECL_THREADSAFE_REFCOUNTING(HSTSDataCallbackWrapper) 912 913 explicit HSTSDataCallbackWrapper(std::function<void(bool)>&& aCallback) 914 : mCallback(std::move(aCallback)) { 915 MOZ_ASSERT(NS_IsMainThread()); 916 } 917 918 void DoCallback(bool aResult) { 919 MOZ_ASSERT(NS_IsMainThread()); 920 mCallback(aResult); 921 } 922 923 private: 924 ~HSTSDataCallbackWrapper() = default; 925 926 std::function<void(bool)> mCallback; 927 }; 928 929 } // namespace mozilla::net 930 931 #endif // nsHttpHandler_h__