зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1575744 - P7. Promisify SendCrossProcessRedirect to avoid needing PHttpChannel to get a response. r=mayhemer
Differential Revision: https://phabricator.services.mozilla.com/D46163 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
9d8eadbabe
Коммит
7cdc8e0a68
|
@ -3636,7 +3636,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) {
|
||||
const uint32_t& aRedirectMode, CrossProcessRedirectResolver&& aResolve) {
|
||||
nsCOMPtr<nsILoadInfo> loadInfo;
|
||||
nsresult rv =
|
||||
mozilla::ipc::LoadInfoArgsToLoadInfo(aLoadInfo, getter_AddRefs(loadInfo));
|
||||
|
@ -3658,8 +3658,16 @@ mozilla::ipc::IPCResult ContentChild::RecvCrossProcessRedirect(
|
|||
|
||||
// This is used to report any errors back to the parent by calling
|
||||
// CrossProcessRedirectFinished.
|
||||
auto scopeExit =
|
||||
MakeScopeExit([&]() { httpChild->CrossProcessRedirectFinished(rv); });
|
||||
auto scopeExit = MakeScopeExit([&]() {
|
||||
rv = httpChild->CrossProcessRedirectFinished(rv);
|
||||
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));
|
||||
});
|
||||
|
||||
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);
|
||||
const uint32_t& aRedirectMode, CrossProcessRedirectResolver&& aResolve);
|
||||
|
||||
mozilla::ipc::IPCResult RecvStartDelayedAutoplayMediaComponents(
|
||||
BrowsingContext* aContext);
|
||||
|
|
|
@ -791,6 +791,9 @@ 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,
|
||||
|
@ -798,7 +801,8 @@ child:
|
|||
uint64_t aChannelId,
|
||||
nsIURI aOriginalURI,
|
||||
uint64_t aIdentifier,
|
||||
uint32_t aRedirectMode);
|
||||
uint32_t aRedirectMode)
|
||||
returns (nsresult rv, LoadInfoArgs? arg);
|
||||
|
||||
/**
|
||||
* This method is used to notifty content process to start delayed autoplay
|
||||
|
|
|
@ -11,19 +11,6 @@
|
|||
[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
|
||||
|
|
|
@ -359,16 +359,6 @@ void DocumentChannelParent::FinishReplacementChannelSetup(bool aSucceeded) {
|
|||
}
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
DocumentChannelParent::FinishCrossProcessSwitch(
|
||||
nsIAsyncVerifyRedirectCallback* aCallback, nsresult aStatusCode) {
|
||||
// This updates ParentChannelListener to point to this parent and at
|
||||
// the same time cancels the old channel.
|
||||
FinishReplacementChannelSetup(NS_SUCCEEDED(aStatusCode));
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult DocumentChannelParent::TriggerCrossProcessSwitch(
|
||||
nsIHttpChannel* aChannel, uint64_t aIdentifier) {
|
||||
MOZ_ASSERT_UNREACHABLE(
|
||||
|
@ -534,6 +524,7 @@ void DocumentChannelParent::TriggerRedirectToRealChannel(
|
|||
contentDispositionFilename = Some(contentDispositionFilenameTemp);
|
||||
}
|
||||
|
||||
RefPtr<DocumentChannelParent> self = this;
|
||||
if (aDestinationProcess) {
|
||||
dom::ContentParent* cp =
|
||||
dom::ContentProcessManager::GetSingleton()->GetContentProcessById(
|
||||
|
@ -544,24 +535,36 @@ void DocumentChannelParent::TriggerRedirectToRealChannel(
|
|||
|
||||
MOZ_ASSERT(config);
|
||||
|
||||
auto result = cp->SendCrossProcessRedirect(
|
||||
mRedirectChannelId, uri, *config, loadInfoArgs, channelId, originalURI,
|
||||
aIdentifier, redirectMode);
|
||||
MOZ_ASSERT(result, "SendCrossProcessRedirect failed");
|
||||
Unused << result;
|
||||
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);
|
||||
});
|
||||
} else {
|
||||
RefPtr<DocumentChannelParent> channel = this;
|
||||
SendRedirectToRealChannel(mRedirectChannelId, uri, newLoadFlags, config,
|
||||
loadInfoArgs, mRedirects, channelId, originalURI,
|
||||
redirectMode, redirectFlags, contentDisposition,
|
||||
contentDispositionFilename)
|
||||
->Then(
|
||||
GetCurrentThreadSerialEventTarget(), __func__,
|
||||
[channel](nsresult aRv) {
|
||||
channel->RedirectToRealChannelFinished(aRv);
|
||||
},
|
||||
[channel](const mozilla::ipc::ResponseRejectReason) {
|
||||
channel->RedirectToRealChannelFinished(NS_ERROR_FAILURE);
|
||||
[self](nsresult aRv) { self->RedirectToRealChannelFinished(aRv); },
|
||||
[self](const mozilla::ipc::ResponseRejectReason) {
|
||||
self->RedirectToRealChannelFinished(NS_ERROR_FAILURE);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4085,16 +4085,7 @@ nsresult HttpChannelChild::CrossProcessRedirectFinished(nsresult aStatus) {
|
|||
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;
|
||||
return mStatus;
|
||||
}
|
||||
|
||||
} // namespace net
|
||||
|
|
|
@ -1257,48 +1257,36 @@ void HttpChannelParent::MaybeFlushPendingDiversion() {
|
|||
}
|
||||
}
|
||||
|
||||
static void FinishCrossProcessSwitchHelper(nsHttpChannel* aChannel,
|
||||
nsresult aStatus) {
|
||||
nsCOMPtr<nsICrossProcessSwitchChannel> switchListener;
|
||||
NS_QueryNotificationCallbacks(aChannel, switchListener);
|
||||
if (!switchListener) {
|
||||
// This can happen if the channel got aborted before the switch completed
|
||||
// and OnStopRequest got called in between which cleared the callback.
|
||||
return;
|
||||
}
|
||||
|
||||
switchListener->FinishCrossProcessSwitch(aChannel, aStatus);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
HttpChannelParent::FinishCrossProcessSwitch(
|
||||
nsIAsyncVerifyRedirectCallback* aCallback, nsresult aStatus) {
|
||||
void HttpChannelParent::FinishCrossProcessSwitch(nsHttpChannel* aChannel,
|
||||
nsresult aStatus) {
|
||||
if (NS_SUCCEEDED(aStatus)) {
|
||||
nsCOMPtr<nsIRedirectResultListener> redirectListener;
|
||||
NS_QueryNotificationCallbacks(aChannel, redirectListener);
|
||||
MOZ_ASSERT(redirectListener);
|
||||
|
||||
// This updates ParentChannelListener to point to this parent and at
|
||||
// the same time cancels the old channel.
|
||||
OnRedirectResult(true);
|
||||
redirectListener->OnRedirectResult(true);
|
||||
}
|
||||
|
||||
aCallback->OnRedirectVerifyCallback(aStatus);
|
||||
return NS_OK;
|
||||
aChannel->OnRedirectVerifyCallback(aStatus);
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult HttpChannelParent::RecvCrossProcessRedirectDone(
|
||||
void HttpChannelParent::CrossProcessRedirectDone(
|
||||
const nsresult& aResult,
|
||||
const mozilla::Maybe<LoadInfoArgs>& aLoadInfoArgs) {
|
||||
RefPtr<nsHttpChannel> chan = do_QueryObject(mChannel);
|
||||
nsresult rv = aResult;
|
||||
auto sendReply =
|
||||
MakeScopeExit([&]() { FinishCrossProcessSwitchHelper(chan, rv); });
|
||||
auto sendReply = MakeScopeExit([&]() { FinishCrossProcessSwitch(chan, rv); });
|
||||
|
||||
if (NS_FAILED(rv)) {
|
||||
return IPC_OK();
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsILoadInfo> newLoadInfo;
|
||||
rv = LoadInfoArgsToLoadInfo(aLoadInfoArgs, getter_AddRefs(newLoadInfo));
|
||||
if (NS_FAILED(rv)) {
|
||||
return IPC_OK();
|
||||
return;
|
||||
}
|
||||
|
||||
if (newLoadInfo) {
|
||||
|
@ -1311,15 +1299,13 @@ mozilla::ipc::IPCResult HttpChannelParent::RecvCrossProcessRedirectDone(
|
|||
WaitForBgParent()->Then(
|
||||
GetMainThreadSerialEventTarget(), __func__,
|
||||
[self, chan, aResult]() {
|
||||
FinishCrossProcessSwitchHelper(chan, aResult);
|
||||
self->FinishCrossProcessSwitch(chan, aResult);
|
||||
},
|
||||
[self, chan](const nsresult& aRejectionRv) {
|
||||
MOZ_ASSERT(NS_FAILED(aRejectionRv), "This should be an error code");
|
||||
FinishCrossProcessSwitchHelper(chan, aRejectionRv);
|
||||
self->FinishCrossProcessSwitch(chan, aRejectionRv);
|
||||
});
|
||||
}
|
||||
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
void HttpChannelParent::ResponseSynthesized() {
|
||||
|
@ -2683,7 +2669,7 @@ nsresult HttpChannelParent::TriggerCrossProcessSwitch(nsIHttpChannel* aChannel,
|
|||
RedirectChannelRegistrar::GetOrCreate();
|
||||
MOZ_ASSERT(registrar);
|
||||
rv = registrar->RegisterChannel(channel, &self->mRedirectChannelId);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
NS_ENSURE_SUCCESS_VOID(rv);
|
||||
|
||||
LOG(("Registered %p channel under id=%d", channel.get(),
|
||||
self->mRedirectChannelId));
|
||||
|
@ -2714,15 +2700,34 @@ nsresult HttpChannelParent::TriggerCrossProcessSwitch(nsIHttpChannel* aChannel,
|
|||
dom::ContentProcessManager::GetSingleton()->GetContentProcessById(
|
||||
ContentParentId{cpId});
|
||||
if (!cp) {
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
return;
|
||||
}
|
||||
auto result = cp->SendCrossProcessRedirect(
|
||||
self->mRedirectChannelId, uri, config, loadInfoArgs, channelId,
|
||||
originalURI, aIdentifier, redirectMode);
|
||||
cp->SendCrossProcessRedirect(self->mRedirectChannelId, uri, config,
|
||||
loadInfoArgs, channelId, originalURI,
|
||||
aIdentifier, redirectMode)
|
||||
->Then(
|
||||
GetCurrentThreadSerialEventTarget(), __func__,
|
||||
[self](Tuple<nsresult, Maybe<LoadInfoArgs>>&& aResponse) {
|
||||
// We need to continue on the new HttpChannelParent.
|
||||
MOZ_ASSERT(self->mRedirectChannelId);
|
||||
nsCOMPtr<nsIRedirectChannelRegistrar> redirectReg =
|
||||
RedirectChannelRegistrar::GetOrCreate();
|
||||
MOZ_ASSERT(redirectReg);
|
||||
|
||||
MOZ_ASSERT(result, "SendCrossProcessRedirect failed");
|
||||
|
||||
return result ? NS_OK : NS_ERROR_UNEXPECTED;
|
||||
nsCOMPtr<nsIParentChannel> redirectParentChannel;
|
||||
redirectReg->GetParentChannel(
|
||||
self->mRedirectChannelId,
|
||||
getter_AddRefs(redirectParentChannel));
|
||||
MOZ_ASSERT(redirectParentChannel);
|
||||
RefPtr<HttpChannelParent> newParent =
|
||||
do_QueryObject(redirectParentChannel);
|
||||
MOZ_ASSERT(newParent);
|
||||
newParent->CrossProcessRedirectDone(Get<0>(aResponse),
|
||||
Get<1>(aResponse));
|
||||
},
|
||||
[self](const mozilla::ipc::ResponseRejectReason) {
|
||||
self->CrossProcessRedirectDone(NS_ERROR_FAILURE, Nothing());
|
||||
});
|
||||
},
|
||||
[httpChannel](nsresult aStatus) {
|
||||
MOZ_ASSERT(NS_FAILED(aStatus), "Status should be error");
|
||||
|
|
|
@ -209,9 +209,6 @@ 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;
|
||||
|
@ -255,6 +252,11 @@ 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
|
||||
|
|
|
@ -50,12 +50,6 @@ 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.
|
||||
|
|
Загрузка…
Ссылка в новой задаче