Bug 1649879 - Handle URIFixup that happens on a failed channel in DocumentLoadListener if available, rather than waiting for it to reach nsDocShell. r=kmag

Differential Revision: https://phabricator.services.mozilla.com/D81947
This commit is contained in:
Matt Woodrow 2020-07-08 23:38:22 +00:00
parent 8575748f00
commit 17fbf88433
4 changed files with 50 additions and 10 deletions

View File

@ -1429,16 +1429,6 @@ var gKeywordURIFixup = {
this.check(browser, fixupInfo);
},
receiveMessage({ target: browser, data: fixupInfo }) {
// As fixupInfo comes from a serialized message, its URI properties are
// strings that we need to recreate nsIURIs from.
this.check(browser, {
fixedURI: fixupInfo.fixedURI ? makeURI(fixupInfo.fixedURI) : null,
keywordProviderName: fixupInfo.keywordProviderName,
preferredURI: makeURI(fixupInfo.preferredURI),
});
},
};
function serializeInputStream(aStream) {

View File

@ -9576,6 +9576,10 @@ nsresult nsDocShell::DoURILoad(nsDocShellLoadState* aLoadState,
loadFlags, this, cacheKey,
uriModified, isXFOError);
MOZ_ASSERT(channel);
// Disable keyword fixup when using DocumentChannel, since
// DocumentLoadListener will handle this for us (in the parent process).
mAllowKeywordFixup = false;
} else if (!CreateAndConfigureRealChannelForLoadState(
mBrowsingContext, aLoadState, loadInfo, this, this,
GetOriginAttributes(), loadFlags, cacheKey, rv,

View File

@ -1774,6 +1774,39 @@ bool DocumentLoadListener::DocShellWillDisplayContent(nsresult aStatus) {
return NS_FAILED(rv);
}
bool DocumentLoadListener::MaybeHandleLoadErrorWithURIFixup(nsresult aStatus) {
nsCOMPtr<nsIInputStream> newPostData;
nsCOMPtr<nsIURI> newURI = nsDocShell::AttemptURIFixup(
mChannel, aStatus, mOriginalUriString, mLoadStateLoadType,
GetBrowsingContext()->IsTop(),
mLoadStateLoadFlags &
nsDocShell::INTERNAL_LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP,
GetBrowsingContext()->UsePrivateBrowsing(), true,
getter_AddRefs(newPostData));
if (!newURI) {
return false;
}
// If we got a new URI, then we should initiate a load with that.
// Notify the listeners that this load is complete (with a code that
// won't trigger an error page), and then start the new one.
DisconnectListeners(NS_BINDING_ABORTED, NS_BINDING_ABORTED);
RefPtr<nsDocShellLoadState> loadState = new nsDocShellLoadState(newURI);
nsCOMPtr<nsILoadInfo> loadInfo = mChannel->LoadInfo();
nsCOMPtr<nsIContentSecurityPolicy> cspToInherit = loadInfo->GetCspToInherit();
loadState->SetCsp(cspToInherit);
nsCOMPtr<nsIPrincipal> triggeringPrincipal = loadInfo->TriggeringPrincipal();
loadState->SetTriggeringPrincipal(triggeringPrincipal);
loadState->SetPostDataStream(newPostData);
GetBrowsingContext()->LoadURI(loadState, false);
return true;
}
NS_IMETHODIMP
DocumentLoadListener::OnStartRequest(nsIRequest* aRequest) {
LOG(("DocumentLoadListener OnStartRequest [this=%p]", this));
@ -1810,6 +1843,13 @@ DocumentLoadListener::OnStartRequest(nsIRequest* aRequest) {
return NS_OK;
}
// If this was a failed load and we want to try fixing the uri, then
// this will initiate a new load (and disconnect this one), and we don't
// need to do anything else.
if (MaybeHandleLoadErrorWithURIFixup(status)) {
return NS_OK;
}
mStreamListenerFunctions.AppendElement(StreamListenerFunction{
VariantIndex<0>{}, OnStartRequestParams{aRequest}});

View File

@ -314,6 +314,12 @@ class DocumentLoadListener : public nsIInterfaceRequestor,
// Returns false if the docshell will ignore the load entirely.
bool DocShellWillDisplayContent(nsresult aStatus);
// Returns true if this is a failed load, where we have successfully
// created a fixed URI to attempt loading instead.
// If successful, this calls DisconnectListeners to completely finish
// the current load, and calls BrowsingContext::LoadURI to start the new one.
bool MaybeHandleLoadErrorWithURIFixup(nsresult aStatus);
// This defines a variant that describes all the attribute setters (and their
// parameters) from nsIParentChannel
//