diff options
Diffstat (limited to '')
-rw-r--r-- | netwerk/protocol/http/HttpChannelParent.h | 325 |
1 files changed, 325 insertions, 0 deletions
diff --git a/netwerk/protocol/http/HttpChannelParent.h b/netwerk/protocol/http/HttpChannelParent.h new file mode 100644 index 0000000000..3dac937127 --- /dev/null +++ b/netwerk/protocol/http/HttpChannelParent.h @@ -0,0 +1,325 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set sw=2 ts=8 et tw=80 : */ + +/* 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/. */ + +#ifndef mozilla_net_HttpChannelParent_h +#define mozilla_net_HttpChannelParent_h + +#include "HttpBaseChannel.h" +#include "nsHttp.h" +#include "mozilla/net/PHttpChannelParent.h" +#include "mozilla/net/NeckoCommon.h" +#include "mozilla/net/NeckoParent.h" +#include "mozilla/MozPromise.h" +#include "nsIParentRedirectingChannel.h" +#include "nsIProgressEventSink.h" +#include "nsIChannelEventSink.h" +#include "nsIRedirectResultListener.h" +#include "nsHttpChannel.h" +#include "mozilla/dom/ipc/IdType.h" +#include "nsIMultiPartChannel.h" +#include "nsIURI.h" + +class nsICacheEntry; + +#define HTTP_CHANNEL_PARENT_IID \ + { \ + 0x982b2372, 0x7aa5, 0x4e8a, { \ + 0xbd, 0x9f, 0x89, 0x74, 0xd7, 0xf0, 0x58, 0xeb \ + } \ + } + +namespace mozilla { + +namespace dom { +class BrowserParent; +} // namespace dom + +namespace net { + +class HttpBackgroundChannelParent; +class ParentChannelListener; +class ChannelEventQueue; + +class HttpChannelParent final : public nsIInterfaceRequestor, + public PHttpChannelParent, + public nsIParentRedirectingChannel, + public nsIProgressEventSink, + public HttpChannelSecurityWarningReporter, + public nsIAsyncVerifyRedirectReadyCallback, + public nsIChannelEventSink, + public nsIRedirectResultListener, + public nsIMultiPartChannelListener { + virtual ~HttpChannelParent(); + + public: + NS_DECL_ISUPPORTS + NS_DECL_NSIREQUESTOBSERVER + NS_DECL_NSISTREAMLISTENER + NS_DECL_NSIPARENTCHANNEL + NS_DECL_NSIPARENTREDIRECTINGCHANNEL + NS_DECL_NSIPROGRESSEVENTSINK + NS_DECL_NSIINTERFACEREQUESTOR + NS_DECL_NSIASYNCVERIFYREDIRECTREADYCALLBACK + NS_DECL_NSICHANNELEVENTSINK + NS_DECL_NSIREDIRECTRESULTLISTENER + NS_DECL_NSIMULTIPARTCHANNELLISTENER + + NS_DECLARE_STATIC_IID_ACCESSOR(HTTP_CHANNEL_PARENT_IID) + + HttpChannelParent(dom::BrowserParent* iframeEmbedding, + nsILoadContext* aLoadContext, + PBOverrideStatus aOverrideStatus); + + [[nodiscard]] bool Init(const HttpChannelCreationArgs& aArgs); + + // Forwarded to nsHttpChannel::SetApplyConversion. + void SetApplyConversion(bool aApplyConversion) { + if (mChannel) { + mChannel->SetApplyConversion(aApplyConversion); + } + } + + [[nodiscard]] nsresult OpenAlternativeOutputStream( + const nsACString& type, int64_t predictedSize, + nsIAsyncOutputStream** _retval); + + // Callbacks for each asynchronous tasks required in AsyncOpen + // procedure, will call InvokeAsyncOpen when all the expected + // tasks is finished successfully or when any failure happened. + // @see mAsyncOpenBarrier. + void TryInvokeAsyncOpen(nsresult aRv); + + void InvokeAsyncOpen(nsresult rv); + + void InvokeEarlyHintPreloader(nsresult rv, uint64_t aEarlyHintPreloaderId); + + // Calls SendSetPriority if mIPCClosed is false. + void DoSendSetPriority(int16_t aValue); + + // Callback while background channel is ready. + void OnBackgroundParentReady(HttpBackgroundChannelParent* aBgParent); + // Callback while background channel is destroyed. + void OnBackgroundParentDestroyed(); + + base::ProcessId OtherPid() const; + + // Inform the child actor that our referrer info was modified late during + // BeginConnect. + void OverrideReferrerInfoDuringBeginConnect(nsIReferrerInfo* aReferrerInfo); + + // Set the cookie string, which will be informed to the child actor during + // PHttpBackgroundChannel::OnStartRequest. Note that CookieService also sends + // the information to all actors via PContent, a main thread IPC, which could + // be slower than background IPC PHttpBackgroundChannel::OnStartRequest. + // Therefore, another cookie notification via PBackground is needed to + // guarantee the listener in child has the necessary cookies before + // OnStartRequest. + void SetCookie(nsCString&& aCookie); + + using ChildEndpointPromise = + MozPromise<ipc::Endpoint<extensions::PStreamFilterChild>, bool, true>; + [[nodiscard]] RefPtr<ChildEndpointPromise> AttachStreamFilter( + Endpoint<extensions::PStreamFilterParent>&& aParentEndpoint, + Endpoint<extensions::PStreamFilterChild>&& aChildEndpoint); + [[nodiscard]] RefPtr<GenericPromise> DetachStreamFilters(); + + // Should only be called from EarlyHintPreloader. mChannel should be null at + // the point of calling. Sets mChannel to aChannel. Used by the + // EarlyHintPreloader to redirect the channel to this parent as soon as the + // final channel becomes available after all http redirects. + void SetHttpChannelFromEarlyHintPreloader(HttpBaseChannel* aChannel); + + protected: + // used to connect redirected-to channel in parent with just created + // ChildChannel. Used during redirects. + [[nodiscard]] bool ConnectChannel(const uint32_t& registrarId); + + [[nodiscard]] bool DoAsyncOpen( + nsIURI* uri, nsIURI* originalUri, nsIURI* docUri, + nsIReferrerInfo* aReferrerInfo, nsIURI* aAPIRedirectToURI, + nsIURI* topWindowUri, const uint32_t& loadFlags, + const RequestHeaderTuples& requestHeaders, const nsCString& requestMethod, + const Maybe<IPCStream>& uploadStream, const bool& uploadStreamHasHeaders, + const int16_t& priority, const ClassOfService& classOfService, + const uint8_t& redirectionLimit, const bool& allowSTS, + const uint32_t& thirdPartyFlags, const bool& doResumeAt, + const uint64_t& startPos, const nsCString& entityID, + const bool& allowSpdy, const bool& allowHttp3, const bool& allowAltSvc, + const bool& beConservative, const bool& bypassProxy, + const uint32_t& tlsFlags, const Maybe<LoadInfoArgs>& aLoadInfoArgs, + const uint32_t& aCacheKey, const uint64_t& aRequestContextID, + const Maybe<CorsPreflightArgs>& aCorsPreflightArgs, + const uint32_t& aInitialRwin, const bool& aBlockAuthPrompt, + const bool& aAllowStaleCacheContent, + const bool& aPreferCacheLoadOverBypass, const nsCString& aContentTypeHint, + const dom::RequestMode& aRequestMode, const uint32_t& aRedirectMode, + const uint64_t& aChannelId, const nsString& aIntegrityMetadata, + const uint64_t& aContentWindowId, + const nsTArray<PreferredAlternativeDataTypeParams>& + aPreferredAlternativeTypes, + const uint64_t& aBrowserId, const TimeStamp& aLaunchServiceWorkerStart, + const TimeStamp& aLaunchServiceWorkerEnd, + const TimeStamp& aDispatchFetchEventStart, + const TimeStamp& aDispatchFetchEventEnd, + const TimeStamp& aHandleFetchEventStart, + const TimeStamp& aHandleFetchEventEnd, + const bool& aForceMainDocumentChannel, + const TimeStamp& aNavigationStartTimeStamp, + const uint64_t& aEarlyHintPreloaderId, + const nsAString& aClassicScriptHintCharset, + const nsAString& aDocumentCharacterSet); + + virtual mozilla::ipc::IPCResult RecvSetPriority( + const int16_t& priority) override; + virtual mozilla::ipc::IPCResult RecvSetClassOfService( + const ClassOfService& cos) override; + virtual mozilla::ipc::IPCResult RecvSuspend() override; + virtual mozilla::ipc::IPCResult RecvResume() override; + virtual mozilla::ipc::IPCResult RecvCancel( + const nsresult& status, const uint32_t& requestBlockingReason, + const nsACString& reason, + const mozilla::Maybe<nsCString>& logString) override; + virtual mozilla::ipc::IPCResult RecvRedirect2Verify( + const nsresult& result, const RequestHeaderTuples& changedHeaders, + const uint32_t& aSourceRequestBlockingReason, + const Maybe<ChildLoadInfoForwarderArgs>& aTargetLoadInfoForwarder, + const uint32_t& loadFlags, nsIReferrerInfo* aReferrerInfo, + nsIURI* apiRedirectUri, + const Maybe<CorsPreflightArgs>& aCorsPreflightArgs) override; + virtual mozilla::ipc::IPCResult RecvDocumentChannelCleanup( + const bool& clearCacheEntry) override; + virtual mozilla::ipc::IPCResult RecvRemoveCorsPreflightCacheEntry( + nsIURI* uri, const mozilla::ipc::PrincipalInfo& requestingPrincipal, + const OriginAttributes& originAttributes) override; + virtual mozilla::ipc::IPCResult RecvBytesRead(const int32_t& aCount) override; + virtual mozilla::ipc::IPCResult RecvOpenOriginalCacheInputStream() override; + virtual void ActorDestroy(ActorDestroyReason why) override; + + friend class ParentChannelListener; + RefPtr<mozilla::dom::BrowserParent> mBrowserParent; + + [[nodiscard]] nsresult ReportSecurityMessage( + const nsAString& aMessageTag, const nsAString& aMessageCategory) override; + nsresult LogBlockedCORSRequest(const nsAString& aMessage, + const nsACString& aCategory, + bool aIsWarning = false) override; + nsresult LogMimeTypeMismatch(const nsACString& aMessageName, bool aWarning, + const nsAString& aURL, + const nsAString& aContentType) override; + + // Calls SendDeleteSelf and sets mIPCClosed to true because we should not + // send any more messages after that. Bug 1274886 + [[nodiscard]] bool DoSendDeleteSelf(); + // Called to notify the parent channel to not send any more IPC messages. + virtual mozilla::ipc::IPCResult RecvDeletingChannel() override; + + private: + already_AddRefed<nsITransportSecurityInfo> SecurityInfo(); + + // final step for Redirect2Verify procedure, will be invoked while both + // redirecting and redirected channel are ready or any error happened. + // OnRedirectVerifyCallback will be invoked for finishing the async + // redirect verification procedure. + void ContinueRedirect2Verify(const nsresult& aResult); + + void AsyncOpenFailed(nsresult aRv); + + // Request to pair with a HttpBackgroundChannelParent with the same channel + // id, a promise will be returned so the caller can append callbacks on it. + // If called multiple times before mBgParent is available, the same promise + // will be returned and the callbacks will be invoked in order. + [[nodiscard]] RefPtr<GenericNonExclusivePromise> WaitForBgParent( + uint64_t aChannelId); + + // Remove the association with background channel after main-thread IPC + // is about to be destroyed or no further event is going to be sent, i.e., + // DocumentChannelCleanup. + void CleanupBackgroundChannel(); + + // Check if the channel needs to enable the flow control on the IPC channel. + // That is, we may suspend the channel if the ODA-s to child process are not + // consumed quickly enough. Otherwise, memory explosion could happen. + bool NeedFlowControl(); + int32_t mSendWindowSize; + + friend class HttpBackgroundChannelParent; + + uint64_t mEarlyHintPreloaderId; + + RefPtr<HttpBaseChannel> mChannel; + nsCOMPtr<nsICacheEntry> mCacheEntry; + + nsCOMPtr<nsIChannel> mRedirectChannel; + nsCOMPtr<nsIAsyncVerifyRedirectCallback> mRedirectCallback; + + nsCOMPtr<nsILoadContext> mLoadContext; + RefPtr<nsHttpHandler> mHttpHandler; + + RefPtr<ParentChannelListener> mParentListener; + + RefPtr<ChannelEventQueue> mEventQ; + + RefPtr<HttpBackgroundChannelParent> mBgParent; + + MozPromiseHolder<GenericNonExclusivePromise> mPromise; + MozPromiseRequestHolder<GenericNonExclusivePromise> mRequest; + + // To calculate the delay caused by the e10s back-pressure suspension + TimeStamp mResumedTimestamp; + + Atomic<bool> mIPCClosed; // PHttpChannel actor has been Closed() + + // Corresponding redirect channel registrar Id. 0 means redirection is not + // started. + uint64_t mRedirectChannelId = 0; + + PBOverrideStatus mPBOverride; + + // Set to the canceled status value if the main channel was canceled. + nsresult mStatus; + + // The referrer info, set during nsHttpChannel::BeginConnect, to override the + // original one. This info will be sent in OnStartRequest. + nsCOMPtr<nsIReferrerInfo> mOverrideReferrerInfo; + + // The cookie string in Set-Cookie header. This info will be sent in + // OnStartRequest. + nsCString mCookie; + + // OnStatus is always called before OnProgress. + // Set true in OnStatus if next OnProgress can be ignored + // since the information can be recontructed from ODA. + uint8_t mIgnoreProgress : 1; + + uint8_t mHasSuspendedByBackPressure : 1; + + // Set if we get the result of and cache |mNeedFlowControl| + uint8_t mCacheNeedFlowControlInitialized : 1; + uint8_t mNeedFlowControl : 1; + uint8_t mSuspendedForFlowControl : 1; + + // Defaults to false. Is set to true at the begining of OnStartRequest. + // Used to ensure methods can't be called before OnStartRequest. + uint8_t mAfterOnStartRequestBegun : 1; + + // Number of events to wait before actually invoking AsyncOpen on the main + // channel. For each asynchronous step required before InvokeAsyncOpen, should + // increase 1 to mAsyncOpenBarrier and invoke TryInvokeAsyncOpen after + // finished. This attribute is main thread only. + uint8_t mAsyncOpenBarrier = 0; + + // When true, ODAs are sent from the socket process to the child process + // directly. + uint8_t mDataSentToChildProcess : 1; +}; + +NS_DEFINE_STATIC_IID_ACCESSOR(HttpChannelParent, HTTP_CHANNEL_PARENT_IID) + +} // namespace net +} // namespace mozilla + +#endif // mozilla_net_HttpChannelParent_h |