Bug 1583076 - Pass LoadInfo back for the current channel when confirming redirects. r=ckerschb

We previously used the initial LoadInfo from when the DocumentChannel was created, but need the one from the most recent channel in the parent.

Depends on D46740

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

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Matt Woodrow 2019-09-24 12:13:49 +00:00
parent 29c34b4b28
commit 4b5ad7f5c4
4 changed files with 32 additions and 21 deletions

View File

@ -255,12 +255,8 @@ IPCResult DocumentChannelChild::RecvRedirectToRealChannel(
const uint32_t& aRedirectFlags, const Maybe<uint32_t>& aContentDisposition,
const Maybe<nsString>& aContentDispositionFilename,
RedirectToRealChannelResolver&& aResolve) {
nsCOMPtr<nsILoadInfo> originalLoadInfo;
RefPtr<dom::Document> loadingDocument;
GetLoadInfo(getter_AddRefs(originalLoadInfo));
if (originalLoadInfo) {
originalLoadInfo->GetLoadingDocument(getter_AddRefs(loadingDocument));
}
mLoadInfo->GetLoadingDocument(getter_AddRefs(loadingDocument));
nsCOMPtr<nsILoadInfo> loadInfo;
nsresult rv = LoadInfoArgsToLoadInfo(aLoadInfo, loadingDocument,
@ -404,11 +400,18 @@ DocumentChannelChild::OnRedirectVerifyCallback(nsresult aStatusCode) {
}
IPCResult DocumentChannelChild::RecvConfirmRedirect(
nsIURI* aNewUri, ConfirmRedirectResolver&& aResolve) {
const LoadInfoArgs& aLoadInfo, nsIURI* aNewUri,
ConfirmRedirectResolver&& aResolve) {
// This is effectively the same as AsyncOnChannelRedirect, except since we're
// not propagating the redirect into this process, we don't have an nsIChannel
// for the redirection and we have to do the checks manually.
// This just checks CSP thus far, hopefully there's not much else needed.
RefPtr<dom::Document> loadingDocument;
mLoadInfo->GetLoadingDocument(getter_AddRefs(loadingDocument));
nsCOMPtr<nsILoadInfo> loadInfo;
MOZ_ALWAYS_SUCCEEDS(LoadInfoArgsToLoadInfo(Some(aLoadInfo), loadingDocument,
getter_AddRefs(loadInfo)));
nsCOMPtr<nsIURI> originalUri;
nsresult rv = GetOriginalURI(getter_AddRefs(originalUri));
if (NS_FAILED(rv)) {
@ -418,7 +421,7 @@ IPCResult DocumentChannelChild::RecvConfirmRedirect(
}
Maybe<nsresult> cancelCode;
rv = CSPService::ConsultCSPForRedirect(originalUri, aNewUri, mLoadInfo,
rv = CSPService::ConsultCSPForRedirect(originalUri, aNewUri, loadInfo,
cancelCode);
aResolve(Tuple<const nsresult&, const Maybe<nsresult>&>(rv, cancelCode));
return IPC_OK();

View File

@ -82,7 +82,8 @@ class DocumentChannelChild final : public PDocumentChannelChild,
const nsCString& aLists, const nsCString& aFullHash);
mozilla::ipc::IPCResult RecvConfirmRedirect(
nsIURI* aNewUri, ConfirmRedirectResolver&& aResolve);
const LoadInfoArgs& aLoadInfo, nsIURI* aNewUri,
ConfirmRedirectResolver&& aResolve);
void DoFailedAsyncOpen(const nsresult& aStatusCode);

View File

@ -801,24 +801,31 @@ DocumentChannelParent::AsyncOnChannelRedirect(
// process so that it can send events. Send a message to
// our content process to ask CSP if we should allow this
// redirect, and wait for confirmation.
nsCOMPtr<nsILoadInfo> loadInfo = aOldChannel->LoadInfo();
Maybe<LoadInfoArgs> loadInfoArgs;
MOZ_ALWAYS_SUCCEEDS(ipc::LoadInfoToLoadInfoArgs(loadInfo, &loadInfoArgs));
MOZ_ASSERT(loadInfoArgs.isSome());
nsCOMPtr<nsIURI> newUri;
nsresult rv = aNewChannel->GetURI(getter_AddRefs(newUri));
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIAsyncVerifyRedirectCallback> callback(aCallback);
nsCOMPtr<nsIChannel> oldChannel(aOldChannel);
SendConfirmRedirect(newUri)->Then(
GetCurrentThreadSerialEventTarget(), __func__,
[callback, oldChannel](const Tuple<nsresult, Maybe<nsresult>>& aResult) {
if (Get<1>(aResult)) {
oldChannel->Cancel(*Get<1>(aResult));
}
callback->OnRedirectVerifyCallback(Get<0>(aResult));
},
[callback, oldChannel](const mozilla::ipc::ResponseRejectReason) {
oldChannel->Cancel(NS_ERROR_DOM_BAD_URI);
callback->OnRedirectVerifyCallback(NS_BINDING_ABORTED);
});
SendConfirmRedirect(*loadInfoArgs, newUri)
->Then(
GetCurrentThreadSerialEventTarget(), __func__,
[callback,
oldChannel](const Tuple<nsresult, Maybe<nsresult>>& aResult) {
if (Get<1>(aResult)) {
oldChannel->Cancel(*Get<1>(aResult));
}
callback->OnRedirectVerifyCallback(Get<0>(aResult));
},
[callback, oldChannel](const mozilla::ipc::ResponseRejectReason) {
oldChannel->Cancel(NS_ERROR_DOM_BAD_URI);
callback->OnRedirectVerifyCallback(NS_BINDING_ABORTED);
});
// Clear out our nsIParentChannel functions, since a normal parent
// channel would actually redirect and not have those values on the new one.

View File

@ -75,7 +75,7 @@ child:
uint32_t? aContentDisposition,
nsString? aContentDispositionFilename) returns(nsresult rv);
async ConfirmRedirect(nsIURI aNewURI) returns(nsresult rv, nsresult? cancelCode);
async ConfirmRedirect(LoadInfoArgs aLoadInfo, nsIURI aNewURI) returns(nsresult rv, nsresult? cancelCode);
// Tell child to delete channel (all IPDL deletes must be done from child to
// avoid races: see bug 591708).