Backed out 8 changesets (bug 1575744) for HttpChannelParent related assertion failures

Backed out changeset af61675dd488 (bug 1575744)
Backed out changeset bf794b9373c8 (bug 1575744)
Backed out changeset 39ffb74d2e12 (bug 1575744)
Backed out changeset c1547b3df672 (bug 1575744)
Backed out changeset 382ee8672027 (bug 1575744)
Backed out changeset 5abb38484f11 (bug 1575744)
Backed out changeset d5244c1bbfe8 (bug 1575744)
Backed out changeset c74b81debf73 (bug 1575744)

--HG--
rename : netwerk/base/nsIProcessSwitchRequestor.idl => netwerk/base/nsICrossProcessSwitchChannel.idl
This commit is contained in:
Bogdan Tara 2019-09-20 06:58:44 +03:00
Родитель d85a0b1f8f
Коммит bee28f01d7
34 изменённых файлов: 355 добавлений и 491 удалений

Просмотреть файл

@ -2606,8 +2606,8 @@ var SessionStoreInternal = {
},
// Examine the channel response to see if we should change the process
// performing the given load. aRequestor implements nsIProcessSwitchRequestor
onMayChangeProcess(aRequestor) {
// performing the given load.
onMayChangeProcess(aChannel) {
if (
!E10SUtils.useHttpResponseProcessSelection() &&
!E10SUtils.useCrossOriginOpenerPolicy()
@ -2615,26 +2615,19 @@ var SessionStoreInternal = {
return;
}
let switchRequestor;
try {
switchRequestor = aRequestor.QueryInterface(Ci.nsIProcessSwitchRequestor);
} catch (e) {
debug(`[process-switch]: object not compatible with process switching `);
return;
}
aChannel.QueryInterface(Ci.nsIHttpChannel);
const channel = switchRequestor.channel;
if (!channel.isDocument || !channel.loadInfo) {
if (!aChannel.isDocument || !aChannel.loadInfo) {
return; // Not a document load.
}
// Check that the document has a corresponding BrowsingContext.
let browsingContext;
let cp = channel.loadInfo.externalContentPolicyType;
let cp = aChannel.loadInfo.externalContentPolicyType;
if (cp == Ci.nsIContentPolicy.TYPE_DOCUMENT) {
browsingContext = channel.loadInfo.browsingContext;
browsingContext = aChannel.loadInfo.browsingContext;
} else {
browsingContext = channel.loadInfo.frameBrowsingContext;
browsingContext = aChannel.loadInfo.frameBrowsingContext;
}
if (!browsingContext) {
@ -2698,7 +2691,7 @@ var SessionStoreInternal = {
// Determine the process type the load should be performed in.
let resultPrincipal = Services.scriptSecurityManager.getChannelResultPrincipal(
channel
aChannel
);
let remoteType = E10SUtils.getRemoteTypeForPrincipal(
resultPrincipal,
@ -2710,7 +2703,7 @@ var SessionStoreInternal = {
if (
currentRemoteType == remoteType &&
(!E10SUtils.useCrossOriginOpenerPolicy() ||
!switchRequestor.hasCrossOriginOpenerPolicyMismatch())
!aChannel.hasCrossOriginOpenerPolicyMismatch())
) {
debug(`[process-switch]: type (${remoteType}) is compatible - ignoring`);
return;
@ -2726,7 +2719,7 @@ var SessionStoreInternal = {
const isCOOPSwitch =
E10SUtils.useCrossOriginOpenerPolicy() &&
switchRequestor.hasCrossOriginOpenerPolicyMismatch();
aChannel.hasCrossOriginOpenerPolicyMismatch();
// ------------------------------------------------------------------------
// DANGER ZONE: Perform a process switch into the new process. This is
@ -2736,11 +2729,11 @@ var SessionStoreInternal = {
let tabPromise = this._doProcessSwitch(
browsingContext,
remoteType,
channel,
aChannel,
identifier,
isCOOPSwitch
);
switchRequestor.switchProcessTo(tabPromise, identifier);
aChannel.switchProcessTo(tabPromise, identifier);
},
/* ........ nsISessionStore API .............. */

Просмотреть файл

@ -3633,7 +3633,7 @@ mozilla::ipc::IPCResult ContentChild::RecvCrossProcessRedirect(
const ReplacementChannelConfigInit& aConfig,
const Maybe<LoadInfoArgs>& aLoadInfo, const uint64_t& aChannelId,
nsIURI* aOriginalURI, const uint64_t& aIdentifier,
const uint32_t& aRedirectMode, CrossProcessRedirectResolver&& aResolve) {
const uint32_t& aRedirectMode) {
nsCOMPtr<nsILoadInfo> loadInfo;
nsresult rv =
mozilla::ipc::LoadInfoArgsToLoadInfo(aLoadInfo, getter_AddRefs(loadInfo));
@ -3655,15 +3655,8 @@ mozilla::ipc::IPCResult ContentChild::RecvCrossProcessRedirect(
// This is used to report any errors back to the parent by calling
// CrossProcessRedirectFinished.
auto scopeExit = MakeScopeExit([&]() {
nsCOMPtr<nsILoadInfo> loadInfo;
MOZ_ALWAYS_SUCCEEDS(newChannel->GetLoadInfo(getter_AddRefs(loadInfo)));
Maybe<LoadInfoArgs> loadInfoArgs;
MOZ_ALWAYS_SUCCEEDS(
mozilla::ipc::LoadInfoToLoadInfoArgs(loadInfo, &loadInfoArgs));
aResolve(
Tuple<const nsresult&, const Maybe<LoadInfoArgs>&>(rv, loadInfoArgs));
});
auto scopeExit =
MakeScopeExit([&]() { httpChild->CrossProcessRedirectFinished(rv); });
rv = httpChild->SetChannelId(aChannelId);
if (NS_FAILED(rv)) {

Просмотреть файл

@ -662,7 +662,7 @@ class ContentChild final : public PContentChild,
const ReplacementChannelConfigInit& aConfig,
const Maybe<LoadInfoArgs>& aLoadInfoForwarder, const uint64_t& aChannelId,
nsIURI* aOriginalURI, const uint64_t& aIdentifier,
const uint32_t& aRedirectMode, CrossProcessRedirectResolver&& aResolve);
const uint32_t& aRedirectMode);
mozilla::ipc::IPCResult RecvStartDelayedAutoplayMediaComponents(
BrowsingContext* aContext);

Просмотреть файл

@ -791,9 +791,6 @@ child:
// new HttpChannelChild that will be connected to the parent channel
// represented by registrarId.
// This is on PContent not PNecko, as PNecko may not be initialized yet.
// The returned loadInfo needs to be set on the channel - since the channel
// moved to a new process it now has different properties.
async CrossProcessRedirect(uint32_t aRegistrarId,
nsIURI aURI,
ReplacementChannelConfigInit config,
@ -801,8 +798,7 @@ child:
uint64_t aChannelId,
nsIURI aOriginalURI,
uint64_t aIdentifier,
uint32_t aRedirectMode)
returns (nsresult rv, LoadInfoArgs? arg);
uint32_t aRedirectMode);
/**
* This method is used to notifty content process to start delayed autoplay

Просмотреть файл

@ -1,54 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "PromiseNativeHandler.h"
#include "mozilla/dom/Promise.h"
#include "nsISupportsImpl.h"
namespace mozilla {
namespace dom {
NS_IMPL_ISUPPORTS0(DomPromiseListener)
DomPromiseListener::DomPromiseListener(dom::Promise* aDOMPromise) {
aDOMPromise->AppendNativeHandler(this);
}
DomPromiseListener::DomPromiseListener(dom::Promise* aDOMPromise,
CallbackType&& aResolve,
CallbackType&& aReject)
: mResolve(Some(std::move(aResolve))), mReject(Some(std::move(aReject))) {
aDOMPromise->AppendNativeHandler(this);
}
void DomPromiseListener::ResolvedCallback(JSContext* aCx,
JS::Handle<JS::Value> aValue) {
if (mResolve) {
(*mResolve)(aCx, aValue);
}
// Let's clear the lambdas in case we have a cycle to ourselves.
mResolve.reset();
mReject.reset();
}
void DomPromiseListener::RejectedCallback(JSContext* aCx,
JS::Handle<JS::Value> aValue) {
if (mReject) {
(*mReject)(aCx, aValue);
}
// Let's clear the lambdas in case we have a cycle to ourselves.
mResolve.reset();
mReject.reset();
}
void DomPromiseListener::SetResolvers(CallbackType&& aResolve,
CallbackType&& aReject) {
mResolve = Some(std::move(aResolve));
mReject = Some(std::move(aReject));
}
} // namespace dom
} // namespace mozilla

Просмотреть файл

@ -7,15 +7,12 @@
#ifndef mozilla_dom_PromiseNativeHandler_h
#define mozilla_dom_PromiseNativeHandler_h
#include <functional>
#include "js/TypeDecls.h"
#include "nsISupports.h"
#include "js/TypeDecls.h"
namespace mozilla {
namespace dom {
class Promise;
/*
* PromiseNativeHandler allows C++ to react to a Promise being
* rejected/resolved. A PromiseNativeHandler can be appended to a Promise using
@ -23,7 +20,7 @@ class Promise;
*/
class PromiseNativeHandler : public nsISupports {
protected:
virtual ~PromiseNativeHandler() = default;
virtual ~PromiseNativeHandler() {}
public:
MOZ_CAN_RUN_SCRIPT
@ -35,27 +32,6 @@ class PromiseNativeHandler : public nsISupports {
JS::Handle<JS::Value> aValue) = 0;
};
// This class is used to set C++ callbacks once a dom Promise a resolved or
// rejected.
class DomPromiseListener final : public PromiseNativeHandler {
NS_DECL_ISUPPORTS
public:
using CallbackType = std::function<void(JSContext*, JS::Handle<JS::Value>)>;
explicit DomPromiseListener(Promise* aDOMPromise);
DomPromiseListener(Promise* aDOMPromise, CallbackType&& aResolve,
CallbackType&& aReject);
void SetResolvers(CallbackType&& aResolve, CallbackType&& aReject);
void ResolvedCallback(JSContext* aCx, JS::Handle<JS::Value> aValue) override;
void RejectedCallback(JSContext* aCx, JS::Handle<JS::Value> aValue) override;
private:
~DomPromiseListener() = default;
Maybe<CallbackType> mResolve;
Maybe<CallbackType> mReject;
};
} // namespace dom
} // namespace mozilla

Просмотреть файл

@ -18,7 +18,6 @@ EXPORTS.mozilla.dom += [
UNIFIED_SOURCES += [
'Promise.cpp',
'PromiseDebugging.cpp',
'PromiseNativeHandler.cpp',
]
LOCAL_INCLUDES += [

Просмотреть файл

@ -35,6 +35,7 @@ XPIDL_SOURCES += [
'nsIClassifiedChannel.idl',
'nsIClassOfService.idl',
'nsIContentSniffer.idl',
'nsICrossProcessSwitchChannel.idl',
'nsIDashboard.idl',
'nsIDashboardEventNotifier.idl',
'nsIDeprecationWarner.idl',
@ -75,7 +76,6 @@ XPIDL_SOURCES += [
'nsIPermission.idl',
'nsIPermissionManager.idl',
'nsIPrivateBrowsingChannel.idl',
'nsIProcessSwitchRequestor.idl',
'nsIProgressEventSink.idl',
'nsIPrompt.idl',
'nsIProtocolHandler.idl',

Просмотреть файл

@ -0,0 +1,39 @@
/* -*- Mode: IDL; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "nsISupports.idl"
#include "nsIAsyncVerifyRedirectCallback.idl"
#include "nsIHttpChannel.idl"
[scriptable, uuid(d2471b64-0292-4cb5-b801-914e34b31af0)]
interface nsICrossProcessSwitchChannel : nsISupports
{
/**
* When a process switch has been processed (either successfully or not),
* HttpChannelParent will call this method on the DocumentChannelParent or
* HttpChannelParent.
*
* @param callback
* Object to inform about the async result of this method.
* @param status
* The error that caused the process switch to fail.
* NS_OK means the process switch was processed successfully.
*/
void finishCrossProcessSwitch(in nsIAsyncVerifyRedirectCallback callback, in nsresult status);
/**
* When a process switch is about to start,
* nsHttpChannel will call this method on DocumentChannelParent or
* HttpChannelParent
*
* @param channel
* nsIHttpChannel caller.
* @param identifier
* identifier from SessionStore to be passed to the childChannel in
* order to identify it.
*/
void triggerCrossProcessSwitch(in nsIHttpChannel channel, in uint64_t identifier);
};

Просмотреть файл

@ -1,45 +0,0 @@
/* -*- Mode: IDL; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "nsIChannel.idl"
/**
* The nsIProcessSwitchRequestor interface allows clients to instruct
* SessionStore.jsm that a channel setup has completed and a process switch
* may be required. This works alongside the on-may-change-process observer
* notification.
* This interface must be used only from the XPCOM main thread.
*/
[scriptable, uuid(fce8497b-c57c-4557-b360-3efefc83eff5)]
interface nsIProcessSwitchRequestor : nsISupports
{
/**
* The underlying channel object that was intercepted and that could trigger
* a process.
*/
readonly attribute nsIChannel channel;
/**
* Instructs the callee to be loaded in a new process. Like 'redirectTo'
* this can only be used on channels that have not yet called their
* listener's OnStartRequest(). Can only be called during the
* http-on-may-change-process observer notification.
*
* @param aTabPromise a promise which resolves to a nsIRemotTab object
* which the load will proceed in.
* @param aIdentifier a 64-bit ID which will be provided to the
* ChildProcessChannelListener.
*/
[must_use] void switchProcessTo(in Promise aTabPromise,
in unsigned long long aIdentifier);
/**
* Used to determine if there is a Cross-Origin-Opener-Policy mismatch
* that would require switching the channel to another process.
* @throws NS_ERROR_NOT_AVAILABLE if we don't have a responseHead
*/
[must_use] boolean hasCrossOriginOpenerPolicyMismatch();
};

Просмотреть файл

@ -8,7 +8,6 @@
#include "DocumentChannelParent.h"
#include "mozilla/DebugOnly.h"
#include "mozilla/LoadInfo.h"
#include "mozilla/MozPromiseInlines.h" // For MozPromise::FromDomPromise
#include "mozilla/dom/BrowserParent.h"
#include "mozilla/dom/ClientChannelHelper.h"
#include "mozilla/dom/ContentParent.h"
@ -39,8 +38,8 @@ NS_INTERFACE_MAP_BEGIN(DocumentChannelParent)
NS_INTERFACE_MAP_ENTRY(nsIStreamListener)
NS_INTERFACE_MAP_ENTRY(nsIParentChannel)
NS_INTERFACE_MAP_ENTRY(nsIAsyncVerifyRedirectReadyCallback)
NS_INTERFACE_MAP_ENTRY(nsICrossProcessSwitchChannel)
NS_INTERFACE_MAP_ENTRY(nsIChannelEventSink)
NS_INTERFACE_MAP_ENTRY(nsIProcessSwitchRequestor)
NS_INTERFACE_MAP_ENTRY_CONCRETE(DocumentChannelParent)
NS_INTERFACE_MAP_END
@ -240,7 +239,7 @@ void DocumentChannelParent::FinishReplacementChannelSetup(bool aSucceeded) {
newChannel->Cancel(NS_BINDING_ABORTED);
}
}
// Release all previously registered channels, they are no longer needed to be
// Release all previously registered channels, they are no longer need to be
// kept in the registrar from this moment.
registrar->DeregisterChannels(mRedirectChannelId);
@ -358,21 +357,46 @@ void DocumentChannelParent::FinishReplacementChannelSetup(bool aSucceeded) {
}
}
void DocumentChannelParent::TriggerCrossProcessSwitch() {
MOZ_ASSERT(mRedirectContentProcessIdPromise);
NS_IMETHODIMP
DocumentChannelParent::FinishCrossProcessSwitch(
nsIAsyncVerifyRedirectCallback* aCallback, nsresult aStatusCode) {
// We only manually Suspend mChannel when we initiate the redirect
// from OnStartRequest, which is currently only in the same-process
// case.
MOZ_ASSERT(!mSuspendedChannel);
if (NS_SUCCEEDED(aStatusCode)) {
// This updates ParentChannelListener to point to this parent and at
// the same time cancels the old channel.
FinishReplacementChannelSetup(true);
}
aCallback->OnRedirectVerifyCallback(aStatusCode);
return NS_OK;
}
nsresult DocumentChannelParent::TriggerCrossProcessSwitch(
nsIHttpChannel* aChannel, uint64_t aIdentifier) {
CancelChildForProcessSwitch();
RefPtr<DocumentChannelParent> self = this;
mRedirectContentProcessIdPromise->Then(
RefPtr<nsHttpChannel> httpChannel = do_QueryObject(aChannel);
MOZ_DIAGNOSTIC_ASSERT(httpChannel,
"Must be called with nsHttpChannel object");
RefPtr<nsHttpChannel::ContentProcessIdPromise> p =
httpChannel->TakeRedirectContentProcessIdPromise();
p->Then(
GetMainThreadSerialEventTarget(), __func__,
[self, this](uint64_t aCpId) {
MOZ_ASSERT(mChannel, "Something went wrong, channel got cancelled");
TriggerRedirectToRealChannel(mChannel, Some(aCpId),
mCrossProcessRedirectIdentifier);
[self = RefPtr<DocumentChannelParent>(this),
channel = nsCOMPtr<nsIChannel>(aChannel), aIdentifier](uint64_t aCpId) {
self->TriggerRedirectToRealChannel(channel, Some(aCpId), aIdentifier);
},
[self](nsresult aStatusCode) {
[httpChannel](nsresult aStatusCode) {
MOZ_ASSERT(NS_FAILED(aStatusCode), "Status should be error");
self->RedirectToRealChannelFinished(aStatusCode);
httpChannel->OnRedirectVerifyCallback(aStatusCode);
});
return NS_OK;
}
void DocumentChannelParent::TriggerRedirectToRealChannel(
@ -515,7 +539,6 @@ void DocumentChannelParent::TriggerRedirectToRealChannel(
contentDispositionFilename = Some(contentDispositionFilenameTemp);
}
RefPtr<DocumentChannelParent> self = this;
if (aDestinationProcess) {
dom::ContentParent* cp =
dom::ContentProcessManager::GetSingleton()->GetContentProcessById(
@ -526,36 +549,24 @@ void DocumentChannelParent::TriggerRedirectToRealChannel(
MOZ_ASSERT(config);
cp->SendCrossProcessRedirect(mRedirectChannelId, uri, *config, loadInfoArgs,
channelId, originalURI, aIdentifier,
redirectMode)
->Then(
GetCurrentThreadSerialEventTarget(), __func__,
[self](Tuple<nsresult, Maybe<LoadInfoArgs>>&& aResponse) {
if (NS_SUCCEEDED(Get<0>(aResponse))) {
nsCOMPtr<nsILoadInfo> newLoadInfo;
MOZ_ALWAYS_SUCCEEDS(LoadInfoArgsToLoadInfo(
Get<1>(aResponse), getter_AddRefs(newLoadInfo)));
if (newLoadInfo) {
self->mChannel->SetLoadInfo(newLoadInfo);
}
}
self->RedirectToRealChannelFinished(Get<0>(aResponse));
},
[self](const mozilla::ipc::ResponseRejectReason) {
self->RedirectToRealChannelFinished(NS_ERROR_FAILURE);
});
auto result = cp->SendCrossProcessRedirect(
mRedirectChannelId, uri, *config, loadInfoArgs, channelId, originalURI,
aIdentifier, redirectMode);
MOZ_ASSERT(result, "SendCrossProcessRedirect failed");
Unused << result;
} else {
RefPtr<DocumentChannelParent> channel = this;
SendRedirectToRealChannel(mRedirectChannelId, uri, newLoadFlags, config,
loadInfoArgs, mRedirects, channelId, originalURI,
redirectMode, redirectFlags, contentDisposition,
contentDispositionFilename)
->Then(
GetCurrentThreadSerialEventTarget(), __func__,
[self](nsresult aRv) { self->RedirectToRealChannelFinished(aRv); },
[self](const mozilla::ipc::ResponseRejectReason) {
self->RedirectToRealChannelFinished(NS_ERROR_FAILURE);
[channel](nsresult aRv) {
channel->RedirectToRealChannelFinished(aRv);
},
[channel](const mozilla::ipc::ResponseRejectReason) {
channel->RedirectToRealChannelFinished(NS_ERROR_FAILURE);
});
}
}
@ -595,16 +606,6 @@ DocumentChannelParent::OnStartRequest(nsIRequest* aRequest) {
if (channel) {
Unused << channel->GetApplyConversion(&mOldApplyConversion);
channel->SetApplyConversion(false);
// notify "http-on-may-change-process" observers which is typically
// SessionStore.jsm. This will determine if a new process needs to be
// spawned and if so SwitchProcessTo() will be called which will set a
// ContentProcessIdPromise.
gHttpHandler->OnMayChangeProcess(this);
if (mRedirectContentProcessIdPromise) {
TriggerCrossProcessSwitch();
return NS_OK;
}
}
TriggerRedirectToRealChannel(mChannel);
@ -828,47 +829,5 @@ DocumentChannelParent::AsyncOnChannelRedirect(
return NS_OK;
}
//-----------------------------------------------------------------------------
// DocumentChannelParent::nsIProcessSwitchRequestor
//-----------------------------------------------------------------------------
NS_IMETHODIMP DocumentChannelParent::GetChannel(nsIChannel** aChannel) {
MOZ_ASSERT(mChannel);
nsCOMPtr<nsIChannel> channel(mChannel);
channel.forget(aChannel);
return NS_OK;
}
NS_IMETHODIMP DocumentChannelParent::SwitchProcessTo(
dom::Promise* aContentProcessIdPromise, uint64_t aIdentifier) {
MOZ_ASSERT(NS_IsMainThread());
NS_ENSURE_ARG(aContentProcessIdPromise);
mRedirectContentProcessIdPromise =
ContentProcessIdPromise::FromDomPromise(aContentProcessIdPromise);
mCrossProcessRedirectIdentifier = aIdentifier;
return NS_OK;
}
// This method returns the cached result of running the Cross-Origin-Opener
// policy compare algorithm by calling ComputeCrossOriginOpenerPolicyMismatch
NS_IMETHODIMP
DocumentChannelParent::HasCrossOriginOpenerPolicyMismatch(bool* aMismatch) {
MOZ_ASSERT(aMismatch);
if (!aMismatch) {
return NS_ERROR_INVALID_ARG;
}
nsCOMPtr<nsHttpChannel> channel = do_QueryInterface(mChannel);
if (!channel) {
// Not an nsHttpChannel assume it's okay to switch.
*aMismatch = false;
return NS_OK;
}
return channel->HasCrossOriginOpenerPolicyMismatch(aMismatch);
}
} // namespace net
} // namespace mozilla

Просмотреть файл

@ -7,17 +7,16 @@
#ifndef mozilla_net_DocumentChannelParent_h
#define mozilla_net_DocumentChannelParent_h
#include "mozilla/MozPromise.h"
#include "mozilla/Variant.h"
#include "mozilla/net/NeckoCommon.h"
#include "mozilla/net/NeckoParent.h"
#include "mozilla/net/PDocumentChannelParent.h"
#include "mozilla/net/ParentChannelListener.h"
#include "nsICrossProcessSwitchChannel.h"
#include "nsIInterfaceRequestor.h"
#include "nsIObserver.h"
#include "nsIParentChannel.h"
#include "nsIParentRedirectingChannel.h"
#include "nsIProcessSwitchRequestor.h"
#include "nsIRedirectResultListener.h"
#define DOCUMENT_CHANNEL_PARENT_IID \
@ -37,8 +36,8 @@ class DocumentChannelParent : public nsIInterfaceRequestor,
public nsIAsyncVerifyRedirectReadyCallback,
public nsIParentChannel,
public nsIChannelEventSink,
public HttpChannelSecurityWarningReporter,
public nsIProcessSwitchRequestor {
public nsICrossProcessSwitchChannel,
public HttpChannelSecurityWarningReporter {
public:
explicit DocumentChannelParent(const dom::PBrowserOrId& iframeEmbedding,
nsILoadContext* aLoadContext,
@ -53,7 +52,7 @@ class DocumentChannelParent : public nsIInterfaceRequestor,
NS_DECL_NSIINTERFACEREQUESTOR
NS_DECL_NSIASYNCVERIFYREDIRECTREADYCALLBACK
NS_DECL_NSICHANNELEVENTSINK
NS_DECL_NSIPROCESSSWITCHREQUESTOR
NS_DECL_NSICROSSPROCESSSWITCHCHANNEL
NS_DECLARE_STATIC_IID_ACCESSOR(DOCUMENT_CHANNEL_PARENT_IID)
@ -111,8 +110,6 @@ class DocumentChannelParent : public nsIInterfaceRequestor,
void FinishReplacementChannelSetup(bool aSucceeded);
void TriggerCrossProcessSwitch();
// This defines a variant that describes all the attribute setters (and their
// parameters) from nsIParentChannel
//
@ -212,18 +209,6 @@ class DocumentChannelParent : public nsIInterfaceRequestor,
// helper from being installed, but we need to restore the value
// later.
bool mOldApplyConversion = false;
typedef MozPromise<uint64_t, nsresult, true /* exclusive */>
ContentProcessIdPromise;
// This promise is set following a on-may-change-process observer
// notification when the associated channel is getting relocated to another
// process. It will be resolved when that process is set up.
RefPtr<ContentProcessIdPromise> mRedirectContentProcessIdPromise;
// This identifier is set at the same time as the
// mRedirectContentProcessIdPromise.
// This identifier is later passed to the childChannel in order to identify it
// once the promise is resolved.
uint64_t mCrossProcessRedirectIdentifier = 0;
};
NS_DEFINE_STATIC_IID_ACCESSOR(DocumentChannelParent,

Просмотреть файл

@ -1926,6 +1926,17 @@ HttpBaseChannel::RedirectTo(nsIURI* targetURI) {
return NS_OK;
}
NS_IMETHODIMP
HttpBaseChannel::SwitchProcessTo(mozilla::dom::Promise* aBrowserParent,
uint64_t aIdentifier) {
return NS_ERROR_NOT_AVAILABLE;
}
NS_IMETHODIMP
HttpBaseChannel::HasCrossOriginOpenerPolicyMismatch(bool* aMismatch) {
return NS_ERROR_NOT_AVAILABLE;
}
NS_IMETHODIMP
HttpBaseChannel::UpgradeToSecure() {
// Upgrades are handled internally between http-on-modify-request and

Просмотреть файл

@ -219,6 +219,9 @@ class HttpBaseChannel : public nsHashPropertyBag,
NS_IMETHOD GetResponseStatusText(nsACString& aValue) override;
NS_IMETHOD GetRequestSucceeded(bool* aValue) override;
NS_IMETHOD RedirectTo(nsIURI* newURI) override;
NS_IMETHOD SwitchProcessTo(mozilla::dom::Promise* aBrowserParent,
uint64_t aIdentifier) override;
NS_IMETHOD HasCrossOriginOpenerPolicyMismatch(bool* aMismatch) override;
NS_IMETHOD UpgradeToSecure() override;
NS_IMETHOD GetRequestContextID(uint64_t* aRCID) override;
NS_IMETHOD GetTransferSize(uint64_t* aTransferSize) override;

Просмотреть файл

@ -4076,5 +4076,26 @@ void HttpChannelChild::MaybeCallSynthesizedCallback() {
mSynthesizedCallback = nullptr;
}
nsresult HttpChannelChild::CrossProcessRedirectFinished(nsresult aStatus) {
if (!CanSend()) {
return NS_BINDING_FAILED;
}
if (!mCanceled && NS_SUCCEEDED(mStatus)) {
mStatus = aStatus;
}
// The loadInfo is updated in nsDocShell::OpenInitializedChannel to have the
// correct attributes (such as browsingContextID).
// We need to send it to the parent channel so the two match, which is done
nsCOMPtr<nsILoadInfo> loadInfo;
MOZ_ALWAYS_SUCCEEDS(GetLoadInfo(getter_AddRefs(loadInfo)));
Maybe<LoadInfoArgs> loadInfoArgs;
MOZ_ALWAYS_SUCCEEDS(
mozilla::ipc::LoadInfoToLoadInfoArgs(loadInfo, &loadInfoArgs));
Unused << SendCrossProcessRedirectDone(mStatus, loadInfoArgs);
return NS_OK;
}
} // namespace net
} // namespace mozilla

Просмотреть файл

@ -125,6 +125,8 @@ class HttpChannelChild final : public PHttpChannelChild,
// Callback while background channel is destroyed.
void OnBackgroundChildDestroyed(HttpBackgroundChannelChild* aBgChild);
nsresult CrossProcessRedirectFinished(nsresult aStatus);
protected:
mozilla::ipc::IPCResult RecvOnStartRequest(
const nsresult& channelStatus, const nsHttpResponseHead& responseHead,

Просмотреть файл

@ -289,6 +289,7 @@ NS_INTERFACE_MAP_BEGIN(HttpChannelParent)
NS_INTERFACE_MAP_ENTRY(nsIAsyncVerifyRedirectReadyCallback)
NS_INTERFACE_MAP_ENTRY(nsIChannelEventSink)
NS_INTERFACE_MAP_ENTRY(nsIRedirectResultListener)
NS_INTERFACE_MAP_ENTRY(nsICrossProcessSwitchChannel)
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIParentRedirectingChannel)
NS_INTERFACE_MAP_ENTRY_CONCRETE(HttpChannelParent)
NS_INTERFACE_MAP_END
@ -1256,32 +1257,44 @@ void HttpChannelParent::MaybeFlushPendingDiversion() {
}
}
void HttpChannelParent::FinishCrossProcessSwitch(nsHttpChannel* aChannel,
nsresult aStatus) {
static void FinishCrossProcessSwitchHelper(nsHttpChannel* aChannel,
nsresult aStatus) {
nsCOMPtr<nsICrossProcessSwitchChannel> switchListener;
NS_QueryNotificationCallbacks(aChannel, switchListener);
MOZ_ASSERT(switchListener);
switchListener->FinishCrossProcessSwitch(aChannel, aStatus);
}
NS_IMETHODIMP
HttpChannelParent::FinishCrossProcessSwitch(
nsIAsyncVerifyRedirectCallback* aCallback, nsresult aStatus) {
if (NS_SUCCEEDED(aStatus)) {
// This updates ParentChannelListener to point to this parent and at
// the same time cancels the old channel.
OnRedirectResult(true);
}
aChannel->OnRedirectVerifyCallback(aStatus);
aCallback->OnRedirectVerifyCallback(aStatus);
return NS_OK;
}
void HttpChannelParent::CrossProcessRedirectDone(
mozilla::ipc::IPCResult HttpChannelParent::RecvCrossProcessRedirectDone(
const nsresult& aResult,
const mozilla::Maybe<LoadInfoArgs>& aLoadInfoArgs) {
RefPtr<nsHttpChannel> chan = do_QueryObject(mChannel);
nsresult rv = aResult;
auto sendReply = MakeScopeExit([&]() { FinishCrossProcessSwitch(chan, rv); });
auto sendReply =
MakeScopeExit([&]() { FinishCrossProcessSwitchHelper(chan, rv); });
if (NS_FAILED(rv)) {
return;
return IPC_OK();
}
nsCOMPtr<nsILoadInfo> newLoadInfo;
rv = LoadInfoArgsToLoadInfo(aLoadInfoArgs, getter_AddRefs(newLoadInfo));
if (NS_FAILED(rv)) {
return;
return IPC_OK();
}
if (newLoadInfo) {
@ -1294,13 +1307,15 @@ void HttpChannelParent::CrossProcessRedirectDone(
WaitForBgParent()->Then(
GetMainThreadSerialEventTarget(), __func__,
[self, chan, aResult]() {
self->FinishCrossProcessSwitch(chan, aResult);
FinishCrossProcessSwitchHelper(chan, aResult);
},
[self, chan](const nsresult& aRejectionRv) {
MOZ_ASSERT(NS_FAILED(aRejectionRv), "This should be an error code");
self->FinishCrossProcessSwitch(chan, aRejectionRv);
FinishCrossProcessSwitchHelper(chan, aRejectionRv);
});
}
return IPC_OK();
}
void HttpChannelParent::ResponseSynthesized() {
@ -2664,7 +2679,7 @@ nsresult HttpChannelParent::TriggerCrossProcessSwitch(nsIHttpChannel* aChannel,
RedirectChannelRegistrar::GetOrCreate();
MOZ_ASSERT(registrar);
rv = registrar->RegisterChannel(channel, &self->mRedirectChannelId);
NS_ENSURE_SUCCESS_VOID(rv);
NS_ENSURE_SUCCESS(rv, rv);
LOG(("Registered %p channel under id=%d", channel.get(),
self->mRedirectChannelId));
@ -2695,20 +2710,15 @@ nsresult HttpChannelParent::TriggerCrossProcessSwitch(nsIHttpChannel* aChannel,
dom::ContentProcessManager::GetSingleton()->GetContentProcessById(
ContentParentId{cpId});
if (!cp) {
return;
return NS_ERROR_UNEXPECTED;
}
cp->SendCrossProcessRedirect(self->mRedirectChannelId, uri, config,
loadInfoArgs, channelId, originalURI,
aIdentifier, redirectMode)
->Then(
GetCurrentThreadSerialEventTarget(), __func__,
[self](Tuple<nsresult, Maybe<LoadInfoArgs>>&& aResponse) {
self->CrossProcessRedirectDone(Get<0>(aResponse),
Get<1>(aResponse));
},
[self](const mozilla::ipc::ResponseRejectReason) {
self->CrossProcessRedirectDone(NS_ERROR_FAILURE, Nothing());
});
auto result = cp->SendCrossProcessRedirect(
self->mRedirectChannelId, uri, config, loadInfoArgs, channelId,
originalURI, aIdentifier, redirectMode);
MOZ_ASSERT(result, "SendCrossProcessRedirect failed");
return result ? NS_OK : NS_ERROR_UNEXPECTED;
},
[httpChannel](nsresult aStatus) {
MOZ_ASSERT(NS_FAILED(aStatus), "Status should be error");

Просмотреть файл

@ -14,6 +14,7 @@
#include "mozilla/net/NeckoCommon.h"
#include "mozilla/net/NeckoParent.h"
#include "mozilla/MozPromise.h"
#include "nsICrossProcessSwitchChannel.h"
#include "nsIObserver.h"
#include "nsIParentRedirectingChannel.h"
#include "nsIProgressEventSink.h"
@ -60,7 +61,8 @@ class HttpChannelParent final : public nsIInterfaceRequestor,
public HttpChannelSecurityWarningReporter,
public nsIAsyncVerifyRedirectReadyCallback,
public nsIChannelEventSink,
public nsIRedirectResultListener {
public nsIRedirectResultListener,
public nsICrossProcessSwitchChannel {
virtual ~HttpChannelParent();
public:
@ -76,6 +78,7 @@ class HttpChannelParent final : public nsIInterfaceRequestor,
NS_DECL_NSIASYNCVERIFYREDIRECTREADYCALLBACK
NS_DECL_NSICHANNELEVENTSINK
NS_DECL_NSIREDIRECTRESULTLISTENER
NS_DECL_NSICROSSPROCESSSWITCHCHANNEL
NS_DECLARE_STATIC_IID_ACCESSOR(HTTP_CHANNEL_PARENT_IID)
@ -129,13 +132,6 @@ class HttpChannelParent final : public nsIInterfaceRequestor,
base::ProcessId OtherPid() const;
// Called by nsHttpChannel when a process switch is about to start.
// aChannel: nsIHttpChannel caller.
// aIdentifier: identifier from SessionStore to be passed to the childChannel
// in order to identify it.
nsresult TriggerCrossProcessSwitch(nsIHttpChannel* aChannel,
uint64_t aIdentifier);
// Calling this method will cancel the HttpChannelChild because the consumer
// needs to be relocated to another process.
// Any OnStart/Stop/DataAvailable calls that follow will not be sent to the
@ -213,6 +209,9 @@ class HttpChannelParent final : public nsIInterfaceRequestor,
virtual mozilla::ipc::IPCResult RecvDivertOnStopRequest(
const nsresult& statusCode) override;
virtual mozilla::ipc::IPCResult RecvDivertComplete() override;
virtual mozilla::ipc::IPCResult RecvCrossProcessRedirectDone(
const nsresult& aResult,
const mozilla::Maybe<LoadInfoArgs>& aLoadInfoArgs) override;
virtual mozilla::ipc::IPCResult RecvRemoveCorsPreflightCacheEntry(
const URIParams& uri,
const mozilla::ipc::PrincipalInfo& requestingPrincipal) override;
@ -256,11 +255,6 @@ class HttpChannelParent final : public nsIInterfaceRequestor,
void MaybeFlushPendingDiversion();
void ResponseSynthesized();
void CrossProcessRedirectDone(
const nsresult& aResult,
const mozilla::Maybe<LoadInfoArgs>& aLoadInfoArgs);
void FinishCrossProcessSwitch(nsHttpChannel* aChannel, nsresult aStatus);
// final step for Redirect2Verify procedure, will be invoked while both
// redirecting and redirected channel are ready or any error happened.
// OnRedirectVerifyCallback will be invoked for finishing the async

Просмотреть файл

@ -273,6 +273,17 @@ NullHttpChannel::RedirectTo(nsIURI* aNewURI) {
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
NullHttpChannel::SwitchProcessTo(mozilla::dom::Promise* aBrowserParent,
uint64_t aIdentifier) {
return NS_ERROR_NOT_AVAILABLE;
}
NS_IMETHODIMP
NullHttpChannel::HasCrossOriginOpenerPolicyMismatch(bool* aMismatch) {
return NS_ERROR_NOT_AVAILABLE;
}
NS_IMETHODIMP
NullHttpChannel::UpgradeToSecure() { return NS_ERROR_NOT_IMPLEMENTED; }

Просмотреть файл

@ -50,6 +50,12 @@ parent:
CorsPreflightArgs? corsPreflightArgs,
bool chooseAppcache);
// Sent to the parent in order signal that the child side listeners have been
// set up and the parent side of the channel can be opened.
// The passed loadInfo needs to be set on the channel - since the channel
// moved to a new process it now has different properties.
async CrossProcessRedirectDone(nsresult result, LoadInfoArgs? loadInfo);
// For document loads we keep this protocol open after child's
// OnStopRequest, and send this msg (instead of __delete__) to allow
// partial cleanup on parent.

Просмотреть файл

@ -132,7 +132,6 @@ LOCAL_INCLUDES += [
'/extensions/auth',
'/netwerk/base',
'/netwerk/cookie',
'/netwerk/ipc',
'/netwerk/url-classifier',
]

Просмотреть файл

@ -9,11 +9,9 @@
#include <inttypes.h>
#include "DocumentChannelParent.h"
#include "mozilla/MozPromiseInlines.h" // For MozPromise::FromDomPromise
#include "mozilla/dom/nsCSPContext.h"
#include "mozilla/ScopeExit.h"
#include "mozilla/Sprintf.h"
#include "mozilla/dom/nsCSPContext.h"
#include "nsHttp.h"
#include "nsHttpChannel.h"
@ -125,6 +123,7 @@
#include "../../cache2/CacheFileUtils.h"
#include "../../cache2/CacheHashUtils.h"
#include "nsINetworkLinkService.h"
#include "mozilla/dom/PromiseNativeHandler.h"
#include "mozilla/dom/Promise.h"
#include "mozilla/dom/ServiceWorkerUtils.h"
#include "mozilla/net/AsyncUrlChannelClassifier.h"
@ -2580,26 +2579,18 @@ nsresult nsHttpChannel::ContinueProcessResponse1() {
return NS_OK;
}
nsCOMPtr<nsIParentChannel> parentChannel;
NS_QueryNotificationCallbacks(this, parentChannel);
// notify "http-on-may-change-process" observers
gHttpHandler->OnMayChangeProcess(this);
RefPtr<DocumentChannelParent> documentChannelParent =
do_QueryObject(parentChannel);
if (mRedirectContentProcessIdPromise) {
MOZ_ASSERT(!mOnStartRequestCalled);
if (!documentChannelParent) {
// notify "http-on-may-change-process" observers
gHttpHandler->OnMayChangeProcess(this);
if (mRedirectContentProcessIdPromise) {
MOZ_ASSERT(!mOnStartRequestCalled);
PushRedirectAsyncFunc(&nsHttpChannel::ContinueProcessResponse2);
rv = StartCrossProcessRedirect();
if (NS_SUCCEEDED(rv)) {
return NS_OK;
}
PopRedirectAsyncFunc(&nsHttpChannel::ContinueProcessResponse2);
PushRedirectAsyncFunc(&nsHttpChannel::ContinueProcessResponse2);
rv = StartCrossProcessRedirect();
if (NS_SUCCEEDED(rv)) {
return NS_OK;
}
PopRedirectAsyncFunc(&nsHttpChannel::ContinueProcessResponse2);
}
}
@ -6139,7 +6130,6 @@ NS_INTERFACE_MAP_BEGIN(nsHttpChannel)
NS_INTERFACE_MAP_ENTRY(nsITimerCallback)
NS_INTERFACE_MAP_ENTRY(nsIChannelWithDivertableParentListener)
NS_INTERFACE_MAP_ENTRY(nsIRequestTailUnblockCallback)
NS_INTERFACE_MAP_ENTRY(nsIProcessSwitchRequestor)
NS_INTERFACE_MAP_ENTRY_CONCRETE(nsHttpChannel)
NS_INTERFACE_MAP_END_INHERITING(HttpBaseChannel)
@ -7242,13 +7232,49 @@ nsHttpChannel::GetRequestMethod(nsACString& aMethod) {
}
//-----------------------------------------------------------------------------
// nsHttpChannel::nsIProcessSwitchRequestor
// nsHttpChannel::nsIRequestObserver
//-----------------------------------------------------------------------------
NS_IMETHODIMP nsHttpChannel::GetChannel(nsIChannel** aChannel) {
*aChannel = do_AddRef(this).take();
return NS_OK;
}
// This class is used to convert from a DOM promise to a MozPromise.
class DomPromiseListener final : dom::PromiseNativeHandler {
NS_DECL_ISUPPORTS
static RefPtr<nsHttpChannel::ContentProcessIdPromise> Create(
dom::Promise* aDOMPromise) {
MOZ_ASSERT(aDOMPromise);
RefPtr<DomPromiseListener> handler = new DomPromiseListener();
RefPtr<nsHttpChannel::ContentProcessIdPromise> promise =
handler->mPromiseHolder.Ensure(__func__);
aDOMPromise->AppendNativeHandler(handler);
return promise;
}
virtual void ResolvedCallback(JSContext* aCx,
JS::Handle<JS::Value> aValue) override {
uint64_t cpId;
if (!JS::ToUint64(aCx, aValue, &cpId)) {
mPromiseHolder.Reject(NS_ERROR_FAILURE, __func__);
return;
}
mPromiseHolder.Resolve(cpId, __func__);
}
virtual void RejectedCallback(JSContext* aCx,
JS::Handle<JS::Value> aValue) override {
if (!aValue.isInt32()) {
mPromiseHolder.Reject(NS_ERROR_DOM_NOT_NUMBER_ERR, __func__);
return;
}
mPromiseHolder.Reject((nsresult)aValue.toInt32(), __func__);
}
private:
DomPromiseListener() = default;
~DomPromiseListener() = default;
MozPromiseHolder<nsHttpChannel::ContentProcessIdPromise> mPromiseHolder;
};
NS_IMPL_ISUPPORTS0(DomPromiseListener)
NS_IMETHODIMP nsHttpChannel::SwitchProcessTo(
dom::Promise* aContentProcessIdPromise, uint64_t aIdentifier) {
@ -7258,36 +7284,15 @@ NS_IMETHODIMP nsHttpChannel::SwitchProcessTo(
LOG(("nsHttpChannel::SwitchProcessTo [this=%p]", this));
LogCallingScriptLocation(this);
nsCOMPtr<nsIParentChannel> parentChannel;
NS_QueryNotificationCallbacks(this, parentChannel);
RefPtr<DocumentChannelParent> documentChannelParent =
do_QueryObject(parentChannel);
// This is a temporary change as the DocumentChannelParent currently must go
// through the nsHttpChannel to perform a process switch via SessionStore.
if (!documentChannelParent) {
// We cannot do this after OnStartRequest of the listener has been called.
NS_ENSURE_FALSE(mOnStartRequestCalled, NS_ERROR_NOT_AVAILABLE);
}
// We cannot do this after OnStartRequest of the listener has been called.
NS_ENSURE_FALSE(mOnStartRequestCalled, NS_ERROR_NOT_AVAILABLE);
mRedirectContentProcessIdPromise =
ContentProcessIdPromise::FromDomPromise(aContentProcessIdPromise);
DomPromiseListener::Create(aContentProcessIdPromise);
mCrossProcessRedirectIdentifier = aIdentifier;
return NS_OK;
}
// This method returns the cached result of running the Cross-Origin-Opener
// policy compare algorithm by calling ComputeCrossOriginOpenerPolicyMismatch
NS_IMETHODIMP
nsHttpChannel::HasCrossOriginOpenerPolicyMismatch(bool* aMismatch) {
MOZ_ASSERT(aMismatch);
if (!aMismatch) {
return NS_ERROR_INVALID_ARG;
}
*aMismatch = mHasCrossOriginOpenerPolicyMismatch;
return NS_OK;
}
nsresult nsHttpChannel::StartCrossProcessRedirect() {
nsresult rv;
@ -7298,7 +7303,8 @@ nsresult nsHttpChannel::StartCrossProcessRedirect() {
nsCOMPtr<nsIParentChannel> parentChannel;
NS_QueryNotificationCallbacks(this, parentChannel);
RefPtr<HttpChannelParent> httpParent = do_QueryObject(parentChannel);
nsCOMPtr<nsICrossProcessSwitchChannel> httpParent =
do_QueryInterface(parentChannel);
MOZ_ASSERT(httpParent);
NS_ENSURE_TRUE(httpParent, NS_ERROR_UNEXPECTED);
@ -7350,6 +7356,19 @@ static bool CompareCrossOriginOpenerPolicies(
return false;
}
// This method returns the cached result of running the Cross-Origin-Opener
// policy compare algorithm by calling ComputeCrossOriginOpenerPolicyMismatch
NS_IMETHODIMP
nsHttpChannel::HasCrossOriginOpenerPolicyMismatch(bool* aMismatch) {
MOZ_ASSERT(aMismatch);
if (!aMismatch) {
return NS_ERROR_INVALID_ARG;
}
*aMismatch = mHasCrossOriginOpenerPolicyMismatch;
return NS_OK;
}
// This runs steps 1-5 of the algorithm when navigating a top level document.
// See https://gist.github.com/annevk/6f2dd8c79c77123f39797f6bdac43f3e
nsresult nsHttpChannel::ComputeCrossOriginOpenerPolicyMismatch() {
@ -7572,10 +7591,6 @@ nsresult nsHttpChannel::ProcessCrossOriginResourcePolicyHeader() {
return NS_OK;
}
//-----------------------------------------------------------------------------
// nsHttpChannel::nsIRequestObserver
//-----------------------------------------------------------------------------
NS_IMETHODIMP
nsHttpChannel::OnStartRequest(nsIRequest* request) {
nsresult rv;
@ -7716,21 +7731,15 @@ nsHttpChannel::OnStartRequest(nsIRequest* request) {
return NS_OK;
}
nsCOMPtr<nsIParentChannel> parentChannel;
NS_QueryNotificationCallbacks(this, parentChannel);
RefPtr<DocumentChannelParent> documentChannelParent =
do_QueryObject(parentChannel);
if (!documentChannelParent) {
gHttpHandler->OnMayChangeProcess(this);
gHttpHandler->OnMayChangeProcess(this);
if (mRedirectContentProcessIdPromise) {
PushRedirectAsyncFunc(&nsHttpChannel::ContinueOnStartRequest1);
rv = StartCrossProcessRedirect();
if (NS_SUCCEEDED(rv)) {
return NS_OK;
}
PopRedirectAsyncFunc(&nsHttpChannel::ContinueOnStartRequest1);
if (mRedirectContentProcessIdPromise) {
PushRedirectAsyncFunc(&nsHttpChannel::ContinueOnStartRequest1);
rv = StartCrossProcessRedirect();
if (NS_SUCCEEDED(rv)) {
return NS_OK;
}
PopRedirectAsyncFunc(&nsHttpChannel::ContinueOnStartRequest1);
}
}

Просмотреть файл

@ -33,7 +33,6 @@
#include "nsIRaceCacheWithNetwork.h"
#include "mozilla/extensions/PStreamFilterParent.h"
#include "mozilla/Mutex.h"
#include "nsIProcessSwitchRequestor.h"
#include "nsIRemoteTab.h"
class nsDNSPrefetch;
@ -79,8 +78,7 @@ class nsHttpChannel final : public HttpBaseChannel,
public nsIChannelWithDivertableParentListener,
public nsIRaceCacheWithNetwork,
public nsIRequestTailUnblockCallback,
public nsITimerCallback,
public nsIProcessSwitchRequestor {
public nsITimerCallback {
public:
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_NSIREQUESTOBSERVER
@ -102,7 +100,6 @@ class nsHttpChannel final : public HttpBaseChannel,
NS_DECL_NSIRACECACHEWITHNETWORK
NS_DECL_NSITIMERCALLBACK
NS_DECL_NSIREQUESTTAILUNBLOCKCALLBACK
NS_DECL_NSIPROCESSSWITCHREQUESTOR
// nsIHttpAuthenticableChannel. We can't use
// NS_DECL_NSIHTTPAUTHENTICABLECHANNEL because it duplicates cancel() and
@ -153,6 +150,9 @@ class nsHttpChannel final : public HttpBaseChannel,
NS_IMETHOD AsyncOpen(nsIStreamListener* aListener) override;
// nsIHttpChannel
NS_IMETHOD GetEncodedBodySize(uint64_t* aEncodedBodySize) override;
NS_IMETHOD SwitchProcessTo(mozilla::dom::Promise* aBrowserParent,
uint64_t aIdentifier) override;
NS_IMETHOD HasCrossOriginOpenerPolicyMismatch(bool* aMismatch) override;
// nsIHttpChannelInternal
NS_IMETHOD SetupFallbackChannel(const char* aFallbackKey) override;
NS_IMETHOD SetChannelIsForDownload(bool aChannelIsForDownload) override;
@ -276,8 +276,7 @@ class nsHttpChannel final : public HttpBaseChannel,
}
TransactionObserver* GetTransactionObserver() { return mTransactionObserver; }
typedef MozPromise<uint64_t, nsresult, true /* exclusive */>
ContentProcessIdPromise;
typedef MozPromise<uint64_t, nsresult, false> ContentProcessIdPromise;
already_AddRefed<ContentProcessIdPromise>
TakeRedirectContentProcessIdPromise() {
return mRedirectContentProcessIdPromise.forget();

Просмотреть файл

@ -23,7 +23,6 @@
#include "nsIPrefService.h"
#include "nsIPrefBranch.h"
#include "nsIPrefLocalizedString.h"
#include "nsIProcessSwitchRequestor.h"
#include "nsSocketProviderService.h"
#include "nsISocketProvider.h"
#include "nsPrintfCString.h"
@ -807,14 +806,6 @@ void nsHttpHandler::NotifyObservers(nsIChannel* chan, const char* event) {
if (obsService) obsService->NotifyObservers(chan, event, nullptr);
}
void nsHttpHandler::NotifyObservers(nsIProcessSwitchRequestor* request,
const char* event) {
LOG(("nsHttpHandler::NotifyObservers [request=%p event=\"%s\"]\n", request,
event));
nsCOMPtr<nsIObserverService> obsService = services::GetObserverService();
if (obsService) obsService->NotifyObservers(request, event, nullptr);
}
nsresult nsHttpHandler::AsyncOnChannelRedirect(
nsIChannel* oldChan, nsIChannel* newChan, uint32_t flags,
nsIEventTarget* mainThreadEventTarget) {

Просмотреть файл

@ -29,7 +29,6 @@ class nsIHttpChannel;
class nsIPrefBranch;
class nsICancelable;
class nsICookieService;
class nsIProcessSwitchRequestor;
class nsIIOService;
class nsIRequestContextService;
class nsISiteSecurityService;
@ -408,8 +407,8 @@ class nsHttpHandler final : public nsIHttpProtocolHandler,
NotifyObservers(chan, NS_HTTP_ON_EXAMINE_CACHED_RESPONSE_TOPIC);
}
void OnMayChangeProcess(nsIProcessSwitchRequestor* request) {
NotifyObservers(request, NS_HTTP_ON_MAY_CHANGE_PROCESS_TOPIC);
void OnMayChangeProcess(nsIHttpChannel* chan) {
NotifyObservers(chan, NS_HTTP_ON_MAY_CHANGE_PROCESS_TOPIC);
}
// Generates the host:port string for use in the Host: header as well as the
@ -480,7 +479,6 @@ class nsHttpHandler final : public nsIHttpProtocolHandler,
MOZ_MUST_USE nsresult InitConnectionMgr();
void NotifyObservers(nsIChannel* chan, const char* event);
void NotifyObservers(nsIProcessSwitchRequestor* request, const char* event);
void SetFastOpenOSSupport();

Просмотреть файл

@ -415,6 +415,26 @@ interface nsIHttpChannel : nsIIdentChannel
*/
[must_use] void redirectTo(in nsIURI aTargetURI);
/**
* Instructs the channel to be loaded in a new process. Like 'redirectTo'
* this can only be used on channels that have not yet called their
* listener's OnStartRequest().
*
* @param aTabPromise a promise which resolves to a nsIRemotTab object
* which the load will proceed in.
* @param aIdentifier a 64-bit ID which will be provided to the
* ChildProcessChannelListener.
*/
[must_use] void switchProcessTo(in Promise aTabPromise,
in unsigned long long aIdentifier);
/**
* Used to determine if there is a Cross-Origin-Opener-Policy mismatch
* that would require switching the channel to another process.
* @throws NS_ERROR_NOT_AVAILABLE if we don't have a responseHead
*/
[must_use] boolean hasCrossOriginOpenerPolicyMismatch();
/**
* Flags a channel to be upgraded to HTTPS.
*

Просмотреть файл

@ -175,9 +175,9 @@ interface nsIHttpProtocolHandler : nsIProxiedProtocolHandler
/**
* The observer of this topic is notified before before the response for a HTTP
* load is available. The "subject" of the notification is the
* nsIProcessSwitchRequestor instance. Observers may call "switchProcessTo" to
* perform a process switch while this is being run.
* load is available. The "subject" of the notification is the nsIHttpChannel
* instance. Observers may call "switchProcessTo" to perform a process switch
* while this is being run.
*/
#define NS_HTTP_ON_MAY_CHANGE_PROCESS_TOPIC "http-on-may-change-process"

Просмотреть файл

@ -22,8 +22,6 @@ EXPORTS += [
FINAL_LIBRARY = 'xul'
LOCAL_INCLUDES += [
'/netwerk/base',
# For nsHttpChannel.h
'/netwerk/protocol/http',
]
include('/ipc/chromium/chromium-config.mozbuild')

Просмотреть файл

@ -5,18 +5,17 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "nsViewSourceChannel.h"
#include "mozilla/DebugOnly.h"
#include "mozilla/NullPrincipal.h"
#include "nsContentSecurityManager.h"
#include "nsContentUtils.h"
#include "nsHttpChannel.h"
#include "nsIHttpHeaderVisitor.h"
#include "nsIIOService.h"
#include "nsIInputStreamChannel.h"
#include "nsIReferrerInfo.h"
#include "nsMimeTypes.h"
#include "nsNetUtil.h"
#include "nsContentUtils.h"
#include "nsIHttpHeaderVisitor.h"
#include "nsContentSecurityManager.h"
#include "nsServiceManagerUtils.h"
#include "nsIInputStreamChannel.h"
#include "mozilla/DebugOnly.h"
#include "mozilla/NullPrincipal.h"
#include "nsIReferrerInfo.h"
NS_IMPL_ADDREF(nsViewSourceChannel)
NS_IMPL_RELEASE(nsViewSourceChannel)
@ -943,6 +942,24 @@ nsViewSourceChannel::RedirectTo(nsIURI* uri) {
return !mHttpChannel ? NS_ERROR_NULL_POINTER : mHttpChannel->RedirectTo(uri);
}
NS_IMETHODIMP
nsViewSourceChannel::SwitchProcessTo(mozilla::dom::Promise* aBrowserParent,
uint64_t aIdentifier) {
return !mHttpChannel
? NS_ERROR_NULL_POINTER
: mHttpChannel->SwitchProcessTo(aBrowserParent, aIdentifier);
}
NS_IMETHODIMP
nsViewSourceChannel::HasCrossOriginOpenerPolicyMismatch(bool* aMismatch) {
MOZ_ASSERT(aMismatch);
if (!aMismatch) {
return NS_ERROR_INVALID_ARG;
}
*aMismatch = false;
return NS_OK;
}
NS_IMETHODIMP
nsViewSourceChannel::UpgradeToSecure() {
return !mHttpChannel ? NS_ERROR_NULL_POINTER

Просмотреть файл

@ -6,18 +6,18 @@
#ifndef nsViewSourceChannel_h___
#define nsViewSourceChannel_h___
#include "mozilla/Attributes.h"
#include "mozilla/net/NeckoChannelParams.h"
#include "nsString.h"
#include "nsCOMPtr.h"
#include "nsIApplicationCacheChannel.h"
#include "nsICachingChannel.h"
#include "nsIFormPOSTActionChannel.h"
#include "nsIViewSourceChannel.h"
#include "nsIURI.h"
#include "nsIStreamListener.h"
#include "nsIHttpChannel.h"
#include "nsIHttpChannelInternal.h"
#include "nsIStreamListener.h"
#include "nsIURI.h"
#include "nsIViewSourceChannel.h"
#include "nsString.h"
#include "nsICachingChannel.h"
#include "nsIApplicationCacheChannel.h"
#include "nsIFormPOSTActionChannel.h"
#include "mozilla/Attributes.h"
#include "mozilla/net/NeckoChannelParams.h"
class nsViewSourceChannel final : public nsIViewSourceChannel,
public nsIStreamListener,

Просмотреть файл

@ -40,28 +40,26 @@ ProcessChooser.prototype = {
Services.obs.removeObserver(this, "http-on-may-change-process");
},
examine(aRequestor) {
const channel = aRequestor.channel;
if (this.channel && this.channel != channel) {
examine(aChannel) {
if (this.channel && this.channel != aChannel) {
// Hack: this is just so we don't get redirected multiple times.
info("same channel. give null");
return;
}
if (channel.URI.host != this.toDomain) {
info("wrong host for channel " + channel.URI.host);
if (aChannel.URI.host != this.toDomain) {
info("wrong host for channel " + aChannel.URI.host);
return;
}
let redirects = channel.loadInfo.redirectChain;
let redirects = aChannel.loadInfo.redirectChain;
if (redirects[redirects.length - 1].principal.URI.host != this.fromDomain) {
info("didn't find redirect");
return;
}
info("setting channel");
this.channel = channel;
this.channel = aChannel;
let self = this;
info("unregistering");
@ -81,13 +79,13 @@ ProcessChooser.prototype = {
});
info("calling switchprocessto");
aRequestor.switchProcessTo(tabPromise, identifier);
aChannel.switchProcessTo(tabPromise, identifier);
},
observe(aSubject, aTopic, aData) {
switch (aTopic) {
case "http-on-may-change-process":
this.examine(aSubject.QueryInterface(Ci.nsIProcessSwitchRequestor));
this.examine(aSubject.QueryInterface(Ci.nsIHttpChannel));
break;
default:
ok(false, "Unexpected topic observed!");

Просмотреть файл

@ -9,8 +9,8 @@
# include "mozilla/Logging.h"
# include "mozilla/Maybe.h"
# include "mozilla/Monitor.h"
# include "mozilla/Mutex.h"
# include "mozilla/Monitor.h"
# include "mozilla/RefPtr.h"
# include "mozilla/Tuple.h"
# include "mozilla/TypeTraits.h"
@ -38,10 +38,6 @@
namespace mozilla {
namespace dom {
class Promise;
}
extern LazyLogModule gMozPromiseLog;
# define PROMISE_LOG(x, ...) \
@ -958,12 +954,6 @@ class MozPromise : public MozPromiseBase {
}
# endif
// Creates a C++ MozPromise from its JS counterpart, dom::Promise.
// FromDomPromise currently only supports primitive types (int8/16/32, float,
// double) And the reject value type must be a nsresult.
// To use, please include MozPromiseInlines.h
static RefPtr<MozPromise> FromDomPromise(dom::Promise* aDOMPromise);
// Note we expose the function AssertIsDead() instead of IsDead() since
// checking IsDead() is a data race in the situation where the request is not
// dead. Therefore we enforce the form |Assert(IsDead())| by exposing

Просмотреть файл

@ -1,53 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#if !defined(MozPromiseInlines_h_)
# define MozPromiseInlines_h_
# include "mozilla/MozPromise.h"
# include "mozilla/dom/PrimitiveConversions.h"
# include "mozilla/dom/PromiseNativeHandler.h"
namespace mozilla {
// Creates a C++ MozPromise from its JS counterpart, dom::Promise.
// FromDomPromise currently only supports primitive types (int8/16/32, float,
// double) And the reject value type must be a nsresult.
template <typename ResolveValueT, typename RejectValueT, bool IsExclusive>
RefPtr<MozPromise<ResolveValueT, RejectValueT, IsExclusive>>
MozPromise<ResolveValueT, RejectValueT, IsExclusive>::FromDomPromise(
dom::Promise* aDOMPromise) {
static_assert(IsSame<RejectValueType, nsresult>::value,
"Reject type must be nsresult");
RefPtr<Private> p = new Private(__func__);
RefPtr<dom::DomPromiseListener> listener = new dom::DomPromiseListener(
aDOMPromise,
[p](JSContext* aCx, JS::Handle<JS::Value> aValue) {
ResolveValueT value;
bool ok = dom::ValueToPrimitive<ResolveValueT,
dom::ConversionBehavior::eDefault>(
aCx, aValue, &value);
if (!ok) {
p->Reject(NS_ERROR_FAILURE, __func__);
return;
}
p->Resolve(value, __func__);
},
[p](JSContext* aCx, JS::Handle<JS::Value> aValue) {
if (!aValue.isInt32()) {
p->Reject(NS_ERROR_DOM_NOT_NUMBER_ERR, __func__);
return;
}
nsresult rv = nsresult(aValue.toInt32());
MOZ_ASSERT(NS_SUCCEEDED(rv));
p->Reject(rv, __func__);
});
return p;
}
} // namespace mozilla
#endif

Просмотреть файл

@ -53,7 +53,6 @@ EXPORTS.mozilla += [
'MainThreadIdlePeriod.h',
'Monitor.h',
'MozPromise.h',
'MozPromiseInlines.h',
'Mutex.h',
'PerformanceCounter.h',
'Queue.h',