Bug 1598520 - Don't require nsIChildChannel for process switching, as we don't need this for DocumentChannel either. r=mayhemer,kmag

Differential Revision: https://phabricator.services.mozilla.com/D57586
This commit is contained in:
Matt Woodrow
2019-12-19 21:47:10 +00:00
parent 8b73451ce0
commit a773e1515d
7 changed files with 60 additions and 77 deletions

View File

@@ -22,7 +22,7 @@ void ChildProcessChannelListener::RegisterCallback(uint64_t aIdentifier,
} }
void ChildProcessChannelListener::OnChannelReady( void ChildProcessChannelListener::OnChannelReady(
nsIChildChannel* aChannel, uint64_t aIdentifier, nsIChannel* aChannel, uint64_t aIdentifier,
nsTArray<net::DocumentChannelRedirect>&& aRedirects, nsTArray<net::DocumentChannelRedirect>&& aRedirects,
uint32_t aLoadStateLoadFlags) { uint32_t aLoadStateLoadFlags) {
if (auto callback = mCallbacks.GetAndRemove(aIdentifier)) { if (auto callback = mCallbacks.GetAndRemove(aIdentifier)) {

View File

@@ -11,7 +11,7 @@
#include "mozilla/net/NeckoChannelParams.h" #include "mozilla/net/NeckoChannelParams.h"
#include "nsDataHashtable.h" #include "nsDataHashtable.h"
#include "nsIChildChannel.h" #include "nsIChannel.h"
namespace mozilla { namespace mozilla {
namespace dom { namespace dom {
@@ -20,11 +20,11 @@ class ChildProcessChannelListener final {
NS_INLINE_DECL_REFCOUNTING(ChildProcessChannelListener) NS_INLINE_DECL_REFCOUNTING(ChildProcessChannelListener)
using Callback = std::function<void( using Callback = std::function<void(
nsIChildChannel*, nsTArray<net::DocumentChannelRedirect>&&, uint32_t)>; nsIChannel*, nsTArray<net::DocumentChannelRedirect>&&, uint32_t)>;
void RegisterCallback(uint64_t aIdentifier, Callback&& aCallback); void RegisterCallback(uint64_t aIdentifier, Callback&& aCallback);
void OnChannelReady(nsIChildChannel* aChannel, uint64_t aIdentifier, void OnChannelReady(nsIChannel* aChannel, uint64_t aIdentifier,
nsTArray<net::DocumentChannelRedirect>&& aRedirects, nsTArray<net::DocumentChannelRedirect>&& aRedirects,
uint32_t aLoadStateLoadFlags); uint32_t aLoadStateLoadFlags);
@@ -34,7 +34,7 @@ class ChildProcessChannelListener final {
ChildProcessChannelListener() = default; ChildProcessChannelListener() = default;
~ChildProcessChannelListener() = default; ~ChildProcessChannelListener() = default;
struct CallbackArgs { struct CallbackArgs {
nsCOMPtr<nsIChildChannel> mChannel; nsCOMPtr<nsIChannel> mChannel;
nsTArray<net::DocumentChannelRedirect> mRedirects; nsTArray<net::DocumentChannelRedirect> mRedirects;
uint32_t mLoadStateLoadFlags; uint32_t mLoadStateLoadFlags;
}; };

View File

@@ -9755,20 +9755,15 @@ nsresult nsDocShell::DoURILoad(nsDocShellLoadState* aLoadState,
} }
// open a channel for the url // open a channel for the url
nsCOMPtr<nsIChannel> channel;
// If we have a pending channel, use the channel we've already created here. // If we have a pending channel, use the channel we've already created here.
// We don't need to set up load flags for our channel, as it has already been // We don't need to set up load flags for our channel, as it has already been
// created. // created.
nsCOMPtr<nsIChildChannel> pendingChannel = nsCOMPtr<nsIChannel> channel = aLoadState->GetPendingRedirectedChannel();
aLoadState->GetPendingRedirectedChannel(); if (channel) {
if (pendingChannel) {
MOZ_ASSERT(!aLoadState->HasLoadFlags(INTERNAL_LOAD_FLAGS_IS_SRCDOC), MOZ_ASSERT(!aLoadState->HasLoadFlags(INTERNAL_LOAD_FLAGS_IS_SRCDOC),
"pending channel for srcdoc load?"); "pending channel for srcdoc load?");
channel = do_QueryInterface(pendingChannel);
MOZ_ASSERT(channel, "nsIChildChannel isn't a nsIChannel?");
// If we have a request outparameter, shove our channel into it. // If we have a request outparameter, shove our channel into it.
if (aRequest) { if (aRequest) {
nsCOMPtr<nsIRequest> outRequest = channel; nsCOMPtr<nsIRequest> outRequest = channel;
@@ -12769,14 +12764,11 @@ nsDocShell::ResumeRedirectedLoad(uint64_t aIdentifier, int32_t aHistoryIndex) {
// Call into InternalLoad with the pending channel when it is received. // Call into InternalLoad with the pending channel when it is received.
cpcl->RegisterCallback( cpcl->RegisterCallback(
aIdentifier, aIdentifier,
[self, aHistoryIndex](nsIChildChannel* aChannel, [self, aHistoryIndex](nsIChannel* aChannel,
nsTArray<net::DocumentChannelRedirect>&& aRedirects, nsTArray<net::DocumentChannelRedirect>&& aRedirects,
uint32_t aLoadStateLoadFlags) { uint32_t aLoadStateLoadFlags) {
if (NS_WARN_IF(self->mIsBeingDestroyed)) { if (NS_WARN_IF(self->mIsBeingDestroyed)) {
nsCOMPtr<nsIRequest> request = do_QueryInterface(aChannel); aChannel->Cancel(NS_BINDING_ABORTED);
if (request) {
request->Cancel(NS_BINDING_ABORTED);
}
return; return;
} }
@@ -12788,14 +12780,11 @@ nsDocShell::ResumeRedirectedLoad(uint64_t aIdentifier, int32_t aHistoryIndex) {
} }
loadState->SetLoadFlags(aLoadStateLoadFlags); loadState->SetLoadFlags(aLoadStateLoadFlags);
if (nsCOMPtr<nsIChannel> channel = do_QueryInterface(aChannel)) { nsCOMPtr<nsIURI> previousURI;
nsCOMPtr<nsIURI> previousURI; uint32_t previousFlags = 0;
uint32_t previousFlags = 0; ExtractLastVisit(aChannel, getter_AddRefs(previousURI), &previousFlags);
ExtractLastVisit(channel, getter_AddRefs(previousURI), self->SavePreviousRedirectsAndLastVisit(aChannel, previousURI,
&previousFlags); previousFlags, aRedirects);
self->SavePreviousRedirectsAndLastVisit(channel, previousURI,
previousFlags, aRedirects);
}
// If we're performing a history load, locate the correct history entry, // If we're performing a history load, locate the correct history entry,
// and set the relevant bits on our loadState. // and set the relevant bits on our loadState.

View File

@@ -10,7 +10,7 @@
#include "SHEntryChild.h" #include "SHEntryChild.h"
#include "nsISHEntry.h" #include "nsISHEntry.h"
#include "nsIWebNavigation.h" #include "nsIWebNavigation.h"
#include "nsIChildChannel.h" #include "nsIChannel.h"
#include "ReferrerInfo.h" #include "ReferrerInfo.h"
#include "mozilla/BasePrincipal.h" #include "mozilla/BasePrincipal.h"
#include "mozilla/dom/BrowsingContext.h" #include "mozilla/dom/BrowsingContext.h"
@@ -90,16 +90,11 @@ nsDocShellLoadState::nsDocShellLoadState(
nsDocShellLoadState::~nsDocShellLoadState() {} nsDocShellLoadState::~nsDocShellLoadState() {}
nsresult nsDocShellLoadState::CreateFromPendingChannel( nsresult nsDocShellLoadState::CreateFromPendingChannel(
nsIChildChannel* aPendingChannel, nsDocShellLoadState** aResult) { nsIChannel* aPendingChannel, nsDocShellLoadState** aResult) {
nsCOMPtr<nsIChannel> channel = do_QueryInterface(aPendingChannel);
if (NS_WARN_IF(!channel)) {
return NS_ERROR_UNEXPECTED;
}
// 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;
nsresult rv = channel->GetURI(getter_AddRefs(uri)); nsresult rv = aPendingChannel->GetURI(getter_AddRefs(uri));
if (NS_WARN_IF(NS_FAILED(rv))) { if (NS_WARN_IF(NS_FAILED(rv))) {
return rv; return rv;
} }
@@ -110,13 +105,13 @@ nsresult nsDocShellLoadState::CreateFromPendingChannel(
// Pull relevant state from the channel, and store it on the // Pull relevant state from the channel, and store it on the
// nsDocShellLoadState. // nsDocShellLoadState.
nsCOMPtr<nsIURI> originalUri; nsCOMPtr<nsIURI> originalUri;
rv = channel->GetOriginalURI(getter_AddRefs(originalUri)); rv = aPendingChannel->GetOriginalURI(getter_AddRefs(originalUri));
if (NS_WARN_IF(NS_FAILED(rv))) { if (NS_WARN_IF(NS_FAILED(rv))) {
return rv; return rv;
} }
loadState->SetOriginalURI(originalUri); loadState->SetOriginalURI(originalUri);
nsCOMPtr<nsILoadInfo> loadInfo = channel->LoadInfo(); nsCOMPtr<nsILoadInfo> loadInfo = aPendingChannel->LoadInfo();
loadState->SetTriggeringPrincipal(loadInfo->TriggeringPrincipal()); loadState->SetTriggeringPrincipal(loadInfo->TriggeringPrincipal());
// Return the newly created loadState. // Return the newly created loadState.

View File

@@ -19,7 +19,7 @@ class nsIInputStream;
class nsISHEntry; class nsISHEntry;
class nsIURI; class nsIURI;
class nsIDocShell; class nsIDocShell;
class nsIChildChannel; class nsIChannel;
class nsIReferrerInfo; class nsIReferrerInfo;
class OriginAttibutes; class OriginAttibutes;
namespace mozilla { namespace mozilla {
@@ -40,7 +40,7 @@ class nsDocShellLoadState final {
explicit nsDocShellLoadState( explicit nsDocShellLoadState(
const mozilla::dom::DocShellLoadStateInit& aLoadState); const mozilla::dom::DocShellLoadStateInit& aLoadState);
static nsresult CreateFromPendingChannel(nsIChildChannel* aPendingChannel, static nsresult CreateFromPendingChannel(nsIChannel* aPendingChannel,
nsDocShellLoadState** aResult); nsDocShellLoadState** aResult);
static nsresult CreateFromLoadURIOptions( static nsresult CreateFromLoadURIOptions(
@@ -200,7 +200,7 @@ class nsDocShellLoadState final {
return mIsFromProcessingFrameAttributes; return mIsFromProcessingFrameAttributes;
} }
nsIChildChannel* GetPendingRedirectedChannel() { nsIChannel* GetPendingRedirectedChannel() {
return mPendingRedirectedChannel; return mPendingRedirectedChannel;
} }
@@ -365,7 +365,7 @@ class nsDocShellLoadState final {
// If set, a pending cross-process redirected channel should be used to // If set, a pending cross-process redirected channel should be used to
// perform the load. The channel will be stored in this value. // perform the load. The channel will be stored in this value.
nsCOMPtr<nsIChildChannel> mPendingRedirectedChannel; nsCOMPtr<nsIChannel> mPendingRedirectedChannel;
// An optional string representation of mURI, before any // An optional string representation of mURI, before any
// fixups were applied, so that we can send it to a search // fixups were applied, so that we can send it to a search

View File

@@ -3721,12 +3721,6 @@ mozilla::ipc::IPCResult ContentChild::RecvCrossProcessRedirect(
return IPC_OK(); return IPC_OK();
} }
RefPtr<nsIChildChannel> childChannel = do_QueryObject(newChannel);
if (!childChannel) {
rv = NS_ERROR_UNEXPECTED;
return IPC_OK();
}
if (httpChild) { if (httpChild) {
rv = httpChild->SetChannelId(aArgs.channelId()); rv = httpChild->SetChannelId(aArgs.channelId());
if (NS_FAILED(rv)) { if (NS_FAILED(rv)) {
@@ -3751,11 +3745,15 @@ mozilla::ipc::IPCResult ContentChild::RecvCrossProcessRedirect(
HttpBaseChannel::ReplacementReason::DocumentChannel); HttpBaseChannel::ReplacementReason::DocumentChannel);
} }
// connect parent. if (nsCOMPtr<nsIChildChannel> childChannel = do_QueryInterface(newChannel)) {
rv = childChannel->ConnectParent( // Connect to the parent if this is a remote channel. If it's entirely
aArgs.registrarId()); // creates parent channel // handled locally, then we'll call AsyncOpen from the docshell when
if (NS_FAILED(rv)) { // we complete the setup
return IPC_OK(); rv = childChannel->ConnectParent(
aArgs.registrarId()); // creates parent channel
if (NS_FAILED(rv)) {
return IPC_OK();
}
} }
// We need to copy the property bag before signaling that the channel // We need to copy the property bag before signaling that the channel
@@ -3766,8 +3764,8 @@ mozilla::ipc::IPCResult ContentChild::RecvCrossProcessRedirect(
RefPtr<ChildProcessChannelListener> processListener = RefPtr<ChildProcessChannelListener> processListener =
ChildProcessChannelListener::GetSingleton(); ChildProcessChannelListener::GetSingleton();
// The listener will call completeRedirectSetup on the channel. // The listener will call completeRedirectSetup or asyncOpen on the channel.
processListener->OnChannelReady(childChannel, aArgs.redirectIdentifier(), processListener->OnChannelReady(newChannel, aArgs.redirectIdentifier(),
std::move(aArgs.redirects()), std::move(aArgs.redirects()),
aArgs.loadStateLoadFlags()); aArgs.loadStateLoadFlags());

View File

@@ -715,37 +715,38 @@ NS_IMETHODIMP nsURILoader::OpenURI(nsIChannel* channel, uint32_t aFlags,
nsCOMPtr<nsIStreamListener> loader; nsCOMPtr<nsIStreamListener> loader;
nsresult rv = OpenChannel(channel, aFlags, aWindowContext, false, nsresult rv = OpenChannel(channel, aFlags, aWindowContext, false,
getter_AddRefs(loader)); getter_AddRefs(loader));
if (NS_FAILED(rv)) {
if (rv == NS_ERROR_WONT_HANDLE_CONTENT) {
// Not really an error, from this method's point of view
return NS_OK;
}
}
if (NS_SUCCEEDED(rv)) { if (aFlags & nsIURILoader::REDIRECTED_CHANNEL) {
if (aFlags & nsIURILoader::REDIRECTED_CHANNEL) { // Our channel was redirected from another process, so doesn't need to
// Our channel was redirected from another process, so doesn't need to // be opened again. However, it does need its listener hooked up
// be opened again. However, it does need its listener hooked up // correctly.
// correctly. if (nsCOMPtr<nsIChildChannel> childChannel = do_QueryInterface(channel)) {
nsCOMPtr<nsIChildChannel> childChannel = do_QueryInterface(channel);
MOZ_ASSERT(childChannel);
if (!childChannel) {
return NS_ERROR_UNEXPECTED;
}
return childChannel->CompleteRedirectSetup(loader, nullptr); return childChannel->CompleteRedirectSetup(loader, nullptr);
} }
// this method is not complete!!! Eventually, we should first go // It's possible for the redirected channel to not implement
// to the content listener and ask them for a protocol handler... // nsIChildChannel and be entirely local (like srcdoc). In that case we
// if they don't give us one, we need to go to the registry and get // can just open the local instance and it will work.
// the preferred protocol handler. }
// But for now, I'm going to let necko do the work for us.... // This method is not complete. Eventually, we should first go
rv = channel->AsyncOpen(loader); // 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
// the preferred protocol handler.
// no content from this load - that's OK. // But for now, I'm going to let necko do the work for us....
if (rv == NS_ERROR_NO_CONTENT) { rv = channel->AsyncOpen(loader);
LOG((" rv is NS_ERROR_NO_CONTENT -- doing nothing"));
rv = NS_OK; // no content from this load - that's OK.
} if (rv == NS_ERROR_NO_CONTENT) {
} else if (rv == NS_ERROR_WONT_HANDLE_CONTENT) { LOG((" rv is NS_ERROR_NO_CONTENT -- doing nothing"));
// Not really an error, from this method's point of view return NS_OK;
rv = NS_OK;
} }
return rv; return rv;
} }