Bug 1646892 - Allow DocumentChannel process switches into the parent process. r=jya,nika

Differential Revision: https://phabricator.services.mozilla.com/D80327
This commit is contained in:
Matt Woodrow
2020-06-27 04:10:23 +00:00
parent f2b2693886
commit b90c5208a5
15 changed files with 194 additions and 77 deletions

View File

@@ -40,6 +40,12 @@ void ChildProcessChannelListener::OnChannelReady(
} }
} }
ChildProcessChannelListener::~ChildProcessChannelListener() {
for (auto& args : mChannelArgs) {
args.GetData().mResolver(NS_ERROR_FAILURE);
}
}
already_AddRefed<ChildProcessChannelListener> already_AddRefed<ChildProcessChannelListener>
ChildProcessChannelListener::GetSingleton() { ChildProcessChannelListener::GetSingleton() {
if (!sCPCLSingleton) { if (!sCPCLSingleton) {

View File

@@ -37,7 +37,7 @@ class ChildProcessChannelListener final {
private: private:
ChildProcessChannelListener() = default; ChildProcessChannelListener() = default;
~ChildProcessChannelListener() = default; ~ChildProcessChannelListener();
struct CallbackArgs { struct CallbackArgs {
RefPtr<nsDocShellLoadState> mLoadState; RefPtr<nsDocShellLoadState> mLoadState;
nsTArray<Endpoint> mStreamFilterEndpoints; nsTArray<Endpoint> mStreamFilterEndpoints;

View File

@@ -79,6 +79,7 @@
#include "mozilla/dom/JSWindowActorChild.h" #include "mozilla/dom/JSWindowActorChild.h"
#include "mozilla/ipc/ProtocolUtils.h" #include "mozilla/ipc/ProtocolUtils.h"
#include "mozilla/net/DocumentChannel.h" #include "mozilla/net/DocumentChannel.h"
#include "mozilla/net/ParentChannelWrapper.h"
#include "mozilla/net/UrlClassifierFeatureFactory.h" #include "mozilla/net/UrlClassifierFeatureFactory.h"
#include "ReferrerInfo.h" #include "ReferrerInfo.h"
@@ -206,6 +207,7 @@
#include "nsSHEntry.h" #include "nsSHEntry.h"
#include "nsStructuredCloneContainer.h" #include "nsStructuredCloneContainer.h"
#include "nsSubDocumentFrame.h" #include "nsSubDocumentFrame.h"
#include "nsURILoader.h"
#include "nsView.h" #include "nsView.h"
#include "nsViewManager.h" #include "nsViewManager.h"
#include "nsViewSourceHandler.h" #include "nsViewSourceHandler.h"
@@ -9436,8 +9438,7 @@ nsresult nsDocShell::DoURILoad(nsDocShellLoadState* aLoadState,
outRequest.forget(aRequest); outRequest.forget(aRequest);
} }
return OpenInitializedChannel(channel, uriLoader, return OpenRedirectedChannel(aLoadState);
nsIURILoader::REDIRECTED_CHANNEL);
} }
// There are two cases we care about: // There are two cases we care about:
@@ -9723,15 +9724,10 @@ static nsresult AppendSegmentToString(nsIInputStream* aIn, void* aClosure,
return openFlags; return openFlags;
} }
nsresult nsDocShell::OpenInitializedChannel(nsIChannel* aChannel, void nsDocShell::UpdateMixedContentChannelForNewLoad(nsIChannel* aChannel) {
nsIURILoader* aURILoader,
uint32_t aOpenFlags) {
nsresult rv = NS_OK;
if (mLoadType == LOAD_NORMAL_ALLOW_MIXED_CONTENT || if (mLoadType == LOAD_NORMAL_ALLOW_MIXED_CONTENT ||
mLoadType == LOAD_RELOAD_ALLOW_MIXED_CONTENT) { mLoadType == LOAD_RELOAD_ALLOW_MIXED_CONTENT) {
rv = SetMixedContentChannel(aChannel); SetMixedContentChannel(aChannel);
NS_ENSURE_SUCCESS(rv, rv);
} else if (mMixedContentChannel) { } else if (mMixedContentChannel) {
/* /*
* If the user "Disables Protection on This Page", we call * If the user "Disables Protection on This Page", we call
@@ -9742,11 +9738,20 @@ nsresult nsDocShell::OpenInitializedChannel(nsIChannel* aChannel,
* This way, the user does not have to click the disable protection button * This way, the user does not have to click the disable protection button
* over and over for browsing the same site. * over and over for browsing the same site.
*/ */
rv = nsContentUtils::CheckSameOrigin(mMixedContentChannel, aChannel); nsresult rv =
nsContentUtils::CheckSameOrigin(mMixedContentChannel, aChannel);
if (NS_FAILED(rv) || NS_FAILED(SetMixedContentChannel(aChannel))) { if (NS_FAILED(rv) || NS_FAILED(SetMixedContentChannel(aChannel))) {
SetMixedContentChannel(nullptr); SetMixedContentChannel(nullptr);
} }
} }
}
nsresult nsDocShell::OpenInitializedChannel(nsIChannel* aChannel,
nsIURILoader* aURILoader,
uint32_t aOpenFlags) {
nsresult rv = NS_OK;
UpdateMixedContentChannelForNewLoad(aChannel);
// If anything fails here, make sure to clear our initial ClientSource. // If anything fails here, make sure to clear our initial ClientSource.
auto cleanupInitialClient = auto cleanupInitialClient =
@@ -9757,21 +9762,6 @@ nsresult nsDocShell::OpenInitializedChannel(nsIChannel* aChannel,
MaybeCreateInitialClientSource(); MaybeCreateInitialClientSource();
if (aOpenFlags & nsIURILoader::REDIRECTED_CHANNEL) {
nsCOMPtr<nsILoadInfo> loadInfo;
aChannel->GetLoadInfo(getter_AddRefs(loadInfo));
LoadInfo* li = static_cast<LoadInfo*>(loadInfo.get());
if (loadInfo->GetExternalContentPolicyType() ==
nsIContentPolicy::TYPE_DOCUMENT) {
li->UpdateBrowsingContextID(mBrowsingContext->Id());
} else if (loadInfo->GetExternalContentPolicyType() ==
nsIContentPolicy::TYPE_SUBDOCUMENT) {
li->UpdateFrameBrowsingContextID(mBrowsingContext->Id());
}
}
// TODO: more attributes need to be updated on the LoadInfo (bug 1561706)
// Let the client channel helper know if we are using DocumentChannel, // Let the client channel helper know if we are using DocumentChannel,
// since redirects get handled in the parent process in that case. // since redirects get handled in the parent process in that case.
RefPtr<net::DocumentChannel> docChannel = do_QueryObject(aChannel); RefPtr<net::DocumentChannel> docChannel = do_QueryObject(aChannel);
@@ -9794,12 +9784,6 @@ nsresult nsDocShell::OpenInitializedChannel(nsIChannel* aChannel,
rv = AddClientChannelHelperInChild( rv = AddClientChannelHelperInChild(
aChannel, win->EventTargetFor(TaskCategory::Other)); aChannel, win->EventTargetFor(TaskCategory::Other));
docChannel->SetInitialClientInfo(GetInitialClientInfo()); docChannel->SetInitialClientInfo(GetInitialClientInfo());
} else if (aOpenFlags & nsIURILoader::REDIRECTED_CHANNEL) {
// If we did a process switch, then we should have an existing allocated
// ClientInfo, so we just need to allocate a corresponding ClientSource.
CreateReservedSourceIfNeeded(aChannel,
win->EventTargetFor(TaskCategory::Other));
rv = NS_OK;
} else { } else {
rv = AddClientChannelHelper(aChannel, std::move(noReservedClient), rv = AddClientChannelHelper(aChannel, std::move(noReservedClient),
GetInitialClientInfo(), GetInitialClientInfo(),
@@ -9821,6 +9805,81 @@ nsresult nsDocShell::OpenInitializedChannel(nsIChannel* aChannel,
return NS_OK; return NS_OK;
} }
nsresult nsDocShell::OpenRedirectedChannel(nsDocShellLoadState* aLoadState) {
nsCOMPtr<nsIChannel> channel = aLoadState->GetPendingRedirectedChannel();
MOZ_ASSERT(channel);
UpdateMixedContentChannelForNewLoad(channel);
// If anything fails here, make sure to clear our initial ClientSource.
auto cleanupInitialClient =
MakeScopeExit([&] { mInitialClientSource.reset(); });
nsCOMPtr<nsPIDOMWindowOuter> win = GetWindow();
NS_ENSURE_TRUE(win, NS_ERROR_FAILURE);
MaybeCreateInitialClientSource();
nsCOMPtr<nsILoadInfo> loadInfo;
channel->GetLoadInfo(getter_AddRefs(loadInfo));
LoadInfo* li = static_cast<LoadInfo*>(loadInfo.get());
if (loadInfo->GetExternalContentPolicyType() ==
nsIContentPolicy::TYPE_DOCUMENT) {
li->UpdateBrowsingContextID(mBrowsingContext->Id());
} else if (loadInfo->GetExternalContentPolicyType() ==
nsIContentPolicy::TYPE_SUBDOCUMENT) {
li->UpdateFrameBrowsingContextID(mBrowsingContext->Id());
}
// TODO: more attributes need to be updated on the LoadInfo (bug 1561706)
// If we did a process switch, then we should have an existing allocated
// ClientInfo, so we just need to allocate a corresponding ClientSource.
CreateReservedSourceIfNeeded(channel,
win->EventTargetFor(TaskCategory::Other));
RefPtr<nsDocumentOpenInfo> loader =
new nsDocumentOpenInfo(this, nsIURILoader::DONT_RETARGET, nullptr);
channel->SetLoadGroup(mLoadGroup);
MOZ_ALWAYS_SUCCEEDS(loader->Prepare());
nsresult rv = NS_OK;
if (XRE_IsParentProcess()) {
// If we're in the parent, the we don't have an nsIChildChannel, just
// the original channel, which is already open in this process.
// DocumentLoadListener expects to get an nsIParentChannel, so
// we create a wrapper around the channel and nsIStreamListener
// that forwards functionality as needed, and then we register
// it under the provided identifier.
RefPtr<ParentChannelWrapper> wrapper =
new ParentChannelWrapper(channel, loader);
wrapper->Register(aLoadState->GetPendingRedirectChannelRegistrarId());
mLoadGroup->AddRequest(channel, nullptr);
} else if (nsCOMPtr<nsIChildChannel> childChannel =
do_QueryInterface(channel)) {
// Our channel was redirected from another process, so doesn't need to
// be opened again. However, it does need its listener hooked up
// correctly.
rv = childChannel->CompleteRedirectSetup(loader);
} else {
// It's possible for the redirected channel to not implement
// nsIChildChannel and be entirely local (like srcdoc). In that case we
// can just open the local instance and it will work.
rv = channel->AsyncOpen(loader);
}
if (rv == NS_ERROR_NO_CONTENT) {
return NS_OK;
}
NS_ENSURE_SUCCESS(rv, rv);
// Success. Keep the initial ClientSource if it exists.
cleanupInitialClient.release();
return NS_OK;
}
nsresult nsDocShell::ScrollToAnchor(bool aCurHasRef, bool aNewHasRef, nsresult nsDocShell::ScrollToAnchor(bool aCurHasRef, bool aNewHasRef,
nsACString& aNewHash, uint32_t aLoadType) { nsACString& aNewHash, uint32_t aLoadType) {
if (!mCurrentURI) { if (!mCurrentURI) {

View File

@@ -653,6 +653,9 @@ class nsDocShell final : public nsDocLoader,
nsresult OpenInitializedChannel(nsIChannel* aChannel, nsresult OpenInitializedChannel(nsIChannel* aChannel,
nsIURILoader* aURILoader, nsIURILoader* aURILoader,
uint32_t aOpenFlags); uint32_t aOpenFlags);
nsresult OpenRedirectedChannel(nsDocShellLoadState* aLoadState);
void UpdateMixedContentChannelForNewLoad(nsIChannel* aChannel);
MOZ_CAN_RUN_SCRIPT MOZ_CAN_RUN_SCRIPT
nsresult ScrollToAnchor(bool aCurHasRef, bool aNewHasRef, nsresult ScrollToAnchor(bool aCurHasRef, bool aNewHasRef,

View File

@@ -183,7 +183,7 @@ nsDocShellLoadState::~nsDocShellLoadState() {}
nsresult nsDocShellLoadState::CreateFromPendingChannel( nsresult nsDocShellLoadState::CreateFromPendingChannel(
nsIChannel* aPendingChannel, uint64_t aLoadIdentifier, nsIChannel* aPendingChannel, uint64_t aLoadIdentifier,
nsDocShellLoadState** aResult) { uint64_t aRegistrarId, nsDocShellLoadState** aResult) {
// Create the nsDocShellLoadState object with default state pulled from the // Create the nsDocShellLoadState object with default state pulled from the
// passed-in channel. // passed-in channel.
nsCOMPtr<nsIURI> uri; nsCOMPtr<nsIURI> uri;
@@ -195,6 +195,7 @@ nsresult nsDocShellLoadState::CreateFromPendingChannel(
RefPtr<nsDocShellLoadState> loadState = RefPtr<nsDocShellLoadState> loadState =
new nsDocShellLoadState(uri, aLoadIdentifier); new nsDocShellLoadState(uri, aLoadIdentifier);
loadState->mPendingRedirectedChannel = aPendingChannel; loadState->mPendingRedirectedChannel = aPendingChannel;
loadState->mChannelRegistrarId = aRegistrarId;
// Pull relevant state from the channel, and store it on the // Pull relevant state from the channel, and store it on the
// nsDocShellLoadState. // nsDocShellLoadState.

View File

@@ -50,6 +50,7 @@ class nsDocShellLoadState final {
static nsresult CreateFromPendingChannel(nsIChannel* aPendingChannel, static nsresult CreateFromPendingChannel(nsIChannel* aPendingChannel,
uint64_t aLoadIdentifier, uint64_t aLoadIdentifier,
uint64_t aRegistarId,
nsDocShellLoadState** aResult); nsDocShellLoadState** aResult);
static nsresult CreateFromLoadURIOptions( static nsresult CreateFromLoadURIOptions(
@@ -230,6 +231,10 @@ class nsDocShellLoadState final {
return mPendingRedirectedChannel; return mPendingRedirectedChannel;
} }
uint64_t GetPendingRedirectChannelRegistrarId() const {
return mChannelRegistrarId;
}
void SetOriginalURIString(const nsCString& aOriginalURI) { void SetOriginalURIString(const nsCString& aOriginalURI) {
mOriginalURIString.emplace(aOriginalURI); mOriginalURIString.emplace(aOriginalURI);
} }
@@ -426,6 +431,11 @@ class nsDocShellLoadState final {
// when initiating the load. // when initiating the load.
mozilla::Maybe<int32_t> mCancelContentJSEpoch; mozilla::Maybe<int32_t> mCancelContentJSEpoch;
// If mPendingRedirectChannel is set, then this is the identifier
// that the parent-process equivalent channel has been registered
// with using RedirectChannelRegistrar.
uint64_t mChannelRegistrarId;
// An identifier to make it possible to examine if two loads are // An identifier to make it possible to examine if two loads are
// equal, and which browsing context they belong to (see // equal, and which browsing context they belong to (see
// BrowsingContext::{Get, Set}CurrentLoadIdentifier) // BrowsingContext::{Get, Set}CurrentLoadIdentifier)

View File

@@ -3447,7 +3447,8 @@ mozilla::ipc::IPCResult ContentChild::RecvCrossProcessRedirect(
RefPtr<nsDocShellLoadState> loadState; RefPtr<nsDocShellLoadState> loadState;
rv = nsDocShellLoadState::CreateFromPendingChannel( rv = nsDocShellLoadState::CreateFromPendingChannel(
newChannel, aArgs.loadIdentifier(), getter_AddRefs(loadState)); newChannel, aArgs.loadIdentifier(), aArgs.registrarId(),
getter_AddRefs(loadState));
if (NS_WARN_IF(NS_FAILED(rv))) { if (NS_WARN_IF(NS_FAILED(rv))) {
return IPC_OK(); return IPC_OK();
} }

View File

@@ -15,6 +15,7 @@
#include "mozilla/StaticPrefs_security.h" #include "mozilla/StaticPrefs_security.h"
#include "mozilla/dom/BrowsingContextGroup.h" #include "mozilla/dom/BrowsingContextGroup.h"
#include "mozilla/dom/CanonicalBrowsingContext.h" #include "mozilla/dom/CanonicalBrowsingContext.h"
#include "mozilla/dom/ChildProcessChannelListener.h"
#include "mozilla/dom/ClientChannelHelper.h" #include "mozilla/dom/ClientChannelHelper.h"
#include "mozilla/dom/ContentParent.h" #include "mozilla/dom/ContentParent.h"
#include "mozilla/dom/ContentProcessManager.h" #include "mozilla/dom/ContentProcessManager.h"
@@ -1312,8 +1313,9 @@ bool DocumentLoadListener::MaybeTriggerProcessSwitch(
NS_ConvertUTF16toUTF8(remoteType).get())); NS_ConvertUTF16toUTF8(remoteType).get()));
return false; return false;
} }
if (NS_WARN_IF(remoteType.IsEmpty())) {
LOG(("Process Switch Abort: non-remote target process")); if (NS_WARN_IF(!browsingContext->IsTop() && remoteType.IsEmpty())) {
LOG(("Process Switch Abort: non-remote target process for subframe"));
return false; return false;
} }
@@ -1335,14 +1337,10 @@ bool DocumentLoadListener::MaybeTriggerProcessSwitch(
->Then( ->Then(
GetMainThreadSerialEventTarget(), __func__, GetMainThreadSerialEventTarget(), __func__,
[self = RefPtr{this}](BrowserParent* aBrowserParent) { [self = RefPtr{this}](BrowserParent* aBrowserParent) {
MOZ_DIAGNOSTIC_ASSERT(
aBrowserParent,
"Shouldn't have switched into the parent process, as we check "
"!remoteType.IsEmpty() earlier in MaybeTriggerProcessSwitch");
MOZ_ASSERT(self->mChannel, MOZ_ASSERT(self->mChannel,
"Something went wrong, channel got cancelled"); "Something went wrong, channel got cancelled");
self->TriggerRedirectToRealChannel( self->TriggerRedirectToRealChannel(Some(
Some(aBrowserParent->Manager()->ChildID())); aBrowserParent ? aBrowserParent->Manager()->ChildID() : 0));
}, },
[self = RefPtr{this}](nsresult aStatusCode) { [self = RefPtr{this}](nsresult aStatusCode) {
MOZ_ASSERT(NS_FAILED(aStatusCode), "Status should be error"); MOZ_ASSERT(NS_FAILED(aStatusCode), "Status should be error");
@@ -1351,6 +1349,42 @@ bool DocumentLoadListener::MaybeTriggerProcessSwitch(
return true; return true;
} }
RefPtr<PDocumentChannelParent::RedirectToRealChannelPromise>
DocumentLoadListener::RedirectToParentProcess(uint32_t aRedirectFlags,
uint32_t aLoadFlags) {
// This is largely the same as ContentChild::RecvCrossProcessRedirect,
// except without needing to deserialize or create an nsIChildChannel.
RefPtr<nsDocShellLoadState> loadState;
nsDocShellLoadState::CreateFromPendingChannel(
mChannel, mLoadIdentifier, mRedirectChannelId, getter_AddRefs(loadState));
loadState->SetLoadFlags(mLoadStateLoadFlags);
loadState->SetLoadType(mLoadStateLoadType);
if (mSessionHistoryInfo) {
loadState->SetSessionHistoryInfo(*mSessionHistoryInfo);
}
// This is poorly named now.
RefPtr<ChildProcessChannelListener> processListener =
ChildProcessChannelListener::GetSingleton();
auto promise =
MakeRefPtr<PDocumentChannelParent::RedirectToRealChannelPromise::Private>(
__func__);
promise->UseDirectTaskDispatch(__func__);
auto resolve = [promise](nsresult aResult) {
promise->Resolve(aResult, __func__);
};
nsTArray<ipc::Endpoint<extensions::PStreamFilterParent>> endpoints;
processListener->OnChannelReady(loadState, mCrossProcessRedirectIdentifier,
std::move(endpoints), mTiming,
std::move(resolve));
return promise;
}
RefPtr<PDocumentChannelParent::RedirectToRealChannelPromise> RefPtr<PDocumentChannelParent::RedirectToRealChannelPromise>
DocumentLoadListener::RedirectToRealChannel( DocumentLoadListener::RedirectToRealChannel(
uint32_t aRedirectFlags, uint32_t aLoadFlags, uint32_t aRedirectFlags, uint32_t aLoadFlags,
@@ -1379,6 +1413,10 @@ DocumentLoadListener::RedirectToRealChannel(
MOZ_ALWAYS_SUCCEEDS(registrar->RegisterChannel(mChannel, mRedirectChannelId)); MOZ_ALWAYS_SUCCEEDS(registrar->RegisterChannel(mChannel, mRedirectChannelId));
if (aDestinationProcess) { if (aDestinationProcess) {
if (!*aDestinationProcess) {
MOZ_ASSERT(aStreamFilterEndpoints.IsEmpty());
return RedirectToParentProcess(aRedirectFlags, aLoadFlags);
}
dom::ContentParent* cp = dom::ContentParent* cp =
dom::ContentProcessManager::GetSingleton()->GetContentProcessById( dom::ContentProcessManager::GetSingleton()->GetContentProcessById(
ContentParentId{*aDestinationProcess}); ContentParentId{*aDestinationProcess});
@@ -1466,15 +1504,24 @@ void DocumentLoadListener::TriggerRedirectToRealChannel(
if (!mStreamFilterRequests.IsEmpty()) { if (!mStreamFilterRequests.IsEmpty()) {
base::ProcessId pid = OtherPid(); base::ProcessId pid = OtherPid();
if (aDestinationProcess) { if (aDestinationProcess) {
dom::ContentParent* cp = if (*aDestinationProcess) {
dom::ContentProcessManager::GetSingleton()->GetContentProcessById( dom::ContentParent* cp =
ContentParentId(*aDestinationProcess)); dom::ContentProcessManager::GetSingleton()->GetContentProcessById(
if (cp) { ContentParentId(*aDestinationProcess));
pid = cp->OtherPid(); if (cp) {
pid = cp->OtherPid();
}
} else {
pid = 0;
} }
} }
for (StreamFilterRequest& request : mStreamFilterRequests) { for (StreamFilterRequest& request : mStreamFilterRequests) {
if (!pid) {
request.mPromise->Reject(false, __func__);
request.mPromise = nullptr;
continue;
}
ParentEndpoint parent; ParentEndpoint parent;
nsresult rv = extensions::PStreamFilter::CreateEndpoints( nsresult rv = extensions::PStreamFilter::CreateEndpoints(
pid, request.mChildProcessId, &parent, &request.mChildEndpoint); pid, request.mChildProcessId, &parent, &request.mChildEndpoint);

View File

@@ -271,6 +271,11 @@ class DocumentLoadListener : public nsIInterfaceRequestor,
const Maybe<uint64_t>& aDestinationProcess, const Maybe<uint64_t>& aDestinationProcess,
nsTArray<ParentEndpoint>&& aStreamFilterEndpoints); nsTArray<ParentEndpoint>&& aStreamFilterEndpoints);
// A helper for RedirectToRealChannel that handles the case where we started
// from a content process and are process switching into the parent process.
RefPtr<PDocumentChannelParent::RedirectToRealChannelPromise>
RedirectToParentProcess(uint32_t aRedirectFlags, uint32_t aLoadFlags);
// Construct a LoadInfo object to use for the internal channel. // Construct a LoadInfo object to use for the internal channel.
already_AddRefed<LoadInfo> CreateLoadInfo( already_AddRefed<LoadInfo> CreateLoadInfo(
dom::CanonicalBrowsingContext* aBrowsingContext, dom::CanonicalBrowsingContext* aBrowsingContext,

View File

@@ -7,6 +7,7 @@
#include "ParentChannelWrapper.h" #include "ParentChannelWrapper.h"
#include "mozilla/net/UrlClassifierCommon.h" #include "mozilla/net/UrlClassifierCommon.h"
#include "nsIRedirectChannelRegistrar.h"
namespace mozilla { namespace mozilla {
namespace net { namespace net {
@@ -14,6 +15,15 @@ namespace net {
NS_IMPL_ISUPPORTS(ParentChannelWrapper, nsIParentChannel, nsIStreamListener, NS_IMPL_ISUPPORTS(ParentChannelWrapper, nsIParentChannel, nsIStreamListener,
nsIRequestObserver); nsIRequestObserver);
void ParentChannelWrapper::Register(uint64_t aRegistrarId) {
nsCOMPtr<nsIRedirectChannelRegistrar> registrar =
RedirectChannelRegistrar::GetOrCreate();
nsCOMPtr<nsIChannel> dummy;
MOZ_ALWAYS_SUCCEEDS(
NS_LinkRedirectChannels(aRegistrarId, this, getter_AddRefs(dummy)));
MOZ_ASSERT(dummy == mChannel);
}
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// nsIParentChannel // nsIParentChannel
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////

View File

@@ -18,6 +18,10 @@ class ParentChannelWrapper : public nsIParentChannel {
ParentChannelWrapper(nsIChannel* aChannel, nsIStreamListener* aListener) ParentChannelWrapper(nsIChannel* aChannel, nsIStreamListener* aListener)
: mChannel(aChannel), mListener(aListener) {} : mChannel(aChannel), mListener(aListener) {}
// Registers this nsIParentChannel wrapper with the RedirectChannelRegistrar
// and holds a reference.
void Register(uint64_t aRegistrarId);
NS_DECL_ISUPPORTS NS_DECL_ISUPPORTS
NS_DECL_NSIPARENTCHANNEL NS_DECL_NSIPARENTCHANNEL
NS_FORWARD_NSISTREAMLISTENER(mListener->) NS_FORWARD_NSISTREAMLISTENER(mListener->)

View File

@@ -13,7 +13,6 @@
#include "nsDocShell.h" #include "nsDocShell.h"
#include "nsIObserverService.h" #include "nsIObserverService.h"
#include "nsIClassifiedChannel.h" #include "nsIClassifiedChannel.h"
#include "nsIRedirectChannelRegistrar.h"
extern mozilla::LazyLogModule gDocumentChannelLog; extern mozilla::LazyLogModule gDocumentChannelLog;
#define LOG(fmt) MOZ_LOG(gDocumentChannelLog, mozilla::LogLevel::Verbose, fmt) #define LOG(fmt) MOZ_LOG(gDocumentChannelLog, mozilla::LogLevel::Verbose, fmt)
@@ -118,13 +117,7 @@ ParentProcessDocumentChannel::OnRedirectVerifyCallback(nsresult aResult) {
RefPtr<ParentChannelWrapper> wrapper = RefPtr<ParentChannelWrapper> wrapper =
new ParentChannelWrapper(channel, mListener); new ParentChannelWrapper(channel, mListener);
nsCOMPtr<nsIRedirectChannelRegistrar> registrar = wrapper->Register(mDocumentLoadListener->GetRedirectChannelId());
RedirectChannelRegistrar::GetOrCreate();
nsCOMPtr<nsIChannel> dummy;
MOZ_ALWAYS_SUCCEEDS(
NS_LinkRedirectChannels(mDocumentLoadListener->GetRedirectChannelId(),
wrapper, getter_AddRefs(dummy)));
MOZ_ASSERT(dummy == channel);
} }
} }

View File

@@ -824,7 +824,6 @@ var E10SUtils = {
// handled using DocumentChannel, then we can skip switching // handled using DocumentChannel, then we can skip switching
// for now, and let DocumentChannel do it during the response. // for now, and let DocumentChannel do it during the response.
if ( if (
requiredRemoteType != NOT_REMOTE &&
uriObject && uriObject &&
(remoteSubframes || documentChannel) && (remoteSubframes || documentChannel) &&
documentChannelPermittedForURI(uriObject) documentChannelPermittedForURI(uriObject)
@@ -855,7 +854,6 @@ var E10SUtils = {
if ( if (
(aRemoteSubframes || documentChannel) && (aRemoteSubframes || documentChannel) &&
wantRemoteType != NOT_REMOTE &&
documentChannelPermittedForURI(aURI) documentChannelPermittedForURI(aURI)
) { ) {
// We can switch later with documentchannel. // We can switch later with documentchannel.
@@ -893,7 +891,6 @@ var E10SUtils = {
if ( if (
AppConstants.MOZ_WIDGET_TOOLKIT != "android" && AppConstants.MOZ_WIDGET_TOOLKIT != "android" &&
(useRemoteSubframes || documentChannel) && (useRemoteSubframes || documentChannel) &&
wantRemoteType != NOT_REMOTE &&
documentChannelPermittedForURI(aURI) documentChannelPermittedForURI(aURI)
) { ) {
return true; return true;

View File

@@ -53,12 +53,6 @@ interface nsIURILoader : nsISupports
* be indicated. * be indicated.
*/ */
const unsigned long DONT_RETARGET = 1 << 1; const unsigned long DONT_RETARGET = 1 << 1;
/**
* If this flag is set, it means that aChannel has been redirected from
* another process, and should be reopened using CompleteRedirectSetup rather
* than AsyncOpen.
*/
const unsigned long REDIRECTED_CHANNEL = 1 << 2;
/* @} */ /* @} */
/** /**

View File

@@ -687,19 +687,6 @@ NS_IMETHODIMP nsURILoader::OpenURI(nsIChannel* channel, uint32_t aFlags,
} }
} }
if (aFlags & nsIURILoader::REDIRECTED_CHANNEL) {
// Our channel was redirected from another process, so doesn't need to
// be opened again. However, it does need its listener hooked up
// correctly.
if (nsCOMPtr<nsIChildChannel> childChannel = do_QueryInterface(channel)) {
return childChannel->CompleteRedirectSetup(loader);
}
// It's possible for the redirected channel to not implement
// nsIChildChannel and be entirely local (like srcdoc). In that case we
// can just open the local instance and it will work.
}
// This method is not complete. Eventually, we should first go // This method is not complete. Eventually, we should first go
// to the content listener and ask them for a protocol handler... // to the content listener and ask them for a protocol handler...
// if they don't give us one, we need to go to the registry and get // if they don't give us one, we need to go to the registry and get