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

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Matt Woodrow 2019-12-19 21:47:10 +00:00
parent c1109e972c
commit eb5ca8b399
7 changed files with 60 additions and 77 deletions

View File

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

View File

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

View File

@ -9755,20 +9755,15 @@ nsresult nsDocShell::DoURILoad(nsDocShellLoadState* aLoadState,
}
// open a channel for the url
nsCOMPtr<nsIChannel> channel;
// 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
// created.
nsCOMPtr<nsIChildChannel> pendingChannel =
aLoadState->GetPendingRedirectedChannel();
if (pendingChannel) {
nsCOMPtr<nsIChannel> channel = aLoadState->GetPendingRedirectedChannel();
if (channel) {
MOZ_ASSERT(!aLoadState->HasLoadFlags(INTERNAL_LOAD_FLAGS_IS_SRCDOC),
"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 (aRequest) {
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.
cpcl->RegisterCallback(
aIdentifier,
[self, aHistoryIndex](nsIChildChannel* aChannel,
[self, aHistoryIndex](nsIChannel* aChannel,
nsTArray<net::DocumentChannelRedirect>&& aRedirects,
uint32_t aLoadStateLoadFlags) {
if (NS_WARN_IF(self->mIsBeingDestroyed)) {
nsCOMPtr<nsIRequest> request = do_QueryInterface(aChannel);
if (request) {
request->Cancel(NS_BINDING_ABORTED);
}
aChannel->Cancel(NS_BINDING_ABORTED);
return;
}
@ -12788,14 +12780,11 @@ nsDocShell::ResumeRedirectedLoad(uint64_t aIdentifier, int32_t aHistoryIndex) {
}
loadState->SetLoadFlags(aLoadStateLoadFlags);
if (nsCOMPtr<nsIChannel> channel = do_QueryInterface(aChannel)) {
nsCOMPtr<nsIURI> previousURI;
uint32_t previousFlags = 0;
ExtractLastVisit(channel, getter_AddRefs(previousURI),
&previousFlags);
self->SavePreviousRedirectsAndLastVisit(channel, previousURI,
previousFlags, aRedirects);
}
nsCOMPtr<nsIURI> previousURI;
uint32_t previousFlags = 0;
ExtractLastVisit(aChannel, getter_AddRefs(previousURI), &previousFlags);
self->SavePreviousRedirectsAndLastVisit(aChannel, previousURI,
previousFlags, aRedirects);
// If we're performing a history load, locate the correct history entry,
// and set the relevant bits on our loadState.

View File

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

View File

@ -19,7 +19,7 @@ class nsIInputStream;
class nsISHEntry;
class nsIURI;
class nsIDocShell;
class nsIChildChannel;
class nsIChannel;
class nsIReferrerInfo;
class OriginAttibutes;
namespace mozilla {
@ -40,7 +40,7 @@ class nsDocShellLoadState final {
explicit nsDocShellLoadState(
const mozilla::dom::DocShellLoadStateInit& aLoadState);
static nsresult CreateFromPendingChannel(nsIChildChannel* aPendingChannel,
static nsresult CreateFromPendingChannel(nsIChannel* aPendingChannel,
nsDocShellLoadState** aResult);
static nsresult CreateFromLoadURIOptions(
@ -200,7 +200,7 @@ class nsDocShellLoadState final {
return mIsFromProcessingFrameAttributes;
}
nsIChildChannel* GetPendingRedirectedChannel() {
nsIChannel* GetPendingRedirectedChannel() {
return mPendingRedirectedChannel;
}
@ -365,7 +365,7 @@ class nsDocShellLoadState final {
// If set, a pending cross-process redirected channel should be used to
// 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
// 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();
}
RefPtr<nsIChildChannel> childChannel = do_QueryObject(newChannel);
if (!childChannel) {
rv = NS_ERROR_UNEXPECTED;
return IPC_OK();
}
if (httpChild) {
rv = httpChild->SetChannelId(aArgs.channelId());
if (NS_FAILED(rv)) {
@ -3751,11 +3745,15 @@ mozilla::ipc::IPCResult ContentChild::RecvCrossProcessRedirect(
HttpBaseChannel::ReplacementReason::DocumentChannel);
}
// connect parent.
rv = childChannel->ConnectParent(
aArgs.registrarId()); // creates parent channel
if (NS_FAILED(rv)) {
return IPC_OK();
if (nsCOMPtr<nsIChildChannel> childChannel = do_QueryInterface(newChannel)) {
// Connect to the parent if this is a remote channel. If it's entirely
// handled locally, then we'll call AsyncOpen from the docshell when
// we complete the setup
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
@ -3766,8 +3764,8 @@ mozilla::ipc::IPCResult ContentChild::RecvCrossProcessRedirect(
RefPtr<ChildProcessChannelListener> processListener =
ChildProcessChannelListener::GetSingleton();
// The listener will call completeRedirectSetup on the channel.
processListener->OnChannelReady(childChannel, aArgs.redirectIdentifier(),
// The listener will call completeRedirectSetup or asyncOpen on the channel.
processListener->OnChannelReady(newChannel, aArgs.redirectIdentifier(),
std::move(aArgs.redirects()),
aArgs.loadStateLoadFlags());

View File

@ -715,37 +715,38 @@ NS_IMETHODIMP nsURILoader::OpenURI(nsIChannel* channel, uint32_t aFlags,
nsCOMPtr<nsIStreamListener> loader;
nsresult rv = OpenChannel(channel, aFlags, aWindowContext, false,
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) {
// Our channel was redirected from another process, so doesn't need to
// be opened again. However, it does need its listener hooked up
// correctly.
nsCOMPtr<nsIChildChannel> childChannel = do_QueryInterface(channel);
MOZ_ASSERT(childChannel);
if (!childChannel) {
return NS_ERROR_UNEXPECTED;
}
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, nullptr);
}
// this method is not complete!!! Eventually, we should first go
// 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.
// 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.
}
// But for now, I'm going to let necko do the work for us....
rv = channel->AsyncOpen(loader);
// This method is not complete. Eventually, we should first go
// 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.
if (rv == NS_ERROR_NO_CONTENT) {
LOG((" rv is NS_ERROR_NO_CONTENT -- doing nothing"));
rv = NS_OK;
}
} else if (rv == NS_ERROR_WONT_HANDLE_CONTENT) {
// Not really an error, from this method's point of view
rv = NS_OK;
// But for now, I'm going to let necko do the work for us....
rv = channel->AsyncOpen(loader);
// no content from this load - that's OK.
if (rv == NS_ERROR_NO_CONTENT) {
LOG((" rv is NS_ERROR_NO_CONTENT -- doing nothing"));
return NS_OK;
}
return rv;
}