/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// XXX These includes can be replaced by forward declarations by moving the On* // method implementations to the cpp file #include"nsIChannel.h" #include"nsIHttpChannel.h" #include"nsSocketTransportService2.h"
class nsIHttpActivityDistributor; class nsIHttpUpgradeListener; class nsIPrefBranch; class nsICancelable; class nsICookieService; class nsIIOService; class nsIRequestContextService; class nsISiteSecurityService; class nsIStreamConverterService;
namespace mozilla::net {
class ATokenBucketEvent; class EventTokenBucket; class Tickler; class nsHttpConnection; class nsHttpConnectionInfo; class HttpBaseChannel; class HttpHandlerInitArgs; class HttpTransactionShell; class AltSvcMapping; class DNSUtils; class TRRServiceChannel; class SocketProcessChild;
/* * FRAMECHECK_LAX - no check * FRAMECHECK_BARELY - allows: * 1) that chunk-encoding does not have the last 0-size * chunk. So, if a chunked-encoded transfer ends on exactly * a chunk boundary we consider that fine. This will allows * us to accept buggy servers that do not send the last * chunk. It will make us not detect a certain amount of * cut-offs. * 2) When receiving a gzipped response, we consider a * gzip stream that doesn't end fine according to the gzip * decompressing state machine to be a partial transfer. * If a gzipped transfer ends fine according to the * decompressor, we do not check for size unalignments. * This allows to allow HTTP gzipped responses where the * Content-Length is not the same as the actual contents. * 3) When receiving HTTP that isn't * content-encoded/compressed (like in case 2) and not * chunked (like in case 1), perform the size comparison * between Content-Length: and the actual size received * and consider a mismatch to mean a * NS_ERROR_NET_PARTIAL_TRANSFER error. * FRAMECHECK_STRICT_CHUNKED - This is the same as FRAMECHECK_BARELY only we * enforce that the last 0-size chunk is received * in case 1). * FRAMECHECK_STRICT - we also do not allow case 2) and 3) from * FRAMECHECK_BARELY.
*/ enum FrameCheckLevel {
FRAMECHECK_LAX,
FRAMECHECK_BARELY,
FRAMECHECK_STRICT_CHUNKED,
FRAMECHECK_STRICT
};
//----------------------------------------------------------------------------- // nsHttpHandler - protocol handler for HTTP and HTTPS //-----------------------------------------------------------------------------
class nsHttpHandler final : public nsIHttpProtocolHandler, public nsIObserver, public nsSupportsWeakReference, public nsISpeculativeConnect { public:
NS_DECL_THREADSAFE_ISUPPORTS
NS_DECL_NSIPROTOCOLHANDLER
NS_DECL_NSIPROXIEDPROTOCOLHANDLER
NS_DECL_NSIHTTPPROTOCOLHANDLER
NS_DECL_NSIOBSERVER
NS_DECL_NSISPECULATIVECONNECT
// Returns true if TCP keepalive should be enabled for short-lived conns. bool TCPKeepaliveEnabledForShortLivedConns() { return mTCPKeepaliveShortLivedEnabled;
} // Return time (secs) that a connection is consider short lived (for TCP // keepalive purposes). After this time, the connection is long-lived.
int32_t GetTCPKeepaliveShortLivedTime() { return mTCPKeepaliveShortLivedTimeS;
} // Returns time (secs) before first TCP keepalive probes should be sent; // same time used between successful keepalive probes.
int32_t GetTCPKeepaliveShortLivedIdleTime() { return mTCPKeepaliveShortLivedIdleTimeS;
}
// Returns true if TCP keepalive should be enabled for long-lived conns. bool TCPKeepaliveEnabledForLongLivedConns() { return mTCPKeepaliveLongLivedEnabled;
} // Returns time (secs) before first TCP keepalive probes should be sent; // same time used between successful keepalive probes.
int32_t GetTCPKeepaliveLongLivedIdleTime() { return mTCPKeepaliveLongLivedIdleTimeS;
}
// returns the HTTP framing check level preference, as controlled with // network.http.enforce-framing.http1 and network.http.enforce-framing.soft
FrameCheckLevel GetEnforceH1Framing() { return mEnforceH1Framing; }
// // Connection management methods: // // - the handler only owns idle connections; it does not own active // connections. // // - the handler keeps a count of active connections to enforce the // steady-state max-connections pref. //
// Called to kick-off a new transaction, by default the transaction // will be put on the pending transaction queue if it cannot be // initiated at this time. Callable from any thread.
[[nodiscard]] nsresult InitiateTransaction(HttpTransactionShell* trans,
int32_t priority);
// This function is also called to kick-off a new transaction. But the new // transaction will take a sticky connection from |transWithStickyConn| // and reuse it.
[[nodiscard]] nsresult InitiateTransactionWithStickyConn(
HttpTransactionShell* trans, int32_t priority,
HttpTransactionShell* transWithStickyConn);
// Called to change the priority of an existing transaction that has // already been initiated.
[[nodiscard]] nsresult RescheduleTransaction(HttpTransactionShell* trans,
int32_t priority);
// Called to cancel a transaction, which may or may not be assigned to // a connection. Callable from any thread.
[[nodiscard]] nsresult CancelTransaction(HttpTransactionShell* trans,
nsresult reason);
// Called when a connection is done processing a transaction. Callable // from any thread.
[[nodiscard]] nsresult ReclaimConnection(HttpConnectionBase* conn) { return mConnMgr->ReclaimConnection(conn);
}
// // The HTTP handler caches pointers to specific XPCOM services, and // provides the following helper routines for accessing those services: //
[[nodiscard]] nsresult GetIOService(nsIIOService** result);
nsICookieService* GetCookieService(); // not addrefed
nsISiteSecurityService* GetSSService();
// Called by the channel synchronously during asyncOpen void OnFailedOpeningRequest(nsIHttpChannel* chan) {
NotifyObservers(chan, NS_HTTP_ON_FAILED_OPENING_REQUEST_TOPIC);
}
// Called by the channel synchronously during asyncOpen void OnOpeningRequest(nsIHttpChannel* chan) {
NotifyObservers(chan, NS_HTTP_ON_OPENING_REQUEST_TOPIC);
}
// Called by the channel before writing a request void OnModifyRequest(nsIHttpChannel* chan) {
NotifyObservers(chan, NS_HTTP_ON_MODIFY_REQUEST_TOPIC);
}
// Same as OnModifyRequest but before cookie headers are written. void OnModifyRequestBeforeCookies(nsIHttpChannel* chan) {
NotifyObservers(chan, NS_HTTP_ON_MODIFY_REQUEST_BEFORE_COOKIES_TOPIC);
}
// Called by the channel before calling onStopRequest void OnBeforeStopRequest(nsIHttpChannel* chan) {
NotifyObservers(chan, NS_HTTP_ON_BEFORE_STOP_REQUEST_TOPIC);
}
// Called by the channel after calling onStopRequest void OnStopRequest(nsIHttpChannel* chan) {
NotifyObservers(chan, NS_HTTP_ON_STOP_REQUEST_TOPIC);
}
// Called by the channel before setting up the transaction void OnBeforeConnect(nsIHttpChannel* chan) {
NotifyObservers(chan, NS_HTTP_ON_BEFORE_CONNECT_TOPIC);
}
// Called by the channel once headers are available void OnExamineResponse(nsIHttpChannel* chan) {
NotifyObservers(chan, NS_HTTP_ON_EXAMINE_RESPONSE_TOPIC);
}
// Called by the channel once the cookie processing is completed. void OnAfterExamineResponse(nsIHttpChannel* chan) {
NotifyObservers(chan, NS_HTTP_ON_AFTER_EXAMINE_RESPONSE_TOPIC);
}
// Called by the channel once headers have been merged with cached headers void OnExamineMergedResponse(nsIHttpChannel* chan) {
NotifyObservers(chan, NS_HTTP_ON_EXAMINE_MERGED_RESPONSE_TOPIC);
}
// Called by the channel once it made background cache revalidation void OnBackgroundRevalidation(nsIHttpChannel* chan) {
NotifyObservers(chan, NS_HTTP_ON_BACKGROUND_REVALIDATION);
}
// Called by channels before a redirect happens. This notifies both the // channel's and the global redirect observers.
[[nodiscard]] nsresult AsyncOnChannelRedirect(
nsIChannel* oldChan, nsIChannel* newChan, uint32_t flags,
nsIEventTarget* mainThreadEventTarget = nullptr);
// Called by the channel when the response is read from the cache without // communicating with the server. void OnExamineCachedResponse(nsIHttpChannel* chan) {
NotifyObservers(chan, NS_HTTP_ON_EXAMINE_CACHED_RESPONSE_TOPIC);
}
// Called by the channel when the transaction pump is suspended because of // trying to get credentials asynchronously. void OnTransactionSuspendedDueToAuthentication(nsIHttpChannel* chan) {
NotifyObservers(chan, "http-on-transaction-suspended-authentication");
}
// Generates the host:port string for use in the Host: header as well as the // CONNECT line for proxies. This handles IPv6 literals correctly.
[[nodiscard]] static nsresult GenerateHostPort(const nsCString& host,
int32_t port,
nsACString& hostLine);
// Called when an optimization feature affecting active vs background tab load // took place. Called only on the parent process and only updates // mLastActiveTabLoadOptimizationHit timestamp to now. void NotifyActiveTabLoadOptimization();
TimeStamp GetLastActiveTabLoadOptimizationHit(); void SetLastActiveTabLoadOptimizationHit(TimeStamp const& when); bool IsBeforeLastActiveTabLoadOptimization(TimeStamp const& when);
bool EchConfigEnabled(bool aIsHttp3 = false) const; // When EchConfig is enabled and all records with echConfig are failed, this // functon indicate whether we can fallback to the origin server. // In the case an HTTPS RRSet contains some RRs with echConfig and some // without, we always fallback to the origin one. bool FallbackToOriginIfConfigsAreECHAndAllFailed() const;
// So we can ensure that this is done during process preallocation to // avoid first-use overhead staticvoid PresetAcceptLanguages();
// we'll warn the user if we load an URL containing a userpass field // unless its length is less than this threshold. this warning is // intended to protect the user against spoofing attempts that use // the userpass field of the URL to obscure the actual origin server.
uint8_t mPhishyUserPassLength{1};
// The maximum amount of time to wait for socket transport to be // established. In milliseconds.
uint32_t mConnectTimeout{90000};
// The maximum amount of time to wait for a tls handshake to be // established. In milliseconds.
uint32_t mTLSHandshakeTimeout{30000};
// The maximum number of current global half open sockets allowable // when starting a new speculative connection.
uint32_t mParallelSpeculativeConnectLimit{6};
// For Rate Pacing of HTTP/1 requests through a netwerk/base/EventTokenBucket // Active requests <= *MinParallelism are not subject to the rate pacing bool mRequestTokenBucketEnabled{true};
uint16_t mRequestTokenBucketMinParallelism{6};
uint32_t mRequestTokenBucketHz{100}; // EventTokenBucket HZ
uint32_t mRequestTokenBucketBurst{32}; // EventTokenBucket Burst
// Whether or not to block requests for non head js/css items (e.g. media) // while those elements load. bool mCriticalRequestPrioritization{true};
// TCP Keepalive configuration values.
// True if TCP keepalive is enabled for short-lived conns. bool mTCPKeepaliveShortLivedEnabled{false}; // Time (secs) indicating how long a conn is considered short-lived.
int32_t mTCPKeepaliveShortLivedTimeS{60}; // Time (secs) before first keepalive probe; between successful probes.
int32_t mTCPKeepaliveShortLivedIdleTimeS{10};
// True if TCP keepalive is enabled for long-lived conns. bool mTCPKeepaliveLongLivedEnabled{false}; // Time (secs) before first keepalive probe; between successful probes.
int32_t mTCPKeepaliveLongLivedIdleTimeS{600};
// if true, generate NS_ERROR_PARTIAL_TRANSFER for h1 responses with // incorrect content lengths or malformed chunked encodings
FrameCheckLevel mEnforceH1Framing{FRAMECHECK_BARELY};
// The default size (in bytes) of the HPACK decompressor table.
uint32_t mDefaultHpackBuffer{4096};
// Http3 parameters
Atomic<uint32_t, Relaxed> mQpackTableSize{4096}; // uint16_t is enough here, but Atomic only supports uint32_t or uint64_t.
Atomic<uint32_t, Relaxed> mHttp3MaxBlockedStreams{10};
nsCString mHttp3QlogDir;
// The ratio for dispatching transactions from the focused window. float mFocusedWindowTransactionRatio{0.9f};
// If true, the transactions from active tab will be dispatched first. bool mActiveTabPriority{true};
HttpTrafficAnalyzer mHttpTrafficAnalyzer;
private: // For Rate Pacing Certain Network Events. Only assign this pointer on // socket thread. void MakeNewRequestTokenBucket();
RefPtr<EventTokenBucket> mRequestTokenBucket;
public: // Socket thread only
[[nodiscard]] nsresult SubmitPacedRequest(ATokenBucketEvent* event,
nsICancelable** cancel) {
MOZ_ASSERT(OnSocketThread(), "not on socket thread"); if (!mRequestTokenBucket) { return NS_ERROR_NOT_AVAILABLE;
} return mRequestTokenBucket->SubmitEvent(event, cancel);
}
// Socket thread only void SetRequestTokenBucket(EventTokenBucket* aTokenBucket) {
MOZ_ASSERT(OnSocketThread(), "not on socket thread");
mRequestTokenBucket = aTokenBucket;
}
void StopRequestTokenBucket() {
MOZ_ASSERT(OnSocketThread(), "not on socket thread"); if (mRequestTokenBucket) {
mRequestTokenBucket->Stop();
mRequestTokenBucket = nullptr;
}
}
// State for generating channelIds
uint64_t mUniqueProcessId{0};
Atomic<uint32_t, Relaxed> mNextChannelId{1};
// ProcessId used for logging.
uint32_t mProcessId{0};
// The last time any of the active tab page load optimization took place. // This is accessed on multiple threads, hence a lock is needed. // On the parent process this is updated to now every time a scheduling // or rate optimization related to the active/background tab is hit. // We carry this value through each http channel's onstoprequest notification // to the parent process. On the content process then we just update this // value from ipc onstoprequest arguments. This is a sufficent way of passing // it down to the content process, since the value will be used only after // onstoprequest notification coming from an http channel.
Mutex mLastActiveTabLoadOptimizationLock{ "nsHttpConnectionMgr::LastActiveTabLoadOptimization"};
TimeStamp mLastActiveTabLoadOptimizationHit;
private:
nsTHashSet<nsCString> mExcludedHttp2Origins;
nsTHashSet<nsCString> mExcludedHttp3Origins;
nsTHashSet<nsCString> mExcluded0RttTcpOrigins; // A set of hosts that we should not upgrade to HTTPS with HTTPS RR.
nsTHashSet<nsCString> mExcludedHostsForHTTPSRRUpgrade;
#ifdef XP_MACOSX // A list of trusted Microsoft SSO authority URLs
nsTHashSet<nsCString> mMSAuthorities; #endif
// The mapping of channel id and the weak pointer of nsHttpChannel.
nsTHashMap<nsUint64HashKey, nsWeakPtr> mIDToHttpChannelMap;
// This is parsed pref network.http.http3.alt-svc-mapping-for-testing. // The pref set artificial altSvc-s for origin for testing. // This maps an origin to an altSvc.
nsClassHashtable<nsCStringHashKey, nsCString> mAltSvcMappingTemptativeMap;
//----------------------------------------------------------------------------- // nsHttpsHandler - thin wrapper to distinguish the HTTP handler from the // HTTPS handler (even though they share the same impl). //-----------------------------------------------------------------------------
class nsHttpsHandler : public nsIHttpProtocolHandler, public nsSupportsWeakReference, public nsISpeculativeConnect { virtual ~nsHttpsHandler() = default;
public: // we basically just want to override GetScheme and GetDefaultPort... // all other methods should be forwarded to the nsHttpHandler instance.
//----------------------------------------------------------------------------- // HSTSDataCallbackWrapper - A threadsafe helper class to wrap the callback. // // We need this because dom::promise and EnsureHSTSDataResolver are not // threadsafe. //----------------------------------------------------------------------------- class HSTSDataCallbackWrapper final { public:
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(HSTSDataCallbackWrapper)
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.