tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

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__