Bug 1607984 - P12. Start parent load via DocumentChannel. r=mayhemer,nika,mattwoodrow

Add ParentProcessDocumentChannel object. This object is a DocumentChannel that will start a channel load from the parent process via a DocumentChannel.

The aim of this task is two-fold.
1- Be consistent on how we handle redirects before continuing the load on the final channel.
2- Prepare to initiate a process switch when needed without having to go via an intermediary content process, saving a process switch. This task will be done in a follow-up task.

The behaviour of the ParentProcessDocumentChannel is similar in logic to the DocumentChannelChild/DocumentChannelParent pair.
The ParentProcessDocumentChannel sets up a DocumentLoadListener, have it handle the redirects and upon completion continue the load on the final channel.

Differential Revision: https://phabricator.services.mozilla.com/D70009
This commit is contained in:
Jean-Yves Avenard
2020-04-15 07:07:06 +00:00
parent 892b93ae83
commit ef78beffd6
13 changed files with 528 additions and 176 deletions

View File

@@ -73,9 +73,8 @@
#include "mozilla/dom/nsCSPContext.h"
#include "mozilla/dom/LoadURIOptionsBinding.h"
#include "mozilla/dom/JSWindowActorChild.h"
#include "mozilla/net/DocumentChannel.h"
#include "nsSHEntry.h"
#include "mozilla/net/DocumentChannelChild.h"
#include "mozilla/net/DocumentChannel.h"
#include "mozilla/net/UrlClassifierFeatureFactory.h"
#include "ReferrerInfo.h"
@@ -5710,7 +5709,8 @@ 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<DocumentChannel> docChannel = do_QueryObject(aOldChannel)) {
RefPtr<DocumentChannel> docChannel = do_QueryObject(aOldChannel);
if (docChannel) {
nsCOMPtr<nsIURI> previousURI;
uint32_t previousFlags = 0;
docChannel->GetLastVisit(getter_AddRefs(previousURI), &previousFlags);
@@ -5758,7 +5758,7 @@ void nsDocShell::OnRedirectStateChange(nsIChannel* aOldChannel,
// check if the new load should go through the application cache.
nsCOMPtr<nsIApplicationCacheChannel> appCacheChannel =
do_QueryInterface(aNewChannel);
if (appCacheChannel) {
if (appCacheChannel && !docChannel) {
if (GeckoProcessType_Default != XRE_GetProcessType()) {
// Permission will be checked in the parent process.
appCacheChannel->SetChooseApplicationCache(true);
@@ -9150,23 +9150,6 @@ static bool IsConsideredSameOriginForUIR(nsIPrincipal* aTriggeringPrincipal,
return NS_OK;
}
// Changes here should also be made in
// E10SUtils.documentChannelPermittedForURI().
static bool URIUsesDocChannel(nsIURI* aURI) {
if (SchemeIsJavascript(aURI) || NS_IsAboutBlank(aURI)) {
return false;
}
nsCString spec = aURI->GetSpecOrDefault();
if (spec.EqualsLiteral("about:printpreview") ||
spec.EqualsLiteral("about:crashcontent")) {
return false;
}
return true;
}
/* static */ bool nsDocShell::CreateAndConfigureRealChannelForLoadState(
BrowsingContext* aBrowsingContext, nsDocShellLoadState* aLoadState,
LoadInfo* aLoadInfo, nsIInterfaceRequestor* aCallbacks,
@@ -9567,8 +9550,9 @@ nsresult nsDocShell::DoURILoad(nsDocShellLoadState* aLoadState,
// 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<nsIChannel> channel = aLoadState->GetPendingRedirectedChannel();
if (channel) {
if (nsCOMPtr<nsIChannel> channel =
aLoadState->GetPendingRedirectedChannel()) {
MOZ_ASSERT(!aLoadState->HasLoadFlags(INTERNAL_LOAD_FLAGS_IS_SRCDOC),
"pending channel for srcdoc load?");
@@ -9715,20 +9699,11 @@ nsresult nsDocShell::DoURILoad(nsDocShellLoadState* aLoadState,
cacheKey = mOSHE->GetCacheKey();
}
// We want to use DocumentChannel if we're using a supported scheme, or if
// we're a sandboxed srcdoc load. Non-sandboxed srcdoc loads need to share
// the same principal object as their outer document (and must load in the
// same process), which breaks if we serialize to the parent process.
bool canUseDocumentChannel =
aLoadState->HasLoadFlags(INTERNAL_LOAD_FLAGS_IS_SRCDOC)
? (sandboxFlags & SANDBOXED_ORIGIN)
: URIUsesDocChannel(aLoadState->URI());
if (StaticPrefs::browser_tabs_documentchannel() && XRE_IsContentProcess() &&
canUseDocumentChannel) {
channel =
new DocumentChannelChild(aLoadState, loadInfo, loadFlags, cacheKey);
channel->SetNotificationCallbacks(this);
nsCOMPtr<nsIChannel> channel;
if (DocumentChannel::CanUseDocumentChannel(aLoadState, sandboxFlags)) {
channel = DocumentChannel::CreateDocumentChannel(
aLoadState, loadInfo, loadFlags, this, sandboxFlags, cacheKey);
MOZ_ASSERT(channel);
} else if (!CreateAndConfigureRealChannelForLoadState(
mBrowsingContext, aLoadState, loadInfo, this, this,
GetOriginAttributes(), loadFlags, cacheKey, rv,