зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1575744 - P5. Implement process switch from DocumentChannelParent. r=mayhemer
Differential Revision: https://phabricator.services.mozilla.com/D46020 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
912b0df630
Коммит
abec029eac
|
@ -8,6 +8,7 @@
|
|||
#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"
|
||||
|
@ -40,6 +41,7 @@ NS_INTERFACE_MAP_BEGIN(DocumentChannelParent)
|
|||
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
|
||||
|
||||
|
@ -369,26 +371,22 @@ DocumentChannelParent::FinishCrossProcessSwitch(
|
|||
|
||||
nsresult DocumentChannelParent::TriggerCrossProcessSwitch(
|
||||
nsIHttpChannel* aChannel, uint64_t aIdentifier) {
|
||||
RefPtr<nsHttpChannel> httpChannel = do_QueryObject(aChannel);
|
||||
MOZ_DIAGNOSTIC_ASSERT(httpChannel,
|
||||
"Must be called with nsHttpChannel object");
|
||||
RefPtr<ContentProcessIdPromise> p =
|
||||
httpChannel->TakeRedirectContentProcessIdPromise();
|
||||
TriggerCrossProcessSwitch(p.forget(), aIdentifier, httpChannel);
|
||||
MOZ_ASSERT_UNREACHABLE(
|
||||
"We can no longer be called from nsHttpChannel, this interface will be "
|
||||
"removed in a follow-up patch");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void DocumentChannelParent::TriggerCrossProcessSwitch(
|
||||
already_AddRefed<ContentProcessIdPromise> aPromise, uint64_t aIdentifier,
|
||||
nsHttpChannel* aChannel) {
|
||||
void DocumentChannelParent::TriggerCrossProcessSwitch() {
|
||||
MOZ_ASSERT(mRedirectContentProcessIdPromise);
|
||||
CancelChildForProcessSwitch();
|
||||
RefPtr<DocumentChannelParent> self = this;
|
||||
RefPtr<nsHttpChannel> channel = aChannel;
|
||||
RefPtr<ContentProcessIdPromise> p = aPromise;
|
||||
p->Then(
|
||||
mRedirectContentProcessIdPromise->Then(
|
||||
GetMainThreadSerialEventTarget(), __func__,
|
||||
[self, aIdentifier, channel](uint64_t aCpId) {
|
||||
self->TriggerRedirectToRealChannel(channel, Some(aCpId), aIdentifier);
|
||||
[self, this](uint64_t aCpId) {
|
||||
MOZ_ASSERT(mChannel, "Something went wrong, channel got cancelled");
|
||||
TriggerRedirectToRealChannel(mChannel, Some(aCpId),
|
||||
mCrossProcessRedirectIdentifier);
|
||||
},
|
||||
[self](nsresult aStatusCode) {
|
||||
MOZ_ASSERT(NS_FAILED(aStatusCode), "Status should be error");
|
||||
|
@ -606,14 +604,11 @@ DocumentChannelParent::OnStartRequest(nsIRequest* aRequest) {
|
|||
|
||||
// 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 channel->SwitchProcessTo() will be called which will
|
||||
// set a ContentProcessIdPromise.
|
||||
gHttpHandler->OnMayChangeProcess(channel);
|
||||
RefPtr<ContentProcessIdPromise> promise =
|
||||
channel->TakeRedirectContentProcessIdPromise();
|
||||
if (promise) {
|
||||
TriggerCrossProcessSwitch(
|
||||
promise.forget(), channel->CrossProcessRedirectIdentifier(), channel);
|
||||
// spawned and if so SwitchProcessTo() will be called which will set a
|
||||
// ContentProcessIdPromise.
|
||||
gHttpHandler->OnMayChangeProcess(this);
|
||||
if (mRedirectContentProcessIdPromise) {
|
||||
TriggerCrossProcessSwitch();
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
|
@ -839,5 +834,47 @@ 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
|
||||
|
|
|
@ -38,7 +38,8 @@ class DocumentChannelParent : public nsIInterfaceRequestor,
|
|||
public nsIParentChannel,
|
||||
public nsIChannelEventSink,
|
||||
public nsICrossProcessSwitchChannel,
|
||||
public HttpChannelSecurityWarningReporter {
|
||||
public HttpChannelSecurityWarningReporter,
|
||||
public nsIProcessSwitchRequestor {
|
||||
public:
|
||||
explicit DocumentChannelParent(const dom::PBrowserOrId& iframeEmbedding,
|
||||
nsILoadContext* aLoadContext,
|
||||
|
@ -54,6 +55,7 @@ class DocumentChannelParent : public nsIInterfaceRequestor,
|
|||
NS_DECL_NSIASYNCVERIFYREDIRECTREADYCALLBACK
|
||||
NS_DECL_NSICHANNELEVENTSINK
|
||||
NS_DECL_NSICROSSPROCESSSWITCHCHANNEL
|
||||
NS_DECL_NSIPROCESSSWITCHREQUESTOR
|
||||
|
||||
NS_DECLARE_STATIC_IID_ACCESSOR(DOCUMENT_CHANNEL_PARENT_IID)
|
||||
|
||||
|
@ -111,11 +113,7 @@ class DocumentChannelParent : public nsIInterfaceRequestor,
|
|||
|
||||
void FinishReplacementChannelSetup(bool aSucceeded);
|
||||
|
||||
typedef MozPromise<uint64_t, nsresult, true /* exclusive */>
|
||||
ContentProcessIdPromise;
|
||||
void TriggerCrossProcessSwitch(
|
||||
already_AddRefed<ContentProcessIdPromise> aPromise, uint64_t aIdentifier,
|
||||
nsHttpChannel* aChannel);
|
||||
void TriggerCrossProcessSwitch();
|
||||
|
||||
// This defines a variant that describes all the attribute setters (and their
|
||||
// parameters) from nsIParentChannel
|
||||
|
@ -216,6 +214,18 @@ 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,
|
||||
|
|
Загрузка…
Ссылка в новой задаче