From ce3b50b737d16454029e24d46bc4966fe67c22d7 Mon Sep 17 00:00:00 2001 From: Matt Woodrow Date: Mon, 13 Jan 2020 00:28:13 +0000 Subject: [PATCH] Bug 1607987 - Split DocumentChannelChild into two classes. r=jya This shouldn't have any functional changes, and adds some new comments to explain the purpose of the classes a bit better. Differential Revision: https://phabricator.services.mozilla.com/D59265 --HG-- rename : netwerk/ipc/DocumentChannelChild.cpp => netwerk/ipc/DocumentChannel.cpp rename : netwerk/ipc/DocumentChannelChild.h => netwerk/ipc/DocumentChannel.h extra : source : ca6f43c061311dfe3e45f0216e320872d9d62cd4 --- docshell/base/nsDocShell.cpp | 9 +- netwerk/ipc/DocumentChannel.cpp | 378 +++++++++++++++++++++++++++ netwerk/ipc/DocumentChannel.h | 109 ++++++++ netwerk/ipc/DocumentChannelChild.cpp | 342 +----------------------- netwerk/ipc/DocumentChannelChild.h | 77 +----- netwerk/ipc/moz.build | 2 + 6 files changed, 513 insertions(+), 404 deletions(-) create mode 100644 netwerk/ipc/DocumentChannel.cpp create mode 100644 netwerk/ipc/DocumentChannel.h diff --git a/docshell/base/nsDocShell.cpp b/docshell/base/nsDocShell.cpp index d22b344a10f1..72e90686e91f 100644 --- a/docshell/base/nsDocShell.cpp +++ b/docshell/base/nsDocShell.cpp @@ -72,6 +72,7 @@ #include "mozilla/dom/LoadURIOptionsBinding.h" #include "mozilla/dom/JSWindowActorChild.h" +#include "mozilla/net/DocumentChannel.h" #include "mozilla/net/DocumentChannelChild.h" #include "mozilla/net/UrlClassifierFeatureFactory.h" #include "ReferrerInfo.h" @@ -5828,7 +5829,7 @@ nsDocShell::OnStateChange(nsIWebProgress* aProgress, nsIRequest* aRequest, // If we are starting a DocumentChannel, we need to pass the timing // statistics so that should a process switch occur, the starting type can // be passed to the new DocShell running in the other content process. - if (RefPtr docChannel = do_QueryObject(aRequest)) { + if (RefPtr docChannel = do_QueryObject(aRequest)) { docChannel->SetNavigationTiming(mTiming); } } @@ -5922,7 +5923,7 @@ void nsDocShell::OnRedirectStateChange(nsIChannel* aOldChannel, // of redirects handled in the parent process. // Query the full redirect chain directly, so that we can add history // entries for them. - if (RefPtr docChannel = do_QueryObject(aOldChannel)) { + if (RefPtr docChannel = do_QueryObject(aOldChannel)) { nsCOMPtr previousURI; uint32_t previousFlags = 0; docChannel->GetLastVisit(getter_AddRefs(previousURI), &previousFlags); @@ -10229,8 +10230,8 @@ nsresult nsDocShell::OpenInitializedChannel(nsIChannel* aChannel, // Let the client channel helper know if we are using DocumentChannel, // since redirects get handled in the parent process in that case. - RefPtr docChannel = do_QueryObject(aChannel); - if (docChannel) { + RefPtr docChannel = do_QueryObject(aChannel); + if (docChannel && XRE_IsContentProcess()) { bool pluginsAllowed = true; GetAllowPlugins(&pluginsAllowed); docChannel->SetDocumentOpenFlags(aOpenFlags, pluginsAllowed); diff --git a/netwerk/ipc/DocumentChannel.cpp b/netwerk/ipc/DocumentChannel.cpp new file mode 100644 index 000000000000..471eb04d93dc --- /dev/null +++ b/netwerk/ipc/DocumentChannel.cpp @@ -0,0 +1,378 @@ +/* -*- 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/. */ + +#include "DocumentChannel.h" + +#include "SerializedLoadContext.h" +#include "mozIThirdPartyUtil.h" +#include "mozilla/LoadInfo.h" +#include "mozilla/dom/BrowserChild.h" +#include "mozilla/dom/ContentChild.h" +#include "mozilla/dom/nsCSPContext.h" +#include "mozilla/extensions/StreamFilterParent.h" +#include "mozilla/ipc/IPCStreamUtils.h" +#include "mozilla/ipc/URIUtils.h" +#include "mozilla/net/HttpChannelChild.h" +#include "mozilla/net/NeckoChild.h" +#include "mozilla/net/UrlClassifierCommon.h" +#include "nsContentSecurityManager.h" +#include "nsDocShellLoadState.h" +#include "nsHttpHandler.h" +#include "nsIInputStreamChannel.h" +#include "nsQueryObject.h" +#include "nsSerializationHelper.h" +#include "nsStreamListenerWrapper.h" +#include "nsStringStream.h" +#include "nsURLHelper.h" + +using namespace mozilla::dom; +using namespace mozilla::ipc; + +extern mozilla::LazyLogModule gDocumentChannelLog; +#define LOG(fmt) MOZ_LOG(gDocumentChannelLog, mozilla::LogLevel::Verbose, fmt) + +namespace mozilla { +namespace net { + +//----------------------------------------------------------------------------- +// DocumentChannel::nsISupports + +NS_IMPL_ADDREF(DocumentChannel) +NS_IMPL_RELEASE(DocumentChannel) + +NS_INTERFACE_MAP_BEGIN(DocumentChannel) + NS_INTERFACE_MAP_ENTRY(nsIRequest) + NS_INTERFACE_MAP_ENTRY(nsIChannel) + NS_INTERFACE_MAP_ENTRY(nsITraceableChannel) + NS_INTERFACE_MAP_ENTRY_CONCRETE(DocumentChannel) + NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIRequest) + /* previous macro end with "else" keyword */ { + foundInterface = 0; + if (mWasOpened && aIID == NS_GET_IID(nsIHttpChannel)) { + // DocumentChannel generally is doing an http connection + // internally, but doesn't implement the interface. Everything + // before AsyncOpen should be duplicated in the parent process + // on the real http channel, but anything trying to QI to nsIHttpChannel + // after that will be failing and get confused. + NS_WARNING( + "Trying to request nsIHttpChannel from DocumentChannel, this is " + "likely broken"); + } else if (aIID == NS_GET_IID(nsIPropertyBag)) { + NS_WARNING( + "Trying to request nsIPropertyBag from DocumentChanneld, this " + "will be broken"); + } else if (aIID == NS_GET_IID(nsIPropertyBag2)) { + NS_WARNING( + "Trying to request nsIPropertyBag2 from DocumentChannel, this " + "will be broken"); + } else if (aIID == NS_GET_IID(nsIWritablePropertyBag)) { + NS_WARNING( + "Trying to request nsIWritablePropertyBag from DocumentChannel, " + "this will be broken"); + } else if (aIID == NS_GET_IID(nsIWritablePropertyBag2)) { + NS_WARNING( + "Trying to request nsIWritablePropertyBag2 from " + "DocumentChannel, this will be broken"); + } + } + if (false) // So we fallback properly in the final macro +NS_INTERFACE_MAP_END + +DocumentChannel::DocumentChannel(nsDocShellLoadState* aLoadState, + net::LoadInfo* aLoadInfo, + const nsString* aInitiatorType, + nsLoadFlags aLoadFlags, uint32_t aLoadType, + uint32_t aCacheKey, bool aIsActive, + bool aIsTopLevelDoc, + bool aHasNonEmptySandboxingFlags) + : mAsyncOpenTime(TimeStamp::Now()), + mLoadState(aLoadState), + mInitiatorType(aInitiatorType ? Some(*aInitiatorType) : Nothing()), + mLoadType(aLoadType), + mCacheKey(aCacheKey), + mIsActive(aIsActive), + mIsTopLevelDoc(aIsTopLevelDoc), + mHasNonEmptySandboxingFlags(aHasNonEmptySandboxingFlags), + mLoadFlags(aLoadFlags), + mURI(aLoadState->URI()), + mLoadInfo(aLoadInfo) { + LOG(("DocumentChannel ctor [this=%p, uri=%s]", this, + aLoadState->URI()->GetSpecOrDefault().get())); + RefPtr handler = nsHttpHandler::GetInstance(); + uint64_t channelId; + Unused << handler->NewChannelId(channelId); + mChannelId = channelId; +} + +NS_IMETHODIMP +DocumentChannel::AsyncOpen(nsIStreamListener* aListener) { + MOZ_CRASH("If we get here, something is broken"); + return NS_ERROR_NOT_IMPLEMENTED; +} + +nsDocShell* DocumentChannel::GetDocShell() { + nsCOMPtr loadContext; + NS_QueryNotificationCallbacks(this, loadContext); + if (!loadContext) { + return nullptr; + } + nsCOMPtr domWindow; + loadContext->GetAssociatedWindow(getter_AddRefs(domWindow)); + if (!domWindow) { + return nullptr; + } + auto* pDomWindow = nsPIDOMWindowOuter::From(domWindow); + nsIDocShell* docshell = pDomWindow->GetDocShell(); + return nsDocShell::Cast(docshell); +} + +//----------------------------------------------------------------------------- +// DocumentChannel::nsITraceableChannel +//----------------------------------------------------------------------------- + +NS_IMETHODIMP +DocumentChannel::SetNewListener(nsIStreamListener* aListener, + nsIStreamListener** _retval) { + NS_ENSURE_ARG_POINTER(aListener); + + nsCOMPtr wrapper = new nsStreamListenerWrapper(mListener); + + wrapper.forget(_retval); + mListener = aListener; + return NS_OK; +} + +NS_IMETHODIMP +DocumentChannel::Cancel(nsresult aStatusCode) { + MOZ_CRASH("If we get here, something is broken"); + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP +DocumentChannel::Suspend() { + MOZ_CRASH("If we get here, something is broken"); + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP +DocumentChannel::Resume() { + MOZ_CRASH("If we get here, something is broken"); + return NS_ERROR_NOT_IMPLEMENTED; +} + +//----------------------------------------------------------------------------- +// Remainder of nsIRequest/nsIChannel. +//----------------------------------------------------------------------------- + +NS_IMETHODIMP DocumentChannel::GetNotificationCallbacks( + nsIInterfaceRequestor** aCallbacks) { + nsCOMPtr callbacks(mCallbacks); + callbacks.forget(aCallbacks); + return NS_OK; +} + +NS_IMETHODIMP DocumentChannel::SetNotificationCallbacks( + nsIInterfaceRequestor* aNotificationCallbacks) { + mCallbacks = aNotificationCallbacks; + return NS_OK; +} + +NS_IMETHODIMP DocumentChannel::GetLoadGroup(nsILoadGroup** aLoadGroup) { + nsCOMPtr loadGroup(mLoadGroup); + loadGroup.forget(aLoadGroup); + return NS_OK; +} + +NS_IMETHODIMP DocumentChannel::SetLoadGroup(nsILoadGroup* aLoadGroup) { + mLoadGroup = aLoadGroup; + return NS_OK; +} + +NS_IMETHODIMP DocumentChannel::GetStatus(nsresult* aStatus) { + *aStatus = mStatus; + return NS_OK; +} + +NS_IMETHODIMP DocumentChannel::GetName(nsACString& aResult) { + if (!mURI) { + aResult.Truncate(); + return NS_OK; + } + nsCString spec; + nsresult rv = mURI->GetSpec(spec); + NS_ENSURE_SUCCESS(rv, rv); + + aResult.AssignLiteral("documentchannel:"); + aResult.Append(spec); + return NS_OK; +} + +NS_IMETHODIMP DocumentChannel::IsPending(bool* aResult) { + *aResult = mIsPending; + return NS_OK; +} + +NS_IMETHODIMP DocumentChannel::GetLoadFlags(nsLoadFlags* aLoadFlags) { + *aLoadFlags = mLoadFlags; + return NS_OK; +} + +NS_IMETHODIMP +DocumentChannel::GetTRRMode(nsIRequest::TRRMode* aTRRMode) { + return GetTRRModeImpl(aTRRMode); +} + +NS_IMETHODIMP +DocumentChannel::SetTRRMode(nsIRequest::TRRMode aTRRMode) { + return SetTRRModeImpl(aTRRMode); +} + +NS_IMETHODIMP DocumentChannel::SetLoadFlags(nsLoadFlags aLoadFlags) { + mLoadFlags = aLoadFlags; + return NS_OK; +} + +NS_IMETHODIMP DocumentChannel::GetOriginalURI(nsIURI** aOriginalURI) { + nsCOMPtr originalURI = + mLoadState->OriginalURI() ? mLoadState->OriginalURI() : mLoadState->URI(); + originalURI.forget(aOriginalURI); + return NS_OK; +} + +NS_IMETHODIMP DocumentChannel::SetOriginalURI(nsIURI* aOriginalURI) { + MOZ_CRASH("If we get here, something is broken"); + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP DocumentChannel::GetURI(nsIURI** aURI) { + nsCOMPtr uri(mURI); + uri.forget(aURI); + return NS_OK; +} + +NS_IMETHODIMP DocumentChannel::GetOwner(nsISupports** aOwner) { + nsCOMPtr owner(mOwner); + owner.forget(aOwner); + return NS_OK; +} + +NS_IMETHODIMP DocumentChannel::SetOwner(nsISupports* aOwner) { + mOwner = aOwner; + return NS_OK; +} + +NS_IMETHODIMP DocumentChannel::GetSecurityInfo(nsISupports** aSecurityInfo) { + *aSecurityInfo = nullptr; + return NS_OK; +} + +NS_IMETHODIMP DocumentChannel::GetContentType(nsACString& aContentType) { + MOZ_CRASH("If we get here, something is broken"); + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP DocumentChannel::SetContentType(const nsACString& aContentType) { + MOZ_CRASH("If we get here, something is broken"); + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP DocumentChannel::GetContentCharset(nsACString& aContentCharset) { + MOZ_CRASH("If we get here, something is broken"); + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP DocumentChannel::SetContentCharset( + const nsACString& aContentCharset) { + MOZ_CRASH("If we get here, something is broken"); + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP DocumentChannel::GetContentLength(int64_t* aContentLength) { + MOZ_CRASH("If we get here, something is broken"); + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP DocumentChannel::SetContentLength(int64_t aContentLength) { + MOZ_CRASH("If we get here, something is broken"); + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP DocumentChannel::Open(nsIInputStream** aStream) { + MOZ_CRASH("If we get here, something is broken"); + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP DocumentChannel::GetContentDisposition( + uint32_t* aContentDisposition) { + MOZ_CRASH("If we get here, something is broken"); + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP DocumentChannel::SetContentDisposition( + uint32_t aContentDisposition) { + MOZ_CRASH("If we get here, something is broken"); + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP DocumentChannel::GetContentDispositionFilename( + nsAString& aContentDispositionFilename) { + MOZ_CRASH("If we get here, something will be broken"); + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP DocumentChannel::SetContentDispositionFilename( + const nsAString& aContentDispositionFilename) { + MOZ_CRASH("If we get here, something will be broken"); + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP DocumentChannel::GetContentDispositionHeader( + nsACString& aContentDispositionHeader) { + MOZ_CRASH("If we get here, something is broken"); + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP DocumentChannel::GetLoadInfo(nsILoadInfo** aLoadInfo) { + nsCOMPtr loadInfo(mLoadInfo); + loadInfo.forget(aLoadInfo); + return NS_OK; +} + +NS_IMETHODIMP DocumentChannel::SetLoadInfo(nsILoadInfo* aLoadInfo) { + MOZ_CRASH("If we get here, something is broken"); + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP DocumentChannel::GetIsDocument(bool* aIsDocument) { + return NS_GetIsDocumentChannel(this, aIsDocument); +} + +NS_IMETHODIMP DocumentChannel::GetCanceled(bool* aCanceled) { + *aCanceled = mCanceled; + return NS_OK; +} + +//----------------------------------------------------------------------------- +// nsIIdentChannel +//----------------------------------------------------------------------------- + +NS_IMETHODIMP +DocumentChannel::GetChannelId(uint64_t* aChannelId) { + *aChannelId = mChannelId; + return NS_OK; +} + +NS_IMETHODIMP +DocumentChannel::SetChannelId(uint64_t aChannelId) { + mChannelId = aChannelId; + return NS_OK; +} + +} // namespace net +} // namespace mozilla + +#undef LOG diff --git a/netwerk/ipc/DocumentChannel.h b/netwerk/ipc/DocumentChannel.h new file mode 100644 index 000000000000..f20da014f1b3 --- /dev/null +++ b/netwerk/ipc/DocumentChannel.h @@ -0,0 +1,109 @@ +/* -*- 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_DocumentChannel_h +#define mozilla_net_DocumentChannel_h + +#include "mozilla/net/PDocumentChannelChild.h" +#include "nsDOMNavigationTiming.h" +#include "nsIChannel.h" +#include "nsIChildChannel.h" +#include "nsITraceableChannel.h" + +#define DOCUMENT_CHANNEL_IID \ + { \ + 0x6977bc44, 0xb1db, 0x41b7, { \ + 0xb5, 0xc5, 0xe2, 0x13, 0x68, 0x22, 0xc9, 0x8f \ + } \ + } + +namespace mozilla { +namespace net { + +/** + * DocumentChannel is a protocol agnostic placeholder nsIChannel implementation + * that we use so that nsDocShell knows about a connecting load. It transfers + * all data into a DocumentLoadListener (running in the parent process), which + * will create the real channel for the connection, and decide which process to + * load the resulting document in. If the document is to be loaded in the + * current process, then we'll synthesize a redirect replacing this placeholder + * channel with the real one, otherwise the originating docshell will be removed + * during the process switch. + */ +class DocumentChannel : public nsIIdentChannel, public nsITraceableChannel { + public: + NS_DECL_ISUPPORTS + NS_DECL_NSIREQUEST + NS_DECL_NSICHANNEL + NS_DECL_NSIIDENTCHANNEL + NS_DECL_NSITRACEABLECHANNEL + + NS_DECLARE_STATIC_IID_ACCESSOR(DOCUMENT_CHANNEL_IID) + + DocumentChannel(nsDocShellLoadState* aLoadState, class LoadInfo* aLoadInfo, + const nsString* aInitiatorType, nsLoadFlags aLoadFlags, + uint32_t aLoadType, uint32_t aCacheKey, bool aIsActive, + bool aIsTopLevelDoc, bool aHasNonEmptySandboxingFlags); + + const nsTArray& GetRedirectChain() const { + return mRedirects; + } + + void GetLastVisit(nsIURI** aURI, uint32_t* aChannelRedirectFlags) const { + *aURI = do_AddRef(mLastVisitInfo.uri()).take(); + *aChannelRedirectFlags = mLastVisitInfo.previousFlags(); + } + + void SetDocumentOpenFlags(uint32_t aFlags, bool aPluginsAllowed) { + mDocumentOpenFlags = Some(aFlags); + mPluginsAllowed = aPluginsAllowed; + } + + void SetNavigationTiming(nsDOMNavigationTiming* aTiming) { + mTiming = aTiming; + } + + protected: + nsDocShell* GetDocShell(); + + virtual ~DocumentChannel() = default; + + LastVisitInfo mLastVisitInfo; + nsTArray mRedirects; + + const TimeStamp mAsyncOpenTime; + const RefPtr mLoadState; + const Maybe mInitiatorType; + const uint32_t mLoadType; + const uint32_t mCacheKey; + const bool mIsActive; + const bool mIsTopLevelDoc; + const bool mHasNonEmptySandboxingFlags; + + nsresult mStatus = NS_OK; + bool mCanceled = false; + Maybe mDocumentOpenFlags; + bool mIsPending = false; + bool mWasOpened = false; + uint64_t mChannelId; + uint32_t mLoadFlags = LOAD_NORMAL; + const nsCOMPtr mURI; + nsCOMPtr mLoadGroup; + nsCOMPtr mLoadInfo; + nsCOMPtr mCallbacks; + nsCOMPtr mListener; + nsCOMPtr mOwner; + bool mPluginsAllowed = false; + RefPtr mTiming; +}; + +NS_DEFINE_STATIC_IID_ACCESSOR(DocumentChannel, DOCUMENT_CHANNEL_IID) + +} // namespace net +} // namespace mozilla + +#endif // mozilla_net_DocumentChannel_h diff --git a/netwerk/ipc/DocumentChannelChild.cpp b/netwerk/ipc/DocumentChannelChild.cpp index 5ba2d2813651..c4ee606368b6 100644 --- a/netwerk/ipc/DocumentChannelChild.cpp +++ b/netwerk/ipc/DocumentChannelChild.cpp @@ -7,28 +7,6 @@ #include "DocumentChannelChild.h" -#include "SerializedLoadContext.h" -#include "mozIThirdPartyUtil.h" -#include "mozilla/LoadInfo.h" -#include "mozilla/dom/BrowserChild.h" -#include "mozilla/dom/ContentChild.h" -#include "mozilla/dom/nsCSPContext.h" -#include "mozilla/extensions/StreamFilterParent.h" -#include "mozilla/ipc/IPCStreamUtils.h" -#include "mozilla/ipc/URIUtils.h" -#include "mozilla/net/HttpChannelChild.h" -#include "mozilla/net/NeckoChild.h" -#include "mozilla/net/UrlClassifierCommon.h" -#include "nsContentSecurityManager.h" -#include "nsDocShellLoadState.h" -#include "nsHttpHandler.h" -#include "nsIInputStreamChannel.h" -#include "nsQueryObject.h" -#include "nsSerializationHelper.h" -#include "nsStreamListenerWrapper.h" -#include "nsStringStream.h" -#include "nsURLHelper.h" - using namespace mozilla::dom; using namespace mozilla::ipc; @@ -41,70 +19,23 @@ namespace net { //----------------------------------------------------------------------------- // DocumentChannelChild::nsISupports -NS_IMPL_ADDREF(DocumentChannelChild) -NS_IMPL_RELEASE(DocumentChannelChild) - NS_INTERFACE_MAP_BEGIN(DocumentChannelChild) - NS_INTERFACE_MAP_ENTRY(nsIRequest) - NS_INTERFACE_MAP_ENTRY(nsIChannel) - NS_INTERFACE_MAP_ENTRY(nsITraceableChannel) NS_INTERFACE_MAP_ENTRY(nsIAsyncVerifyRedirectCallback) - NS_INTERFACE_MAP_ENTRY_CONCRETE(DocumentChannelChild) - NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIRequest) - /* previous macro end with "else" keyword */ { - foundInterface = 0; - if (mWasOpened && aIID == NS_GET_IID(nsIHttpChannel)) { - // DocumentChannelChild generally is doing an http connection - // internally, but doesn't implement the interface. Everything - // before AsyncOpen should be duplicated in the parent process - // on the real http channel, but anything trying to QI to nsIHttpChannel - // after that will be failing and get confused. - NS_WARNING( - "Trying to request nsIHttpChannel from DocumentChannelChild, this is " - "likely broken"); - } else if (aIID == NS_GET_IID(nsIPropertyBag)) { - NS_WARNING( - "Trying to request nsIPropertyBag from DocumentChannelChild, this " - "will be broken"); - } else if (aIID == NS_GET_IID(nsIPropertyBag2)) { - NS_WARNING( - "Trying to request nsIPropertyBag2 from DocumentChannelChild, this " - "will be broken"); - } else if (aIID == NS_GET_IID(nsIWritablePropertyBag)) { - NS_WARNING( - "Trying to request nsIWritablePropertyBag from DocumentChannelChild, " - "this will be broken"); - } else if (aIID == NS_GET_IID(nsIWritablePropertyBag2)) { - NS_WARNING( - "Trying to request nsIWritablePropertyBag2 from " - "DocumentChannelChild, this will be broken"); - } - } - if (false) // So we fallback properly in the final macro -NS_INTERFACE_MAP_END +NS_INTERFACE_MAP_END_INHERITING(DocumentChannel) + +NS_IMPL_ADDREF_INHERITED(DocumentChannelChild, DocumentChannel) +NS_IMPL_RELEASE_INHERITED(DocumentChannelChild, DocumentChannel) DocumentChannelChild::DocumentChannelChild( nsDocShellLoadState* aLoadState, net::LoadInfo* aLoadInfo, const nsString* aInitiatorType, nsLoadFlags aLoadFlags, uint32_t aLoadType, uint32_t aCacheKey, bool aIsActive, bool aIsTopLevelDoc, bool aHasNonEmptySandboxingFlags) - : mAsyncOpenTime(TimeStamp::Now()), - mLoadState(aLoadState), - mInitiatorType(aInitiatorType ? Some(*aInitiatorType) : Nothing()), - mLoadType(aLoadType), - mCacheKey(aCacheKey), - mIsActive(aIsActive), - mIsTopLevelDoc(aIsTopLevelDoc), - mHasNonEmptySandboxingFlags(aHasNonEmptySandboxingFlags), - mLoadFlags(aLoadFlags), - mURI(aLoadState->URI()), - mLoadInfo(aLoadInfo) { + : DocumentChannel(aLoadState, aLoadInfo, aInitiatorType, aLoadFlags, + aLoadType, aCacheKey, aIsActive, aIsTopLevelDoc, + aHasNonEmptySandboxingFlags) { LOG(("DocumentChannelChild ctor [this=%p, uri=%s]", this, aLoadState->URI()->GetSpecOrDefault().get())); - RefPtr handler = nsHttpHandler::GetInstance(); - uint64_t channelId; - Unused << handler->NewChannelId(channelId); - mChannelId = channelId; } DocumentChannelChild::~DocumentChannelChild() { @@ -130,12 +61,12 @@ DocumentChannelChild::AsyncOpen(nsIStreamListener* aListener) { NS_ENSURE_SUCCESS(rv, rv); nsCOMPtr topWindowURI; - nsCOMPtr uriBeingLoaded = - AntiTrackingCommon::MaybeGetDocumentURIBeingLoaded(this); nsCOMPtr contentBlockingAllowListPrincipal; nsCOMPtr util = services::GetThirdPartyUtil(); if (util) { + nsCOMPtr uriBeingLoaded = + AntiTrackingCommon::MaybeGetDocumentURIBeingLoaded(this); nsCOMPtr win; rv = util->GetTopWindowForChannel(this, uriBeingLoaded, getter_AddRefs(win)); @@ -225,22 +156,6 @@ DocumentChannelChild::AsyncOpen(nsIStreamListener* aListener) { return NS_OK; } -nsDocShell* DocumentChannelChild::GetDocShell() { - nsCOMPtr loadContext; - NS_QueryNotificationCallbacks(this, loadContext); - if (!loadContext) { - return nullptr; - } - nsCOMPtr domWindow; - loadContext->GetAssociatedWindow(getter_AddRefs(domWindow)); - if (!domWindow) { - return nullptr; - } - auto* pDomWindow = nsPIDOMWindowOuter::From(domWindow); - nsIDocShell* docshell = pDomWindow->GetDocShell(); - return nsDocShell::Cast(docshell); -} - IPCResult DocumentChannelChild::RecvFailedAsyncOpen( const nsresult& aStatusCode) { ShutdownListeners(aStatusCode); @@ -511,22 +426,6 @@ mozilla::ipc::IPCResult DocumentChannelChild::RecvAttachStreamFilter( return IPC_OK(); } -//----------------------------------------------------------------------------- -// DocumentChannelChild::nsITraceableChannel -//----------------------------------------------------------------------------- - -NS_IMETHODIMP -DocumentChannelChild::SetNewListener(nsIStreamListener* aListener, - nsIStreamListener** _retval) { - NS_ENSURE_ARG_POINTER(aListener); - - nsCOMPtr wrapper = new nsStreamListenerWrapper(mListener); - - wrapper.forget(_retval); - mListener = aListener; - return NS_OK; -} - NS_IMETHODIMP DocumentChannelChild::Cancel(nsresult aStatusCode) { if (mCanceled) { @@ -543,229 +442,6 @@ DocumentChannelChild::Cancel(nsresult aStatusCode) { return NS_OK; } -NS_IMETHODIMP -DocumentChannelChild::Suspend() { - MOZ_CRASH("If we get here, something is broken"); - return NS_ERROR_NOT_IMPLEMENTED; -} - -NS_IMETHODIMP -DocumentChannelChild::Resume() { - MOZ_CRASH("If we get here, something is broken"); - return NS_ERROR_NOT_IMPLEMENTED; -} - -//----------------------------------------------------------------------------- -// Remainder of nsIRequest/nsIChannel. -//----------------------------------------------------------------------------- - -NS_IMETHODIMP DocumentChannelChild::GetNotificationCallbacks( - nsIInterfaceRequestor** aCallbacks) { - nsCOMPtr callbacks(mCallbacks); - callbacks.forget(aCallbacks); - return NS_OK; -} - -NS_IMETHODIMP DocumentChannelChild::SetNotificationCallbacks( - nsIInterfaceRequestor* aNotificationCallbacks) { - mCallbacks = aNotificationCallbacks; - return NS_OK; -} - -NS_IMETHODIMP DocumentChannelChild::GetLoadGroup(nsILoadGroup** aLoadGroup) { - nsCOMPtr loadGroup(mLoadGroup); - loadGroup.forget(aLoadGroup); - return NS_OK; -} - -NS_IMETHODIMP DocumentChannelChild::SetLoadGroup(nsILoadGroup* aLoadGroup) { - mLoadGroup = aLoadGroup; - return NS_OK; -} - -NS_IMETHODIMP DocumentChannelChild::GetStatus(nsresult* aStatus) { - *aStatus = mStatus; - return NS_OK; -} - -NS_IMETHODIMP DocumentChannelChild::GetName(nsACString& aResult) { - if (!mURI) { - aResult.Truncate(); - return NS_OK; - } - nsCString spec; - nsresult rv = mURI->GetSpec(spec); - NS_ENSURE_SUCCESS(rv, rv); - - aResult.AssignLiteral("documentchannel:"); - aResult.Append(spec); - return NS_OK; -} - -NS_IMETHODIMP DocumentChannelChild::IsPending(bool* aResult) { - *aResult = mIsPending; - return NS_OK; -} - -NS_IMETHODIMP DocumentChannelChild::GetLoadFlags(nsLoadFlags* aLoadFlags) { - *aLoadFlags = mLoadFlags; - return NS_OK; -} - -NS_IMETHODIMP -DocumentChannelChild::GetTRRMode(nsIRequest::TRRMode* aTRRMode) { - return GetTRRModeImpl(aTRRMode); -} - -NS_IMETHODIMP -DocumentChannelChild::SetTRRMode(nsIRequest::TRRMode aTRRMode) { - return SetTRRModeImpl(aTRRMode); -} - -NS_IMETHODIMP DocumentChannelChild::SetLoadFlags(nsLoadFlags aLoadFlags) { - mLoadFlags = aLoadFlags; - return NS_OK; -} - -NS_IMETHODIMP DocumentChannelChild::GetOriginalURI(nsIURI** aOriginalURI) { - nsCOMPtr originalURI = - mLoadState->OriginalURI() ? mLoadState->OriginalURI() : mLoadState->URI(); - originalURI.forget(aOriginalURI); - return NS_OK; -} - -NS_IMETHODIMP DocumentChannelChild::SetOriginalURI(nsIURI* aOriginalURI) { - MOZ_CRASH("If we get here, something is broken"); - return NS_ERROR_NOT_IMPLEMENTED; -} - -NS_IMETHODIMP DocumentChannelChild::GetURI(nsIURI** aURI) { - nsCOMPtr uri(mURI); - uri.forget(aURI); - return NS_OK; -} - -NS_IMETHODIMP DocumentChannelChild::GetOwner(nsISupports** aOwner) { - nsCOMPtr owner(mOwner); - owner.forget(aOwner); - return NS_OK; -} - -NS_IMETHODIMP DocumentChannelChild::SetOwner(nsISupports* aOwner) { - mOwner = aOwner; - return NS_OK; -} - -NS_IMETHODIMP DocumentChannelChild::GetSecurityInfo( - nsISupports** aSecurityInfo) { - *aSecurityInfo = nullptr; - return NS_OK; -} - -NS_IMETHODIMP DocumentChannelChild::GetContentType(nsACString& aContentType) { - MOZ_CRASH("If we get here, something is broken"); - return NS_ERROR_NOT_IMPLEMENTED; -} - -NS_IMETHODIMP DocumentChannelChild::SetContentType( - const nsACString& aContentType) { - MOZ_CRASH("If we get here, something is broken"); - return NS_ERROR_NOT_IMPLEMENTED; -} - -NS_IMETHODIMP DocumentChannelChild::GetContentCharset( - nsACString& aContentCharset) { - MOZ_CRASH("If we get here, something is broken"); - return NS_ERROR_NOT_IMPLEMENTED; -} - -NS_IMETHODIMP DocumentChannelChild::SetContentCharset( - const nsACString& aContentCharset) { - MOZ_CRASH("If we get here, something is broken"); - return NS_ERROR_NOT_IMPLEMENTED; -} - -NS_IMETHODIMP DocumentChannelChild::GetContentLength(int64_t* aContentLength) { - MOZ_CRASH("If we get here, something is broken"); - return NS_ERROR_NOT_IMPLEMENTED; -} - -NS_IMETHODIMP DocumentChannelChild::SetContentLength(int64_t aContentLength) { - MOZ_CRASH("If we get here, something is broken"); - return NS_ERROR_NOT_IMPLEMENTED; -} - -NS_IMETHODIMP DocumentChannelChild::Open(nsIInputStream** aStream) { - MOZ_CRASH("If we get here, something is broken"); - return NS_ERROR_NOT_IMPLEMENTED; -} - -NS_IMETHODIMP DocumentChannelChild::GetContentDisposition( - uint32_t* aContentDisposition) { - MOZ_CRASH("If we get here, something is broken"); - return NS_ERROR_NOT_IMPLEMENTED; -} - -NS_IMETHODIMP DocumentChannelChild::SetContentDisposition( - uint32_t aContentDisposition) { - MOZ_CRASH("If we get here, something is broken"); - return NS_ERROR_NOT_IMPLEMENTED; -} - -NS_IMETHODIMP DocumentChannelChild::GetContentDispositionFilename( - nsAString& aContentDispositionFilename) { - MOZ_CRASH("If we get here, something will be broken"); - return NS_ERROR_NOT_IMPLEMENTED; -} - -NS_IMETHODIMP DocumentChannelChild::SetContentDispositionFilename( - const nsAString& aContentDispositionFilename) { - MOZ_CRASH("If we get here, something will be broken"); - return NS_ERROR_NOT_IMPLEMENTED; -} - -NS_IMETHODIMP DocumentChannelChild::GetContentDispositionHeader( - nsACString& aContentDispositionHeader) { - MOZ_CRASH("If we get here, something is broken"); - return NS_ERROR_NOT_IMPLEMENTED; -} - -NS_IMETHODIMP DocumentChannelChild::GetLoadInfo(nsILoadInfo** aLoadInfo) { - nsCOMPtr loadInfo(mLoadInfo); - loadInfo.forget(aLoadInfo); - return NS_OK; -} - -NS_IMETHODIMP DocumentChannelChild::SetLoadInfo(nsILoadInfo* aLoadInfo) { - MOZ_CRASH("If we get here, something is broken"); - return NS_ERROR_NOT_IMPLEMENTED; -} - -NS_IMETHODIMP DocumentChannelChild::GetIsDocument(bool* aIsDocument) { - return NS_GetIsDocumentChannel(this, aIsDocument); -} - -NS_IMETHODIMP DocumentChannelChild::GetCanceled(bool* aCanceled) { - *aCanceled = mCanceled; - return NS_OK; -} - -//----------------------------------------------------------------------------- -// nsIIdentChannel -//----------------------------------------------------------------------------- - -NS_IMETHODIMP -DocumentChannelChild::GetChannelId(uint64_t* aChannelId) { - *aChannelId = mChannelId; - return NS_OK; -} - -NS_IMETHODIMP -DocumentChannelChild::SetChannelId(uint64_t aChannelId) { - mChannelId = aChannelId; - return NS_OK; -} - } // namespace net } // namespace mozilla diff --git a/netwerk/ipc/DocumentChannelChild.h b/netwerk/ipc/DocumentChannelChild.h index 1297ba4f15d0..5fb7c1438af4 100644 --- a/netwerk/ipc/DocumentChannelChild.h +++ b/netwerk/ipc/DocumentChannelChild.h @@ -9,25 +9,19 @@ #define mozilla_net_DocumentChannelChild_h #include "mozilla/net/PDocumentChannelChild.h" -#include "nsDOMNavigationTiming.h" +#include "mozilla/net/DocumentChannel.h" #include "nsIAsyncVerifyRedirectCallback.h" -#include "nsIChannel.h" -#include "nsIChildChannel.h" -#include "nsITraceableChannel.h" - -#define DOCUMENT_CHANNEL_CHILD_IID \ - { \ - 0x6977bc44, 0xb1db, 0x41b7, { \ - 0xb5, 0xc5, 0xe2, 0x13, 0x68, 0x22, 0xc9, 0x8f \ - } \ - } namespace mozilla { namespace net { -class DocumentChannelChild final : public nsIIdentChannel, +/** + * DocumentChannelChild is an implementation of DocumentChannel for nsDocShells + * in the content process, that uses PDocumentChannel to serialize everything + * across IPDL to the parent process. + */ +class DocumentChannelChild final : public DocumentChannel, public nsIAsyncVerifyRedirectCallback, - public nsITraceableChannel, public PDocumentChannelChild { public: DocumentChannelChild(nsDocShellLoadState* aLoadState, @@ -36,14 +30,11 @@ class DocumentChannelChild final : public nsIIdentChannel, uint32_t aLoadType, uint32_t aCacheKey, bool aIsActive, bool aIsTopLevelDoc, bool aHasNonEmptySandboxingFlags); - NS_DECL_ISUPPORTS - NS_DECL_NSIREQUEST - NS_DECL_NSICHANNEL - NS_DECL_NSIIDENTCHANNEL + NS_DECL_ISUPPORTS_INHERITED NS_DECL_NSIASYNCVERIFYREDIRECTCALLBACK - NS_DECL_NSITRACEABLECHANNEL - NS_DECLARE_STATIC_IID_ACCESSOR(DOCUMENT_CHANNEL_CHILD_IID) + NS_IMETHOD AsyncOpen(nsIStreamListener* aListener) override; + NS_IMETHOD Cancel(nsresult aStatusCode) override; mozilla::ipc::IPCResult RecvFailedAsyncOpen(const nsresult& aStatusCode); @@ -63,64 +54,16 @@ class DocumentChannelChild final : public nsIIdentChannel, LoadInfoArgs&& aLoadInfo, nsIURI* aNewUri, ConfirmRedirectResolver&& aResolve); - const nsTArray& GetRedirectChain() const { - return mRedirects; - } - - void GetLastVisit(nsIURI** aURI, uint32_t* aChannelRedirectFlags) const { - *aURI = do_AddRef(mLastVisitInfo.uri()).take(); - *aChannelRedirectFlags = mLastVisitInfo.previousFlags(); - } - - void SetDocumentOpenFlags(uint32_t aFlags, bool aPluginsAllowed) { - mDocumentOpenFlags = Some(aFlags); - mPluginsAllowed = aPluginsAllowed; - } - - void SetNavigationTiming(nsDOMNavigationTiming* aTiming) { - mTiming = aTiming; - } - private: void ShutdownListeners(nsresult aStatusCode); - nsDocShell* GetDocShell(); ~DocumentChannelChild(); - LastVisitInfo mLastVisitInfo; nsCOMPtr mRedirectChannel; - nsTArray mRedirects; RedirectToRealChannelResolver mRedirectResolver; - - const TimeStamp mAsyncOpenTime; - const RefPtr mLoadState; - const Maybe mInitiatorType; - const uint32_t mLoadType; - const uint32_t mCacheKey; - const bool mIsActive; - const bool mIsTopLevelDoc; - const bool mHasNonEmptySandboxingFlags; - - nsresult mStatus = NS_OK; - bool mCanceled = false; - Maybe mDocumentOpenFlags; - bool mIsPending = false; - bool mWasOpened = false; - uint64_t mChannelId; - uint32_t mLoadFlags = LOAD_NORMAL; - const nsCOMPtr mURI; - nsCOMPtr mLoadGroup; - nsCOMPtr mLoadInfo; - nsCOMPtr mCallbacks; - nsCOMPtr mListener; - nsCOMPtr mOwner; - bool mPluginsAllowed = false; - RefPtr mTiming; }; -NS_DEFINE_STATIC_IID_ACCESSOR(DocumentChannelChild, DOCUMENT_CHANNEL_CHILD_IID) - } // namespace net } // namespace mozilla diff --git a/netwerk/ipc/moz.build b/netwerk/ipc/moz.build index 616165ffdea1..81b5077d51fc 100644 --- a/netwerk/ipc/moz.build +++ b/netwerk/ipc/moz.build @@ -7,6 +7,7 @@ EXPORTS.mozilla.net += [ 'ADocumentChannelBridge.h', 'ChannelEventQueue.h', + 'DocumentChannel.h', 'DocumentChannelChild.h', 'DocumentChannelParent.h', 'DocumentLoadListener.h', @@ -25,6 +26,7 @@ EXPORTS.mozilla.net += [ UNIFIED_SOURCES += [ 'ChannelEventQueue.cpp', + 'DocumentChannel.cpp', 'DocumentChannelChild.cpp', 'DocumentChannelParent.cpp', 'DocumentLoadListener.cpp',