Bug 1551601 - When performing a cross process redirect update the loadInfo to have the correct browsingContext r=nika

Differential Revision: https://phabricator.services.mozilla.com/D35839

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Valentin Gosu 2019-06-30 20:20:51 +00:00
Родитель 5cbe9516b1
Коммит a09f77fb6b
6 изменённых файлов: 70 добавлений и 15 удалений

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

@ -8301,19 +8301,22 @@ nsresult nsDocShell::CreateContentViewer(const nsACString& aContentType,
if (DocGroup::TryToLoadIframesInBackground()) {
if ((!mContentViewer || GetDocument()->IsInitialDocument()) && IsFrame()) {
// At this point, we know we just created a new iframe document based on the
// response from the server, and we check if it's a cross-domain iframe
// At this point, we know we just created a new iframe document based on
// the response from the server, and we check if it's a cross-domain
// iframe
RefPtr<Document> newDoc = viewer->GetDocument();
RefPtr<nsDocShell> parent = GetParentDocshell();
nsCOMPtr<nsIPrincipal> parentPrincipal = parent->GetDocument()->NodePrincipal();
nsCOMPtr<nsIPrincipal> parentPrincipal =
parent->GetDocument()->NodePrincipal();
nsCOMPtr<nsIPrincipal> thisPrincipal = newDoc->NodePrincipal();
SiteIdentifier parentSite;
SiteIdentifier thisSite;
nsresult rv = BasePrincipal::Cast(parentPrincipal)->GetSiteIdentifier(parentSite);
nsresult rv =
BasePrincipal::Cast(parentPrincipal)->GetSiteIdentifier(parentSite);
NS_ENSURE_SUCCESS(rv, rv);
rv = BasePrincipal::Cast(thisPrincipal)->GetSiteIdentifier(thisSite);
@ -8323,9 +8326,12 @@ nsresult nsDocShell::CreateContentViewer(const nsACString& aContentType,
#ifdef MOZ_GECKO_PROFILER
nsCOMPtr<nsIURI> prinURI;
thisPrincipal->GetURI(getter_AddRefs(prinURI));
nsPrintfCString marker("Iframe loaded in background: %s", prinURI->GetSpecOrDefault().get());
nsPrintfCString marker("Iframe loaded in background: %s",
prinURI->GetSpecOrDefault().get());
TimeStamp now = TimeStamp::Now();
profiler_add_text_marker("Background Iframe", marker, JS::ProfilingCategoryPair::DOM, now, now, Nothing(), Nothing());
profiler_add_text_marker("Background Iframe", marker,
JS::ProfilingCategoryPair::DOM, now, now,
Nothing(), Nothing());
#endif
SetBackgroundLoadIframe();
}
@ -8335,9 +8341,9 @@ nsresult nsDocShell::CreateContentViewer(const nsACString& aContentType,
NS_ENSURE_SUCCESS(Embed(viewer, "", nullptr), NS_ERROR_FAILURE);
if (TreatAsBackgroundLoad()) {
nsCOMPtr<nsIRunnable> triggerParentCheckDocShell = NewRunnableMethod(
"nsDocShell::TriggerParentCheckDocShellIsEmpty", this,
&nsDocShell::TriggerParentCheckDocShellIsEmpty);
nsCOMPtr<nsIRunnable> triggerParentCheckDocShell =
NewRunnableMethod("nsDocShell::TriggerParentCheckDocShellIsEmpty", this,
&nsDocShell::TriggerParentCheckDocShellIsEmpty);
nsresult rv = NS_DispatchToCurrentThread(triggerParentCheckDocShell);
NS_ENSURE_SUCCESS(rv, rv);
}
@ -10600,6 +10606,19 @@ nsresult nsDocShell::OpenInitializedChannel(nsIChannel* aChannel,
MaybeCreateInitialClientSource();
nsCOMPtr<nsILoadInfo> loadInfo;
aChannel->GetLoadInfo(getter_AddRefs(loadInfo));
LoadInfo* li = static_cast<LoadInfo*>(loadInfo.get());
if (loadInfo->GetExternalContentPolicyType() ==
nsIContentPolicy::TYPE_DOCUMENT) {
li->UpdateBrowsingContextID(mBrowsingContext->Id());
} else if (loadInfo->GetExternalContentPolicyType() ==
nsIContentPolicy::TYPE_SUBDOCUMENT) {
li->UpdateFrameBrowsingContextID(mBrowsingContext->Id());
}
// TODO: more attributes need to be updated on the LoadInfo (bug 1561706)
// Since we are loading a document we need to make sure the proper reserved
// and initial client data is stored on the nsILoadInfo. The
// ClientChannelHelper does this and ensures that it is propagated properly

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

@ -174,6 +174,16 @@ class LoadInfo final : public nsILoadInfo {
void SetIncludeCookiesSecFlag();
friend class mozilla::dom::XMLHttpRequestMainThread;
// nsDocShell::OpenInitializedChannel needs to update the loadInfo with
// the correct browsingContext.
friend class ::nsDocShell;
void UpdateBrowsingContextID(uint64_t aBrowsingContextID) {
mBrowsingContextID = aBrowsingContextID;
}
void UpdateFrameBrowsingContextID(uint64_t aFrameBrowsingContextID) {
mFrameBrowsingContextID = aFrameBrowsingContextID;
}
// if you add a member, please also update the copy constructor and consider
// if it should be merged from parent channel through
// ParentLoadInfoForwarderArgs.

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

@ -4060,7 +4060,16 @@ nsresult HttpChannelChild::CrossProcessRedirectFinished(nsresult aStatus) {
if (!CanSend()) {
return NS_BINDING_FAILED;
}
Unused << SendCrossProcessRedirectDone(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(aStatus, loadInfoArgs);
return NS_OK;
}

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

@ -1249,9 +1249,25 @@ static void FinishCrossProcessRedirect(nsHttpChannel* channel,
}
mozilla::ipc::IPCResult HttpChannelParent::RecvCrossProcessRedirectDone(
const nsresult& aResult) {
const nsresult& aResult,
const mozilla::Maybe<LoadInfoArgs>& aLoadInfoArgs) {
RefPtr<nsHttpChannel> chan = do_QueryObject(mChannel);
nsresult rv = NS_OK;
auto sendReply =
MakeScopeExit([&]() { FinishCrossProcessRedirect(chan, rv); });
nsCOMPtr<nsILoadInfo> newLoadInfo;
rv = LoadInfoArgsToLoadInfo(aLoadInfoArgs, getter_AddRefs(newLoadInfo));
if (NS_FAILED(rv)) {
return IPC_OK();
}
if (newLoadInfo) {
chan->SetLoadInfo(newLoadInfo);
}
if (!mBgParent) {
sendReply.release();
RefPtr<HttpChannelParent> self = this;
WaitForBgParent()->Then(
GetMainThreadSerialEventTarget(), __func__,
@ -1260,8 +1276,6 @@ mozilla::ipc::IPCResult HttpChannelParent::RecvCrossProcessRedirectDone(
MOZ_ASSERT(NS_FAILED(aRejectionRv), "This should be an error code");
FinishCrossProcessRedirect(chan, aRejectionRv);
});
} else {
FinishCrossProcessRedirect(chan, aResult);
}
return IPC_OK();

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

@ -201,7 +201,8 @@ class HttpChannelParent final : public nsIInterfaceRequestor,
const nsresult& statusCode) override;
virtual mozilla::ipc::IPCResult RecvDivertComplete() override;
virtual mozilla::ipc::IPCResult RecvCrossProcessRedirectDone(
const nsresult& aResult) override;
const nsresult& aResult,
const mozilla::Maybe<LoadInfoArgs>& aLoadInfoArgs) override;
virtual mozilla::ipc::IPCResult RecvRemoveCorsPreflightCacheEntry(
const URIParams& uri,
const mozilla::ipc::PrincipalInfo& requestingPrincipal) override;

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

@ -52,7 +52,9 @@ parent:
// 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.
async CrossProcessRedirectDone(nsresult result);
// 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