mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-27 23:02:20 +00:00
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:
parent
d85a0b1f8f
commit
bee28f01d7
@ -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',
|
||||
|
39
netwerk/base/nsICrossProcessSwitchChannel.idl
Normal file
39
netwerk/base/nsICrossProcessSwitchChannel.idl
Normal file
@ -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,
|
||||
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,13 +2579,6 @@ nsresult nsHttpChannel::ContinueProcessResponse1() {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIParentChannel> parentChannel;
|
||||
NS_QueryNotificationCallbacks(this, parentChannel);
|
||||
|
||||
RefPtr<DocumentChannelParent> documentChannelParent =
|
||||
do_QueryObject(parentChannel);
|
||||
|
||||
if (!documentChannelParent) {
|
||||
// notify "http-on-may-change-process" observers
|
||||
gHttpHandler->OnMayChangeProcess(this);
|
||||
|
||||
@ -2601,7 +2593,6 @@ nsresult nsHttpChannel::ContinueProcessResponse1() {
|
||||
PopRedirectAsyncFunc(&nsHttpChannel::ContinueProcessResponse2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// No process switch needed, continue as normal.
|
||||
return ContinueProcessResponse2(rv);
|
||||
@ -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,14 +7232,50 @@ 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) {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
@ -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);
|
||||
}
|
||||
|
||||
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,11 +7731,6 @@ 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);
|
||||
|
||||
if (mRedirectContentProcessIdPromise) {
|
||||
@ -7732,7 +7742,6 @@ nsHttpChannel::OnStartRequest(nsIRequest* request) {
|
||||
PopRedirectAsyncFunc(&nsHttpChannel::ContinueOnStartRequest1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// No process change is needed, so continue on to ContinueOnStartRequest1.
|
||||
return ContinueOnStartRequest1(rv);
|
||||
|
@ -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',
|
||||
|
Loading…
Reference in New Issue
Block a user