зеркало из https://github.com/mozilla/gecko-dev.git
391 строка
16 KiB
C++
391 строка
16 KiB
C++
/* -*- 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 "ADivertableParentChannel.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 "nsIAuthPromptProvider.h"
|
|
#include "mozilla/dom/ipc/IdType.h"
|
|
#include "nsIDeprecationWarner.h"
|
|
#include "nsIMultiPartChannel.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;
|
|
|
|
// Note: nsIInterfaceRequestor must be the first base so that do_QueryObject()
|
|
// works correctly on this object, as it's needed to compute a void* pointing to
|
|
// the beginning of this object.
|
|
|
|
class HttpChannelParent final : public nsIInterfaceRequestor,
|
|
public PHttpChannelParent,
|
|
public nsIParentRedirectingChannel,
|
|
public nsIProgressEventSink,
|
|
public ADivertableParentChannel,
|
|
public nsIAuthPromptProvider,
|
|
public nsIDeprecationWarner,
|
|
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_NSIAUTHPROMPTPROVIDER
|
|
NS_DECL_NSIDEPRECATIONWARNER
|
|
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 aStatus);
|
|
|
|
[[nodiscard]] bool Init(const HttpChannelCreationArgs& aOpenArgs);
|
|
|
|
// ADivertableParentChannel functions.
|
|
void DivertTo(nsIStreamListener* aListener) override;
|
|
[[nodiscard]] nsresult SuspendForDiversion() override;
|
|
[[nodiscard]] nsresult SuspendMessageDiversion() override;
|
|
[[nodiscard]] nsresult ResumeMessageDiversion() override;
|
|
[[nodiscard]] nsresult CancelDiversion() override;
|
|
|
|
// Calls OnStartRequest for "DivertTo" listener, then notifies child channel
|
|
// that it should divert OnDataAvailable and OnStopRequest calls to this
|
|
// parent channel.
|
|
void StartDiversion();
|
|
|
|
// Handles calling OnStart/Stop if there are errors during diversion.
|
|
// Called asynchronously from FailDiversion.
|
|
void NotifyDiversionFailed(nsresult aErrorCode);
|
|
|
|
// 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);
|
|
|
|
// 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);
|
|
|
|
protected:
|
|
// used to connect redirected-to channel in parent with just created
|
|
// ChildChannel. Used during redirects.
|
|
[[nodiscard]] bool ConnectChannel(const uint32_t& channelId,
|
|
const bool& shouldIntercept);
|
|
|
|
[[nodiscard]] bool DoAsyncOpen(
|
|
const URIParams& uri, const Maybe<URIParams>& originalUri,
|
|
const Maybe<URIParams>& docUri, nsIReferrerInfo* aReferrerInfo,
|
|
const Maybe<URIParams>& internalRedirectUri,
|
|
const Maybe<URIParams>& topWindowUri, const uint32_t& loadFlags,
|
|
const RequestHeaderTuples& requestHeaders, const nsCString& requestMethod,
|
|
const Maybe<IPCStream>& uploadStream, const bool& uploadStreamHasHeaders,
|
|
const int16_t& priority, const uint32_t& classOfService,
|
|
const uint8_t& redirectionLimit, const bool& allowSTS,
|
|
const uint32_t& thirdPartyFlags, const bool& doResumeAt,
|
|
const uint64_t& startPos, const nsCString& entityID,
|
|
const bool& chooseApplicationCache, const nsCString& appCacheClientID,
|
|
const bool& allowSpdy, const bool& allowAltSvc,
|
|
const bool& beConservative, const uint32_t& tlsFlags,
|
|
const Maybe<LoadInfoArgs>& aLoadInfoArgs,
|
|
const Maybe<nsHttpResponseHead>& aSynthesizedResponseHead,
|
|
const nsCString& aSecurityInfoSerialization, const uint32_t& aCacheKey,
|
|
const uint64_t& aRequestContextID,
|
|
const Maybe<CorsPreflightArgs>& aCorsPreflightArgs,
|
|
const uint32_t& aInitialRwin, const bool& aBlockAuthPrompt,
|
|
const bool& aSuspendAfterSynthesizeResponse,
|
|
const bool& aAllowStaleCacheContent,
|
|
const bool& aPreferCacheLoadOverBypass, const nsCString& aContentTypeHint,
|
|
const uint32_t& aCorsMode, const uint32_t& aRedirectMode,
|
|
const uint64_t& aChannelId, const nsString& aIntegrityMetadata,
|
|
const uint64_t& aContentWindowId,
|
|
const nsTArray<PreferredAlternativeDataTypeParams>&
|
|
aPreferredAlternativeTypes,
|
|
const uint64_t& aTopLevelOuterContentWindowId,
|
|
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 bool& hasNonEmptySandboxingFlag);
|
|
|
|
virtual mozilla::ipc::IPCResult RecvSetPriority(
|
|
const int16_t& priority) override;
|
|
virtual mozilla::ipc::IPCResult RecvSetClassOfService(
|
|
const uint32_t& cos) override;
|
|
virtual mozilla::ipc::IPCResult RecvSetCacheTokenCachedCharset(
|
|
const nsCString& charset) 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) 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,
|
|
const Maybe<URIParams>& apiRedirectUri,
|
|
const Maybe<CorsPreflightArgs>& aCorsPreflightArgs,
|
|
const bool& aChooseAppcache) override;
|
|
virtual mozilla::ipc::IPCResult RecvDocumentChannelCleanup(
|
|
const bool& clearCacheEntry) override;
|
|
virtual mozilla::ipc::IPCResult RecvMarkOfflineCacheEntryAsForeign() override;
|
|
virtual mozilla::ipc::IPCResult RecvDivertOnDataAvailable(
|
|
const nsCString& data, const uint64_t& offset,
|
|
const uint32_t& count) override;
|
|
virtual mozilla::ipc::IPCResult RecvDivertOnStopRequest(
|
|
const nsresult& statusCode) override;
|
|
virtual mozilla::ipc::IPCResult RecvDivertComplete() override;
|
|
virtual mozilla::ipc::IPCResult RecvRemoveCorsPreflightCacheEntry(
|
|
const URIParams& uri,
|
|
const mozilla::ipc::PrincipalInfo& requestingPrincipal) override;
|
|
virtual mozilla::ipc::IPCResult RecvBytesRead(const int32_t& aCount) override;
|
|
virtual mozilla::ipc::IPCResult RecvOpenOriginalCacheInputStream() override;
|
|
virtual mozilla::ipc::IPCResult RecvOpenAltDataCacheInputStream(
|
|
const nsCString& aType) override;
|
|
virtual void ActorDestroy(ActorDestroyReason why) override;
|
|
|
|
// Supporting function for ADivertableParentChannel.
|
|
[[nodiscard]] nsresult ResumeForDiversion();
|
|
|
|
// Asynchronously calls NotifyDiversionFailed.
|
|
void FailDiversion(nsresult aErrorCode);
|
|
|
|
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) 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;
|
|
virtual mozilla::ipc::IPCResult RecvFinishInterceptedRedirect() override;
|
|
|
|
private:
|
|
void UpdateAndSerializeSecurityInfo(nsACString& aSerializedSecurityInfoOut);
|
|
|
|
void DivertOnDataAvailable(const nsCString& data, const uint64_t& offset,
|
|
const uint32_t& count);
|
|
void DivertOnStopRequest(const nsresult& statusCode);
|
|
void DivertComplete();
|
|
void MaybeFlushPendingDiversion();
|
|
void ResponseSynthesized();
|
|
|
|
// 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();
|
|
|
|
// 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;
|
|
friend class DivertDataAvailableEvent;
|
|
friend class DivertStopRequestEvent;
|
|
friend class DivertCompleteEvent;
|
|
|
|
RefPtr<HttpBaseChannel> mChannel;
|
|
nsCOMPtr<nsICacheEntry> mCacheEntry;
|
|
|
|
nsCOMPtr<nsIChannel> mRedirectChannel;
|
|
nsCOMPtr<nsIAsyncVerifyRedirectCallback> mRedirectCallback;
|
|
|
|
UniquePtr<class nsHttpChannel::OfflineCacheEntryAsForeignMarker>
|
|
mOfflineForeignMarker;
|
|
nsCOMPtr<nsILoadContext> mLoadContext;
|
|
RefPtr<nsHttpHandler> mHttpHandler;
|
|
|
|
RefPtr<ParentChannelListener> mParentListener;
|
|
// The listener we are diverting to or will divert to if mPendingDiversion
|
|
// is set.
|
|
nsCOMPtr<nsIStreamListener> mDivertListener;
|
|
|
|
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 mSentRedirect1BeginFailed : 1;
|
|
uint8_t mReceivedRedirect2Verify : 1;
|
|
uint8_t mHasSuspendedByBackPressure : 1;
|
|
|
|
// Indicates that diversion has been requested, but we could not start it
|
|
// yet because the channel is still being opened with a synthesized response.
|
|
uint8_t mPendingDiversion : 1;
|
|
// Once set, no OnStart/OnData/OnStop calls should be accepted; conversely, it
|
|
// must be set when RecvDivertOnData/~DivertOnStop/~DivertComplete are
|
|
// received from the child channel.
|
|
uint8_t mDivertingFromChild : 1;
|
|
|
|
// Set if OnStart|StopRequest was called during a diversion from the child.
|
|
uint8_t mDivertedOnStartRequest : 1;
|
|
|
|
uint8_t mSuspendedForDiversion : 1;
|
|
|
|
// Set if this channel should be suspended after synthesizing a response.
|
|
uint8_t mSuspendAfterSynthesizeResponse : 1;
|
|
// Set if this channel will synthesize its response.
|
|
uint8_t mWillSynthesizeResponse : 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;
|
|
};
|
|
|
|
NS_DEFINE_STATIC_IID_ACCESSOR(HttpChannelParent, HTTP_CHANNEL_PARENT_IID)
|
|
|
|
} // namespace net
|
|
} // namespace mozilla
|
|
|
|
#endif // mozilla_net_HttpChannelParent_h
|