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:
@@ -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)) {
|
||||||
|
|||||||
@@ -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;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -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.
|
||||||
|
|||||||
@@ -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.
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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());
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user