Backed out 9 changesets (bug 1626362) for failures on a-download-click-404.html. CLOSED TREE

Backed out changeset d29ac651a4fd (bug 1626362)
Backed out changeset 5ba5cf98a95d (bug 1626362)
Backed out changeset 69b5b01da9c1 (bug 1626362)
Backed out changeset 1d31061f4421 (bug 1626362)
Backed out changeset a627870e35fb (bug 1626362)
Backed out changeset 5f3ee46032b6 (bug 1626362)
Backed out changeset 5b170666991e (bug 1626362)
Backed out changeset 4d31c2ede058 (bug 1626362)
Backed out changeset 66a9ba0f87cb (bug 1626362)
This commit is contained in:
Csoregi Natalia 2020-06-25 02:45:52 +03:00
parent bdaad3b232
commit e67ceab432
21 changed files with 395 additions and 546 deletions

View File

@ -1,3 +0,0 @@
function handleRequest(request, response) {
response.setStatusLine(request.httpVersion, 204, "No Content");
}

View File

@ -1,2 +0,0 @@
<!doctype html>
This page intentionally left blank.

View File

@ -19,10 +19,6 @@ tags = audiochannel
skip-if = (verify && debug && (os == 'linux')) skip-if = (verify && debug && (os == 'linux'))
support-files = support-files =
test_bug1358314.html test_bug1358314.html
[browser_dont_process_switch_204.js]
support-files =
blank.html
204.sjs
[browser_e10s_about_page_triggeringprincipal.js] [browser_e10s_about_page_triggeringprincipal.js]
skip-if = verify skip-if = verify
support-files = support-files =

View File

@ -1,56 +0,0 @@
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
const TEST_ROOT = getRootDirectory(gTestPath).replace(
"chrome://mochitests/content",
"https://example.com"
);
const TEST_URL = TEST_ROOT + "204.sjs";
const BLANK_URL = TEST_ROOT + "blank.html";
// Test for bug 1626362.
add_task(async function() {
await BrowserTestUtils.withNewTab("about:robots", async function(aBrowser) {
// Get the current pid for browser for comparison later, we expect this
// to be the parent process for about:robots.
let browserPid = await SpecialPowers.spawn(aBrowser, [], () => {
return Services.appinfo.processID;
});
is(
Services.appinfo.processID,
browserPid,
"about:robots should have loaded in the parent"
);
// Attempt to load a uri that returns a 204 response, and then check that
// we didn't process switch for it.
let stopped = BrowserTestUtils.browserStopped(aBrowser, TEST_URL, true);
BrowserTestUtils.loadURI(aBrowser, TEST_URL);
await stopped;
let newPid = await SpecialPowers.spawn(aBrowser, [], () => {
return Services.appinfo.processID;
});
is(
browserPid,
newPid,
"Shouldn't change process when we get a 204 response"
);
// Load a valid http page and confirm that we did change process
// to confirm that we weren't in a web process to begin with.
let loaded = BrowserTestUtils.browserLoaded(aBrowser, false, BLANK_URL);
BrowserTestUtils.loadURI(aBrowser, BLANK_URL);
await loaded;
newPid = await SpecialPowers.spawn(aBrowser, [], () => {
return Services.appinfo.processID;
});
isnot(browserPid, newPid, "Should change process for a valid response");
});
});

View File

@ -321,8 +321,6 @@ already_AddRefed<BrowsingContext> BrowsingContext::CreateDetached(
inherit ? inherit->GetUseGlobalHistory() : false; inherit ? inherit->GetUseGlobalHistory() : false;
context->mFields.SetWithoutSyncing<IDX_UseGlobalHistory>(useGlobalHistory); context->mFields.SetWithoutSyncing<IDX_UseGlobalHistory>(useGlobalHistory);
context->mFields.SetWithoutSyncing<IDX_UseErrorPages>(true);
nsCOMPtr<nsIRequestContextService> rcsvc = nsCOMPtr<nsIRequestContextService> rcsvc =
net::RequestContextService::GetOrCreate(); net::RequestContextService::GetOrCreate();
if (rcsvc) { if (rcsvc) {
@ -2078,12 +2076,6 @@ bool BrowsingContext::CanSet(FieldIndex<IDX_FullscreenAllowedByOwner>,
return CheckOnlyEmbedderCanSet(aSource); return CheckOnlyEmbedderCanSet(aSource);
} }
bool BrowsingContext::CanSet(FieldIndex<IDX_UseErrorPages>,
const bool& aUseErrorPages,
ContentParent* aSource) {
return CheckOnlyEmbedderCanSet(aSource);
}
// We map `watchedByDevTools` WebIDL attribute to `watchedByDevToolsInternal` // We map `watchedByDevTools` WebIDL attribute to `watchedByDevToolsInternal`
// BC field. And we map it to the top level BrowsingContext. // BC field. And we map it to the top level BrowsingContext.
bool BrowsingContext::WatchedByDevTools() { bool BrowsingContext::WatchedByDevTools() {

View File

@ -147,8 +147,7 @@ class WindowProxyHolder;
/* Signals that session history is enabled for this browsing context tree. \ /* Signals that session history is enabled for this browsing context tree. \
* This is only ever set to true on the top BC, so consumers need to get \ * This is only ever set to true on the top BC, so consumers need to get \
* the value from the top BC! */ \ * the value from the top BC! */ \
FIELD(HasSessionHistory, bool) \ FIELD(HasSessionHistory, bool)
FIELD(UseErrorPages, bool)
// BrowsingContext, in this context, is the cross process replicated // BrowsingContext, in this context, is the cross process replicated
// environment in which information about documents is stored. In // environment in which information about documents is stored. In
@ -787,9 +786,6 @@ class BrowsingContext : public nsILoadContext, public nsWrapperCache {
bool CanSet(FieldIndex<IDX_BrowserId>, const uint32_t& aValue, bool CanSet(FieldIndex<IDX_BrowserId>, const uint32_t& aValue,
ContentParent* aSource); ContentParent* aSource);
bool CanSet(FieldIndex<IDX_UseErrorPages>, const bool& aUseErrorPages,
ContentParent* aSource);
template <size_t I, typename T> template <size_t I, typename T>
bool CanSet(FieldIndex<I>, const T&, ContentParent*) { bool CanSet(FieldIndex<I>, const T&, ContentParent*) {
return true; return true;

View File

@ -378,6 +378,7 @@ nsDocShell::nsDocShell(BrowsingContext* aBrowsingContext,
mAllowMedia(true), mAllowMedia(true),
mAllowDNSPrefetch(true), mAllowDNSPrefetch(true),
mAllowWindowControl(true), mAllowWindowControl(true),
mUseErrorPages(true),
mCSSErrorReportingEnabled(false), mCSSErrorReportingEnabled(false),
mAllowAuth(mItemType == typeContent), mAllowAuth(mItemType == typeContent),
mAllowKeywordFixup(false), mAllowKeywordFixup(false),
@ -712,6 +713,12 @@ nsDocShell::LoadURI(nsDocShellLoadState* aLoadState, bool aSetNavigating) {
} }
AutoPopupStatePusher statePusher(popupState); AutoPopupStatePusher statePusher(popupState);
if (aLoadState->GetOriginalURIString().isSome()) {
// Save URI string in case it's needed later when
// sending to search engine service in EndPageLoad()
mOriginalUriString = *aLoadState->GetOriginalURIString();
}
if (aLoadState->GetCancelContentJSEpoch().isSome()) { if (aLoadState->GetCancelContentJSEpoch().isSome()) {
SetCancelContentJSEpoch(*aLoadState->GetCancelContentJSEpoch()); SetCancelContentJSEpoch(*aLoadState->GetCancelContentJSEpoch());
} }
@ -800,16 +807,7 @@ nsDocShell::LoadURI(nsDocShellLoadState* aLoadState, bool aSetNavigating) {
MOZ_ASSERT(aLoadState->SHEntry() == nullptr, MOZ_ASSERT(aLoadState->SHEntry() == nullptr,
"SHEntry should be null when calling InternalLoad from LoadURI"); "SHEntry should be null when calling InternalLoad from LoadURI");
rv = InternalLoad(aLoadState); return InternalLoad(aLoadState); // no nsIRequest
NS_ENSURE_SUCCESS(rv, rv);
if (aLoadState->GetOriginalURIString().isSome()) {
// Save URI string in case it's needed later when
// sending to search engine service in EndPageLoad()
mOriginalUriString = *aLoadState->GetOriginalURIString();
}
return NS_OK;
} }
void nsDocShell::MaybeHandleSubframeHistory(nsDocShellLoadState* aLoadState) { void nsDocShell::MaybeHandleSubframeHistory(nsDocShellLoadState* aLoadState) {
@ -1870,13 +1868,13 @@ already_AddRefed<nsILoadURIDelegate> nsDocShell::GetLoadURIDelegate() {
NS_IMETHODIMP NS_IMETHODIMP
nsDocShell::GetUseErrorPages(bool* aUseErrorPages) { nsDocShell::GetUseErrorPages(bool* aUseErrorPages) {
*aUseErrorPages = mBrowsingContext->GetUseErrorPages(); *aUseErrorPages = mUseErrorPages;
return NS_OK; return NS_OK;
} }
NS_IMETHODIMP NS_IMETHODIMP
nsDocShell::SetUseErrorPages(bool aUseErrorPages) { nsDocShell::SetUseErrorPages(bool aUseErrorPages) {
mBrowsingContext->SetUseErrorPages(aUseErrorPages); mUseErrorPages = aUseErrorPages;
return NS_OK; return NS_OK;
} }
@ -3610,7 +3608,7 @@ nsDocShell::DisplayLoadError(nsresult aError, nsIURI* aURI,
error = "nssFailure2"; error = "nssFailure2";
} }
if (mBrowsingContext->GetUseErrorPages()) { if (mUseErrorPages) {
// Display an error page // Display an error page
nsresult loadedPage = nsresult loadedPage =
LoadErrorPage(aURI, aURL, errorPage.get(), error, messageStr.get(), LoadErrorPage(aURI, aURL, errorPage.get(), error, messageStr.get(),
@ -5614,279 +5612,6 @@ already_AddRefed<nsIURIFixupInfo> nsDocShell::KeywordToURI(
return info.forget(); return info.forget();
} }
/* static */
already_AddRefed<nsIURI> nsDocShell::AttemptURIFixup(
nsIChannel* aChannel, nsresult aStatus,
const mozilla::Maybe<nsCString>& aOriginalURIString, uint32_t aLoadType,
bool aIsTopFrame, bool aAllowKeywordFixup, bool aUsePrivateBrowsing,
bool aNotifyKeywordSearchLoading, nsIInputStream** aNewPostData) {
if (aStatus != NS_ERROR_UNKNOWN_HOST && aStatus != NS_ERROR_NET_RESET &&
aStatus != NS_ERROR_CONNECTION_REFUSED) {
return nullptr;
}
if (!(aLoadType == LOAD_NORMAL && aIsTopFrame) && !aAllowKeywordFixup) {
return nullptr;
}
nsCOMPtr<nsIURI> url;
nsresult rv = aChannel->GetURI(getter_AddRefs(url));
if (NS_FAILED(rv)) {
return nullptr;
}
//
// Try and make an alternative URI from the old one
//
nsCOMPtr<nsIURI> newURI;
nsCOMPtr<nsIInputStream> newPostData;
nsAutoCString oldSpec;
url->GetSpec(oldSpec);
//
// First try keyword fixup
//
nsAutoString keywordProviderName, keywordAsSent;
if (aStatus == NS_ERROR_UNKNOWN_HOST && aAllowKeywordFixup) {
// we should only perform a keyword search under the following
// conditions:
// (0) Pref keyword.enabled is true
// (1) the url scheme is http (or https)
// (2) the url does not have a protocol scheme
// If we don't enforce such a policy, then we end up doing
// keyword searchs on urls we don't intend like imap, file,
// mailbox, etc. This could lead to a security problem where we
// send data to the keyword server that we shouldn't be.
// Someone needs to clean up keywords in general so we can
// determine on a per url basis if we want keywords
// enabled...this is just a bandaid...
nsAutoCString scheme;
Unused << url->GetScheme(scheme);
if (Preferences::GetBool("keyword.enabled", false) &&
StringBeginsWith(scheme, NS_LITERAL_CSTRING("http"))) {
bool attemptFixup = false;
nsAutoCString host;
Unused << url->GetHost(host);
if (host.FindChar('.') == kNotFound) {
attemptFixup = true;
} else {
// For domains with dots, we check the public suffix validity.
nsCOMPtr<nsIEffectiveTLDService> tldService =
do_GetService(NS_EFFECTIVETLDSERVICE_CONTRACTID);
if (tldService) {
nsAutoCString suffix;
attemptFixup =
NS_SUCCEEDED(tldService->GetKnownPublicSuffix(url, suffix)) &&
suffix.IsEmpty();
}
}
if (attemptFixup) {
nsCOMPtr<nsIURIFixupInfo> info;
// only send non-qualified hosts to the keyword server
if (aOriginalURIString && !aOriginalURIString->IsEmpty()) {
info = KeywordToURI(*aOriginalURIString, aUsePrivateBrowsing,
getter_AddRefs(newPostData));
} else {
//
// If this string was passed through nsStandardURL by
// chance, then it may have been converted from UTF-8 to
// ACE, which would result in a completely bogus keyword
// query. Here we try to recover the original Unicode
// value, but this is not 100% correct since the value may
// have been normalized per the IDN normalization rules.
//
// Since we don't have access to the exact original string
// that was entered by the user, this will just have to do.
bool isACE;
nsAutoCString utf8Host;
nsCOMPtr<nsIIDNService> idnSrv =
do_GetService(NS_IDNSERVICE_CONTRACTID);
if (idnSrv && NS_SUCCEEDED(idnSrv->IsACE(host, &isACE)) && isACE &&
NS_SUCCEEDED(idnSrv->ConvertACEtoUTF8(host, utf8Host))) {
info = KeywordToURI(utf8Host, aUsePrivateBrowsing,
getter_AddRefs(newPostData));
} else {
info = KeywordToURI(host, aUsePrivateBrowsing,
getter_AddRefs(newPostData));
}
}
if (info) {
info->GetPreferredURI(getter_AddRefs(newURI));
if (newURI) {
info->GetKeywordAsSent(keywordAsSent);
info->GetKeywordProviderName(keywordProviderName);
}
}
}
}
}
//
// Now try change the address, e.g. turn http://foo into
// http://www.foo.com, and if that doesn't work try https with
// https://foo and https://www.foo.com.
//
if (aStatus == NS_ERROR_UNKNOWN_HOST || aStatus == NS_ERROR_NET_RESET) {
bool doCreateAlternate = true;
// Skip fixup for anything except a normal document load
// operation on the topframe.
if (aLoadType != LOAD_NORMAL || !aIsTopFrame) {
doCreateAlternate = false;
} else {
// Test if keyword lookup produced a new URI or not
if (newURI) {
bool sameURI = false;
url->Equals(newURI, &sameURI);
if (!sameURI) {
// Keyword lookup made a new URI so no need to try
// an alternate one.
doCreateAlternate = false;
}
}
if (doCreateAlternate) {
nsCOMPtr<nsILoadInfo> info = aChannel->LoadInfo();
// Skip doing this if our channel was redirected, because we
// shouldn't be guessing things about the post-redirect URI.
if (!info->RedirectChain().IsEmpty()) {
doCreateAlternate = false;
}
}
}
if (doCreateAlternate) {
newURI = nullptr;
newPostData = nullptr;
keywordProviderName.Truncate();
keywordAsSent.Truncate();
nsCOMPtr<nsIURIFixup> uriFixup = components::URIFixup::Service();
if (uriFixup) {
uriFixup->CreateFixupURI(
oldSpec, nsIURIFixup::FIXUP_FLAGS_MAKE_ALTERNATE_URI,
getter_AddRefs(newPostData), getter_AddRefs(newURI));
}
}
} else if (aStatus == NS_ERROR_CONNECTION_REFUSED &&
Preferences::GetBool("browser.fixup.fallback-to-https", false)) {
// Try HTTPS, since http didn't work
if (SchemeIsHTTP(url)) {
int32_t port = 0;
url->GetPort(&port);
// Fall back to HTTPS only if port is default
if (port == -1) {
newURI = nullptr;
newPostData = nullptr;
Unused << NS_MutateURI(url)
.SetScheme(NS_LITERAL_CSTRING("https"))
.Finalize(getter_AddRefs(newURI));
}
}
}
// Did we make a new URI that is different to the old one? If so
// load it.
//
if (newURI) {
// Make sure the new URI is different from the old one,
// otherwise there's little point trying to load it again.
bool sameURI = false;
url->Equals(newURI, &sameURI);
if (!sameURI) {
if (aNewPostData) {
newPostData.forget(aNewPostData);
}
if (aNotifyKeywordSearchLoading) {
// This notification is meant for Firefox Health Report so it
// can increment counts from the search engine
MaybeNotifyKeywordSearchLoading(keywordProviderName, keywordAsSent);
}
return newURI.forget();
}
}
return nullptr;
}
nsresult nsDocShell::FilterStatusForErrorPage(
nsresult aStatus, nsIChannel* aChannel, uint32_t aLoadType,
bool aIsTopFrame, bool aUseErrorPages, bool aIsInitialDocument,
bool* aSkippedUnknownProtocolNavigation) {
// Errors to be shown only on top-level frames
if ((aStatus == NS_ERROR_UNKNOWN_HOST ||
aStatus == NS_ERROR_CONNECTION_REFUSED ||
aStatus == NS_ERROR_UNKNOWN_PROXY_HOST ||
aStatus == NS_ERROR_PROXY_CONNECTION_REFUSED ||
aStatus == NS_ERROR_PROXY_FORBIDDEN ||
aStatus == NS_ERROR_PROXY_NOT_IMPLEMENTED ||
aStatus == NS_ERROR_PROXY_AUTHENTICATION_FAILED ||
aStatus == NS_ERROR_PROXY_TOO_MANY_REQUESTS ||
aStatus == NS_ERROR_MALFORMED_URI ||
aStatus == NS_ERROR_BLOCKED_BY_POLICY) &&
(aIsTopFrame || aUseErrorPages)) {
return aStatus;
}
if (aStatus == NS_ERROR_NET_TIMEOUT ||
aStatus == NS_ERROR_PROXY_GATEWAY_TIMEOUT ||
aStatus == NS_ERROR_REDIRECT_LOOP ||
aStatus == NS_ERROR_UNKNOWN_SOCKET_TYPE ||
aStatus == NS_ERROR_NET_INTERRUPT || aStatus == NS_ERROR_NET_RESET ||
aStatus == NS_ERROR_PROXY_BAD_GATEWAY || aStatus == NS_ERROR_OFFLINE ||
aStatus == NS_ERROR_MALWARE_URI || aStatus == NS_ERROR_PHISHING_URI ||
aStatus == NS_ERROR_UNWANTED_URI || aStatus == NS_ERROR_HARMFUL_URI ||
aStatus == NS_ERROR_UNSAFE_CONTENT_TYPE ||
aStatus == NS_ERROR_REMOTE_XUL ||
aStatus == NS_ERROR_INTERCEPTION_FAILED ||
aStatus == NS_ERROR_NET_INADEQUATE_SECURITY ||
aStatus == NS_ERROR_NET_HTTP2_SENT_GOAWAY ||
aStatus == NS_ERROR_NET_HTTP3_PROTOCOL_ERROR ||
aStatus == NS_ERROR_DOM_BAD_URI || aStatus == NS_ERROR_FILE_NOT_FOUND ||
aStatus == NS_ERROR_FILE_ACCESS_DENIED ||
aStatus == NS_ERROR_CORRUPTED_CONTENT ||
aStatus == NS_ERROR_INVALID_CONTENT_ENCODING ||
NS_ERROR_GET_MODULE(aStatus) == NS_ERROR_MODULE_SECURITY) {
// Errors to be shown for any frame
return aStatus;
}
if (aStatus == NS_ERROR_UNKNOWN_PROTOCOL) {
// For unknown protocols we only display an error if the load is triggered
// by the browser itself, or we're replacing the initial document (and
// nothing else). Showing the error for page-triggered navigations causes
// annoying behavior for users, see bug 1528305.
//
// We could, maybe, try to detect if this is in response to some user
// interaction (like clicking a link, or something else) and maybe show
// the error page in that case. But this allows for ctrl+clicking and such
// to see the error page.
nsCOMPtr<nsILoadInfo> info = aChannel->LoadInfo();
if (!info->TriggeringPrincipal()->IsSystemPrincipal() &&
StaticPrefs::dom_no_unknown_protocol_error_enabled() &&
!aIsInitialDocument) {
if (aSkippedUnknownProtocolNavigation) {
*aSkippedUnknownProtocolNavigation = true;
}
return NS_OK;
}
return aStatus;
}
if (aStatus == NS_ERROR_DOCUMENT_NOT_CACHED) {
// Non-caching channels will simply return NS_ERROR_OFFLINE.
// Caching channels would have to look at their flags to work
// out which error to return. Or we can fix up the error here.
if (!(aLoadType & LOAD_CMD_HISTORY)) {
return NS_ERROR_OFFLINE;
}
return aStatus;
}
return NS_OK;
}
nsresult nsDocShell::EndPageLoad(nsIWebProgress* aProgress, nsresult nsDocShell::EndPageLoad(nsIWebProgress* aProgress,
nsIChannel* aChannel, nsresult aStatus) { nsIChannel* aChannel, nsresult aStatus) {
MOZ_LOG(gDocShellLeakLog, LogLevel::Debug, MOZ_LOG(gDocShellLeakLog, LogLevel::Debug,
@ -6019,17 +5744,246 @@ nsresult nsDocShell::EndPageLoad(nsIWebProgress* aProgress,
// (if appropriate). // (if appropriate).
// 5. Throw an error dialog box... // 5. Throw an error dialog box...
// //
if (NS_FAILED(aStatus)) { if (url && NS_FAILED(aStatus)) {
if (aStatus == NS_ERROR_FILE_NOT_FOUND ||
aStatus == NS_ERROR_FILE_ACCESS_DENIED ||
aStatus == NS_ERROR_CORRUPTED_CONTENT ||
aStatus == NS_ERROR_INVALID_CONTENT_ENCODING) {
UnblockEmbedderLoadEventForFailure();
DisplayLoadError(aStatus, url, nullptr, aChannel);
return NS_OK;
}
// Handle iframe document not loading error because source was
// a tracking URL. We make a note of this iframe node by including
// it in a dedicated array of blocked tracking nodes under its parent
// document. (document of parent window of blocked document)
if (!isTopFrame &&
UrlClassifierFeatureFactory::IsClassifierBlockingErrorCode(aStatus)) {
UnblockEmbedderLoadEventForFailure();
// We don't really need to add the blocked node if we are not testing.
// This could save a IPC here.
if (!StaticPrefs::
privacy_trackingprotection_testing_report_blocked_node()) {
return NS_OK;
}
RefPtr<BrowsingContext> bc = GetBrowsingContext();
RefPtr<BrowsingContext> parentBC = bc->GetParent();
if (!parentBC) {
return NS_OK;
}
if (parentBC->IsInProcess()) {
// We can directly add the blocked node in the parent document if the
// parent is in the same process.
nsCOMPtr<nsPIDOMWindowOuter> parentOuter = parentBC->GetDOMWindow();
if (!parentOuter) {
return NS_OK;
}
nsCOMPtr<nsPIDOMWindowInner> parentInner =
parentOuter->GetCurrentInnerWindow();
if (!parentInner) {
return NS_OK;
}
RefPtr<Document> parentDoc;
parentDoc = parentInner->GetExtantDoc();
if (!parentDoc) {
return NS_OK;
}
parentDoc->AddBlockedNodeByClassifier(bc->GetEmbedderElement());
} else {
// If the parent is out-of-process, we send to the process of the
// document which embeds the frame to add the blocked node there.
RefPtr<BrowserChild> browserChild = BrowserChild::GetFrom(this);
if (browserChild) {
Unused << browserChild->SendReportBlockedEmbedderNodeByClassifier();
}
}
return NS_OK;
}
if ((aStatus == NS_ERROR_UNKNOWN_HOST || aStatus == NS_ERROR_NET_RESET ||
aStatus == NS_ERROR_CONNECTION_REFUSED) &&
((mLoadType == LOAD_NORMAL && isTopFrame) || mAllowKeywordFixup)) {
//
// Try and make an alternative URI from the old one
//
nsCOMPtr<nsIURI> newURI;
nsCOMPtr<nsIInputStream> newPostData; nsCOMPtr<nsIInputStream> newPostData;
nsCOMPtr<nsIURI> newURI =
AttemptURIFixup(aChannel, aStatus, Some(mOriginalUriString), mLoadType, nsAutoCString oldSpec;
isTopFrame, mAllowKeywordFixup, UsePrivateBrowsing(), url->GetSpec(oldSpec);
true, getter_AddRefs(newPostData));
//
// First try keyword fixup
//
nsAutoString keywordProviderName, keywordAsSent;
if (aStatus == NS_ERROR_UNKNOWN_HOST && mAllowKeywordFixup) {
// we should only perform a keyword search under the following
// conditions:
// (0) Pref keyword.enabled is true
// (1) the url scheme is http (or https)
// (2) the url does not have a protocol scheme
// If we don't enforce such a policy, then we end up doing
// keyword searchs on urls we don't intend like imap, file,
// mailbox, etc. This could lead to a security problem where we
// send data to the keyword server that we shouldn't be.
// Someone needs to clean up keywords in general so we can
// determine on a per url basis if we want keywords
// enabled...this is just a bandaid...
nsAutoCString scheme;
Unused << url->GetScheme(scheme);
if (Preferences::GetBool("keyword.enabled", false) &&
StringBeginsWith(scheme, NS_LITERAL_CSTRING("http"))) {
bool attemptFixup = false;
nsAutoCString host;
Unused << url->GetHost(host);
if (host.FindChar('.') == kNotFound) {
attemptFixup = true;
} else {
// For domains with dots, we check the public suffix validity.
nsCOMPtr<nsIEffectiveTLDService> tldService =
do_GetService(NS_EFFECTIVETLDSERVICE_CONTRACTID);
if (tldService) {
nsAutoCString suffix;
attemptFixup =
NS_SUCCEEDED(tldService->GetKnownPublicSuffix(url, suffix)) &&
suffix.IsEmpty();
}
}
if (attemptFixup) {
nsCOMPtr<nsIURIFixupInfo> info;
// only send non-qualified hosts to the keyword server
if (!mOriginalUriString.IsEmpty()) {
info = KeywordToURI(mOriginalUriString, UsePrivateBrowsing(),
getter_AddRefs(newPostData));
} else {
//
// If this string was passed through nsStandardURL by
// chance, then it may have been converted from UTF-8 to
// ACE, which would result in a completely bogus keyword
// query. Here we try to recover the original Unicode
// value, but this is not 100% correct since the value may
// have been normalized per the IDN normalization rules.
//
// Since we don't have access to the exact original string
// that was entered by the user, this will just have to do.
bool isACE;
nsAutoCString utf8Host;
nsCOMPtr<nsIIDNService> idnSrv =
do_GetService(NS_IDNSERVICE_CONTRACTID);
if (idnSrv && NS_SUCCEEDED(idnSrv->IsACE(host, &isACE)) &&
isACE &&
NS_SUCCEEDED(idnSrv->ConvertACEtoUTF8(host, utf8Host))) {
info = KeywordToURI(utf8Host, UsePrivateBrowsing(),
getter_AddRefs(newPostData));
} else {
info = KeywordToURI(host, UsePrivateBrowsing(),
getter_AddRefs(newPostData));
}
}
if (info) {
info->GetPreferredURI(getter_AddRefs(newURI));
if (newURI) { if (newURI) {
info->GetKeywordAsSent(keywordAsSent);
info->GetKeywordProviderName(keywordProviderName);
}
}
}
}
}
//
// Now try change the address, e.g. turn http://foo into
// http://www.foo.com, and if that doesn't work try https with
// https://foo and https://www.foo.com.
//
if (aStatus == NS_ERROR_UNKNOWN_HOST || aStatus == NS_ERROR_NET_RESET) {
bool doCreateAlternate = true;
// Skip fixup for anything except a normal document load
// operation on the topframe.
if (mLoadType != LOAD_NORMAL || !isTopFrame) {
doCreateAlternate = false;
} else {
// Test if keyword lookup produced a new URI or not
if (newURI) {
bool sameURI = false;
url->Equals(newURI, &sameURI);
if (!sameURI) {
// Keyword lookup made a new URI so no need to try
// an alternate one.
doCreateAlternate = false;
}
}
if (doCreateAlternate) {
nsCOMPtr<nsILoadInfo> info = aChannel->LoadInfo();
// Skip doing this if our channel was redirected, because we
// shouldn't be guessing things about the post-redirect URI.
if (!info->RedirectChain().IsEmpty()) {
doCreateAlternate = false;
}
}
}
if (doCreateAlternate) {
newURI = nullptr;
newPostData = nullptr;
keywordProviderName.Truncate();
keywordAsSent.Truncate();
nsCOMPtr<nsIURIFixup> uriFixup = components::URIFixup::Service();
if (uriFixup) {
uriFixup->CreateFixupURI(
oldSpec, nsIURIFixup::FIXUP_FLAGS_MAKE_ALTERNATE_URI,
getter_AddRefs(newPostData), getter_AddRefs(newURI));
}
}
} else if (aStatus == NS_ERROR_CONNECTION_REFUSED &&
Preferences::GetBool("browser.fixup.fallback-to-https",
false)) {
// Try HTTPS, since http didn't work
if (SchemeIsHTTP(url)) {
int32_t port = 0;
url->GetPort(&port);
// Fall back to HTTPS only if port is default
if (port == -1) {
newURI = nullptr;
newPostData = nullptr;
Unused << NS_MutateURI(url)
.SetScheme(NS_LITERAL_CSTRING("https"))
.Finalize(getter_AddRefs(newURI));
}
}
}
// Did we make a new URI that is different to the old one? If so
// load it.
//
if (newURI) {
// Make sure the new URI is different from the old one,
// otherwise there's little point trying to load it again.
bool sameURI = false;
url->Equals(newURI, &sameURI);
if (!sameURI) {
nsAutoCString newSpec; nsAutoCString newSpec;
newURI->GetSpec(newSpec); newURI->GetSpec(newSpec);
NS_ConvertUTF8toUTF16 newSpecW(newSpec); NS_ConvertUTF8toUTF16 newSpecW(newSpec);
// This notification is meant for Firefox Health Report so it
// can increment counts from the search engine
MaybeNotifyKeywordSearchLoading(keywordProviderName, keywordAsSent);
nsCOMPtr<nsILoadInfo> loadInfo = aChannel->LoadInfo(); nsCOMPtr<nsILoadInfo> loadInfo = aChannel->LoadInfo();
MOZ_ASSERT(loadInfo, "loadInfo is required on all channels"); MOZ_ASSERT(loadInfo, "loadInfo is required on all channels");
nsCOMPtr<nsIPrincipal> triggeringPrincipal = nsCOMPtr<nsIPrincipal> triggeringPrincipal =
@ -6070,6 +6024,8 @@ nsresult nsDocShell::EndPageLoad(nsIWebProgress* aProgress,
loadURIOptions.mPostData = newPostData; loadURIOptions.mPostData = newPostData;
return LoadURI(newSpecW, loadURIOptions); return LoadURI(newSpecW, loadURIOptions);
} }
}
}
// Well, fixup didn't work :-( // Well, fixup didn't work :-(
// It is time to throw an error dialog box, and be done with it... // It is time to throw an error dialog box, and be done with it...
@ -6084,27 +6040,77 @@ nsresult nsDocShell::EndPageLoad(nsIWebProgress* aProgress,
aStatus == NS_ERROR_CONTENT_BLOCKED); aStatus == NS_ERROR_CONTENT_BLOCKED);
UnblockEmbedderLoadEventForFailure(fireFrameErrorEvent); UnblockEmbedderLoadEventForFailure(fireFrameErrorEvent);
bool isInitialDocument = // Errors to be shown only on top-level frames
!GetExtantDocument() || GetExtantDocument()->IsInitialDocument(); if ((aStatus == NS_ERROR_UNKNOWN_HOST ||
bool skippedUnknownProtocolNavigation = false; aStatus == NS_ERROR_CONNECTION_REFUSED ||
aStatus = FilterStatusForErrorPage(aStatus, aChannel, mLoadType, isTopFrame, aStatus == NS_ERROR_UNKNOWN_PROXY_HOST ||
mBrowsingContext->GetUseErrorPages(), aStatus == NS_ERROR_PROXY_CONNECTION_REFUSED ||
isInitialDocument, aStatus == NS_ERROR_PROXY_FORBIDDEN ||
&skippedUnknownProtocolNavigation); aStatus == NS_ERROR_PROXY_NOT_IMPLEMENTED ||
if (NS_FAILED(aStatus)) { aStatus == NS_ERROR_PROXY_AUTHENTICATION_FAILED ||
aStatus == NS_ERROR_PROXY_TOO_MANY_REQUESTS ||
aStatus == NS_ERROR_MALFORMED_URI ||
aStatus == NS_ERROR_BLOCKED_BY_POLICY) &&
(isTopFrame || mUseErrorPages)) {
DisplayLoadError(aStatus, url, nullptr, aChannel); DisplayLoadError(aStatus, url, nullptr, aChannel);
} else if (skippedUnknownProtocolNavigation) { } else if (aStatus == NS_ERROR_NET_TIMEOUT ||
aStatus == NS_ERROR_PROXY_GATEWAY_TIMEOUT ||
aStatus == NS_ERROR_REDIRECT_LOOP ||
aStatus == NS_ERROR_UNKNOWN_SOCKET_TYPE ||
aStatus == NS_ERROR_NET_INTERRUPT ||
aStatus == NS_ERROR_NET_RESET ||
aStatus == NS_ERROR_PROXY_BAD_GATEWAY ||
aStatus == NS_ERROR_OFFLINE || aStatus == NS_ERROR_MALWARE_URI ||
aStatus == NS_ERROR_PHISHING_URI ||
aStatus == NS_ERROR_UNWANTED_URI ||
aStatus == NS_ERROR_HARMFUL_URI ||
aStatus == NS_ERROR_UNSAFE_CONTENT_TYPE ||
aStatus == NS_ERROR_REMOTE_XUL ||
aStatus == NS_ERROR_INTERCEPTION_FAILED ||
aStatus == NS_ERROR_NET_INADEQUATE_SECURITY ||
aStatus == NS_ERROR_NET_HTTP2_SENT_GOAWAY ||
aStatus == NS_ERROR_NET_HTTP3_PROTOCOL_ERROR ||
aStatus == NS_ERROR_DOM_BAD_URI ||
NS_ERROR_GET_MODULE(aStatus) == NS_ERROR_MODULE_SECURITY) {
// Errors to be shown for any frame
DisplayLoadError(aStatus, url, nullptr, aChannel);
} else if (aStatus == NS_ERROR_UNKNOWN_PROTOCOL) {
// For unknown protocols we only display an error if the load is triggered
// by the browser itself, or we're replacing the initial document (and
// nothing else). Showing the error for page-triggered navigations causes
// annoying behavior for users, see bug 1528305.
//
// We could, maybe, try to detect if this is in response to some user
// interaction (like clicking a link, or something else) and maybe show
// the error page in that case. But this allows for ctrl+clicking and such
// to see the error page.
nsCOMPtr<nsILoadInfo> info = aChannel->LoadInfo();
Document* doc = GetDocument();
if (!info->TriggeringPrincipal()->IsSystemPrincipal() &&
StaticPrefs::dom_no_unknown_protocol_error_enabled() && doc &&
!doc->IsInitialDocument()) {
nsTArray<nsString> params; nsTArray<nsString> params;
if (NS_FAILED( if (NS_FAILED(NS_GetSanitizedURIStringFromURI(
NS_GetSanitizedURIStringFromURI(url, *params.AppendElement()))) { url, *params.AppendElement()))) {
params.LastElement().AssignLiteral(u"(unknown uri)"); params.LastElement().AssignLiteral(u"(unknown uri)");
} }
nsContentUtils::ReportToConsole( nsContentUtils::ReportToConsole(
nsIScriptError::warningFlag, NS_LITERAL_CSTRING("DOM"), nsIScriptError::warningFlag, NS_LITERAL_CSTRING("DOM"), doc,
GetExtantDocument(), nsContentUtils::eDOM_PROPERTIES, nsContentUtils::eDOM_PROPERTIES,
"UnknownProtocolNavigationPrevented", params); "UnknownProtocolNavigationPrevented", params);
}
} else { } else {
DisplayLoadError(aStatus, url, nullptr, aChannel);
}
} else if (aStatus == NS_ERROR_DOCUMENT_NOT_CACHED) {
// Non-caching channels will simply return NS_ERROR_OFFLINE.
// Caching channels would have to look at their flags to work
// out which error to return. Or we can fix up the error here.
if (!(mLoadType & LOAD_CMD_HISTORY)) {
aStatus = NS_ERROR_OFFLINE;
}
DisplayLoadError(aStatus, url, nullptr, aChannel);
}
} else if (url && NS_SUCCEEDED(aStatus)) {
// If we have a host // If we have a host
nsCOMPtr<nsILoadInfo> loadInfo = aChannel->LoadInfo(); nsCOMPtr<nsILoadInfo> loadInfo = aChannel->LoadInfo();
PredictorLearnRedirect(url, aChannel, loadInfo->GetOriginAttributes()); PredictorLearnRedirect(url, aChannel, loadInfo->GetOriginAttributes());
@ -12062,12 +12068,6 @@ nsDocShell::ResumeRedirectedLoad(uint64_t aIdentifier, int32_t aHistoryIndex) {
self->InternalLoad(aLoadState); self->InternalLoad(aLoadState);
if (aLoadState->GetOriginalURIString().isSome()) {
// Save URI string in case it's needed later when
// sending to search engine service in EndPageLoad()
self->mOriginalUriString = *aLoadState->GetOriginalURIString();
}
for (auto& endpoint : aStreamFilterEndpoints) { for (auto& endpoint : aStreamFilterEndpoints) {
extensions::StreamFilterParent::Attach( extensions::StreamFilterParent::Attach(
aLoadState->GetPendingRedirectedChannel(), std::move(endpoint)); aLoadState->GetPendingRedirectedChannel(), std::move(endpoint));

View File

@ -436,25 +436,6 @@ class nsDocShell final : public nsDocLoader,
nsLoadFlags aLoadFlags, uint32_t aCacheKey, nsresult& rv, nsLoadFlags aLoadFlags, uint32_t aCacheKey, nsresult& rv,
nsIChannel** aChannel); nsIChannel** aChannel);
static already_AddRefed<nsIURI> AttemptURIFixup(
nsIChannel* aChannel, nsresult aStatus,
const mozilla::Maybe<nsCString>& aOriginalURIString, uint32_t aLoadType,
bool aIsTopFrame, bool aAllowKeywordFixup, bool aUsePrivateBrowsing,
bool aNotifyKeywordSearchLoading = false,
nsIInputStream** aNewPostData = nullptr);
// Takes aStatus and filters out results that should not display
// an error page.
// If this returns a failed result, then we should display an error
// page with that result.
// aSkippedUnknownProtocolNavigation will be set to true if we chose
// to skip displaying an error page for an NS_ERROR_UNKNOWN_PROTOCOL
// navigation.
static nsresult FilterStatusForErrorPage(
nsresult aStatus, nsIChannel* aChannel, uint32_t aLoadType,
bool aIsTopFrame, bool aUseErrorPages, bool aIsInitialDocument,
bool* aSkippedUnknownProtocolNavigation = nullptr);
// Notify consumers of a search being loaded through the observer service: // Notify consumers of a search being loaded through the observer service:
static void MaybeNotifyKeywordSearchLoading(const nsString& aProvider, static void MaybeNotifyKeywordSearchLoading(const nsString& aProvider,
const nsString& aKeyword); const nsString& aKeyword);
@ -759,8 +740,8 @@ class nsDocShell final : public nsDocLoader,
uint32_t aResponseStatus, mozilla::dom::BrowsingContext* aBrowsingContext, uint32_t aResponseStatus, mozilla::dom::BrowsingContext* aBrowsingContext,
nsIWidget* aWidget, uint32_t aLoadType); nsIWidget* aWidget, uint32_t aLoadType);
static already_AddRefed<nsIURIFixupInfo> KeywordToURI( already_AddRefed<nsIURIFixupInfo> KeywordToURI(const nsACString& aKeyword,
const nsACString& aKeyword, bool aIsPrivateContext, bool aIsPrivateContext,
nsIInputStream** aPostData); nsIInputStream** aPostData);
// Sets the current document's current state object to the given SHEntry's // Sets the current document's current state object to the given SHEntry's
@ -1183,6 +1164,7 @@ class nsDocShell final : public nsDocLoader,
bool mAllowMedia : 1; bool mAllowMedia : 1;
bool mAllowDNSPrefetch : 1; bool mAllowDNSPrefetch : 1;
bool mAllowWindowControl : 1; bool mAllowWindowControl : 1;
bool mUseErrorPages : 1;
bool mCSSErrorReportingEnabled : 1; bool mCSSErrorReportingEnabled : 1;
bool mAllowAuth : 1; bool mAllowAuth : 1;
bool mAllowKeywordFixup : 1; bool mAllowKeywordFixup : 1;

View File

@ -221,6 +221,21 @@ mozilla::ipc::IPCResult BrowserBridgeChild::RecvSubFrameCrashed() {
return IPC_OK(); return IPC_OK();
} }
mozilla::ipc::IPCResult BrowserBridgeChild::RecvAddBlockedNodeByClassifier() {
RefPtr<Element> owner = mFrameLoader->GetOwnerContent();
if (!owner) {
return IPC_OK();
}
RefPtr<Document> doc = mFrameLoader->GetOwnerDoc();
if (!doc) {
return IPC_OK();
}
doc->AddBlockedNodeByClassifier(owner);
return IPC_OK();
}
void BrowserBridgeChild::ActorDestroy(ActorDestroyReason aWhy) { void BrowserBridgeChild::ActorDestroy(ActorDestroyReason aWhy) {
if (!mBrowsingContext) { if (!mBrowsingContext) {
// This BBC was never valid, skip teardown. // This BBC was never valid, skip teardown.

View File

@ -94,6 +94,8 @@ class BrowserBridgeChild : public PBrowserBridgeChild {
mozilla::ipc::IPCResult RecvSubFrameCrashed(); mozilla::ipc::IPCResult RecvSubFrameCrashed();
mozilla::ipc::IPCResult RecvAddBlockedNodeByClassifier();
void ActorDestroy(ActorDestroyReason aWhy) override; void ActorDestroy(ActorDestroyReason aWhy) override;
private: private:

View File

@ -2763,6 +2763,18 @@ mozilla::ipc::IPCResult BrowserParent::RecvNotifyContentBlockingEvent(
return IPC_OK(); return IPC_OK();
} }
mozilla::ipc::IPCResult
BrowserParent::RecvReportBlockedEmbedderNodeByClassifier() {
BrowserBridgeParent* bridge = GetBrowserBridgeParent();
if (!bridge) {
return IPC_OK();
}
Unused << bridge->SendAddBlockedNodeByClassifier();
return IPC_OK();
}
already_AddRefed<nsIBrowser> BrowserParent::GetBrowser() { already_AddRefed<nsIBrowser> BrowserParent::GetBrowser() {
nsCOMPtr<nsIBrowser> browser; nsCOMPtr<nsIBrowser> browser;
RefPtr<Element> currentElement = mFrameElement; RefPtr<Element> currentElement = mFrameElement;

View File

@ -314,6 +314,8 @@ class BrowserParent final : public PBrowserParent,
const Maybe<mozilla::ContentBlockingNotifier:: const Maybe<mozilla::ContentBlockingNotifier::
StorageAccessPermissionGrantedReason>& aReason); StorageAccessPermissionGrantedReason>& aReason);
mozilla::ipc::IPCResult RecvReportBlockedEmbedderNodeByClassifier();
mozilla::ipc::IPCResult RecvNavigationFinished(); mozilla::ipc::IPCResult RecvNavigationFinished();
already_AddRefed<nsIBrowser> GetBrowser(); already_AddRefed<nsIBrowser> GetBrowser();

View File

@ -3459,9 +3459,6 @@ mozilla::ipc::IPCResult ContentChild::RecvCrossProcessRedirect(
if (aArgs.sessionHistoryInfo().isSome()) { if (aArgs.sessionHistoryInfo().isSome()) {
loadState->SetSessionHistoryInfo(aArgs.sessionHistoryInfo().ref()); loadState->SetSessionHistoryInfo(aArgs.sessionHistoryInfo().ref());
} }
if (aArgs.originalUriString().isSome()) {
loadState->SetOriginalURIString(aArgs.originalUriString().ref());
}
RefPtr<ChildProcessChannelListener> processListener = RefPtr<ChildProcessChannelListener> processListener =
ChildProcessChannelListener::GetSingleton(); ChildProcessChannelListener::GetSingleton();

View File

@ -672,6 +672,8 @@ parent:
ScrollAxis aHorizontal, ScrollFlags aScrollFlags, ScrollAxis aHorizontal, ScrollFlags aScrollFlags,
int32_t aAppUnitsPerDevPixel); int32_t aAppUnitsPerDevPixel);
async ReportBlockedEmbedderNodeByClassifier();
child: child:
/** /**
* Notify the remote browser that it has been Show()n on this side. This * Notify the remote browser that it has been Show()n on this side. This

View File

@ -66,6 +66,8 @@ child:
async SubFrameCrashed(); async SubFrameCrashed();
async AddBlockedNodeByClassifier();
parent: parent:
// Destroy the remote web browser due to the nsFrameLoader going away. // Destroy the remote web browser due to the nsFrameLoader going away.
async __delete__(); async __delete__();

View File

@ -72,8 +72,6 @@ child:
async SaveStorageAccessPermissionGranted(); async SaveStorageAccessPermissionGranted();
async AddBlockedFrameNodeByClassifier(MaybeDiscardedBrowsingContext aNode);
both: both:
async RawMessage(JSActorMessageMeta aMetadata, ClonedMessageData aData, async RawMessage(JSActorMessageMeta aMetadata, ClonedMessageData aData,
ClonedMessageData aStack); ClonedMessageData aStack);

View File

@ -525,27 +525,6 @@ mozilla::ipc::IPCResult WindowGlobalChild::RecvDispatchSecurityPolicyViolation(
return IPC_OK(); return IPC_OK();
} }
mozilla::ipc::IPCResult WindowGlobalChild::RecvAddBlockedFrameNodeByClassifier(
const MaybeDiscardedBrowsingContext& aNode) {
if (aNode.IsNullOrDiscarded()) {
return IPC_OK();
}
nsGlobalWindowInner* window = GetWindowGlobal();
if (!window) {
return IPC_OK();
}
Document* doc = window->GetDocument();
if (!doc) {
return IPC_OK();
}
MOZ_ASSERT(aNode.get()->GetEmbedderElement()->OwnerDoc() == doc);
doc->AddBlockedNodeByClassifier(aNode.get()->GetEmbedderElement());
return IPC_OK();
}
IPCResult WindowGlobalChild::RecvRawMessage(const JSActorMessageMeta& aMeta, IPCResult WindowGlobalChild::RecvRawMessage(const JSActorMessageMeta& aMeta,
const ClonedMessageData& aData, const ClonedMessageData& aData,
const ClonedMessageData& aStack) { const ClonedMessageData& aStack) {

View File

@ -146,9 +146,6 @@ class WindowGlobalChild final : public WindowGlobalActor,
mozilla::ipc::IPCResult RecvSaveStorageAccessPermissionGranted(); mozilla::ipc::IPCResult RecvSaveStorageAccessPermissionGranted();
mozilla::ipc::IPCResult RecvAddBlockedFrameNodeByClassifier(
const MaybeDiscardedBrowsingContext& aNode);
virtual void ActorDestroy(ActorDestroyReason aWhy) override; virtual void ActorDestroy(ActorDestroyReason aWhy) override;
private: private:

View File

@ -44,7 +44,6 @@
#include "mozilla/dom/Element.h" #include "mozilla/dom/Element.h"
#include "mozilla/dom/RemoteWebProgress.h" #include "mozilla/dom/RemoteWebProgress.h"
#include "mozilla/dom/RemoteWebProgressRequest.h" #include "mozilla/dom/RemoteWebProgressRequest.h"
#include "mozilla/net/UrlClassifierFeatureFactory.h"
#ifdef ANDROID #ifdef ANDROID
# include "mozilla/widget/nsWindow.h" # include "mozilla/widget/nsWindow.h"
@ -176,7 +175,7 @@ class ParentProcessDocumentOpenInfo final : public nsDocumentOpenInfo,
// default listener. This happens when the channel is in // default listener. This happens when the channel is in
// an error state, and we want to just forward that on to be // an error state, and we want to just forward that on to be
// handled in the content process. // handled in the content process.
if (NS_SUCCEEDED(rv) && !mUsedContentHandler && !m_targetStreamListener) { if (!mUsedContentHandler && !m_targetStreamListener) {
m_targetStreamListener = mListener; m_targetStreamListener = mListener;
return m_targetStreamListener->OnStartRequest(request); return m_targetStreamListener->OnStartRequest(request);
} }
@ -199,8 +198,7 @@ class ParentProcessDocumentOpenInfo final : public nsDocumentOpenInfo,
nsCOMPtr<nsIMultiPartChannel> multiPartChannel = nsCOMPtr<nsIMultiPartChannel> multiPartChannel =
do_QueryInterface(request); do_QueryInterface(request);
if (!multiPartChannel && !mCloned) { if (!multiPartChannel && !mCloned) {
DisconnectChildListeners(NS_FAILED(rv) ? rv : NS_BINDING_RETARGETED, DisconnectChildListeners();
rv);
} }
} }
return rv; return rv;
@ -216,14 +214,14 @@ class ParentProcessDocumentOpenInfo final : public nsDocumentOpenInfo,
LOG(("ParentProcessDocumentOpenInfo dtor [this=%p]", this)); LOG(("ParentProcessDocumentOpenInfo dtor [this=%p]", this));
} }
void DisconnectChildListeners(nsresult aStatus, nsresult aLoadGroupStatus) { void DisconnectChildListeners() {
// Tell the DocumentLoadListener to notify the content process that it's // Tell the DocumentLoadListener to notify the content process that it's
// been entirely retargeted, and to stop waiting. // been entirely retargeted, and to stop waiting.
// Clear mListener's pointer to the DocumentLoadListener to break the // Clear mListener's pointer to the DocumentLoadListener to break the
// reference cycle. // reference cycle.
RefPtr<DocumentLoadListener> doc = do_GetInterface(ToSupports(mListener)); RefPtr<DocumentLoadListener> doc = do_GetInterface(ToSupports(mListener));
MOZ_ASSERT(doc); MOZ_ASSERT(doc);
doc->DisconnectListeners(aStatus, aLoadGroupStatus); doc->DisconnectListeners(NS_BINDING_RETARGETED, NS_OK);
mListener->SetListenerAfterRedirect(nullptr); mListener->SetListenerAfterRedirect(nullptr);
} }
@ -522,7 +520,6 @@ auto DocumentLoadListener::Open(
mTiming = aTiming; mTiming = aTiming;
mSrcdocData = aLoadState->SrcdocData(); mSrcdocData = aLoadState->SrcdocData();
mBaseURI = aLoadState->BaseURI(); mBaseURI = aLoadState->BaseURI();
mOriginalUriString = aLoadState->GetOriginalURIString();
if (StaticPrefs::fission_sessionHistoryInParent() && if (StaticPrefs::fission_sessionHistoryInParent() &&
browsingContext->GetSessionHistory()) { browsingContext->GetSessionHistory()) {
mSessionHistoryInfo = mSessionHistoryInfo =
@ -1086,7 +1083,6 @@ void DocumentLoadListener::SerializeRedirectData(
aArgs.baseUri() = mBaseURI; aArgs.baseUri() = mBaseURI;
aArgs.loadStateLoadFlags() = mLoadStateLoadFlags; aArgs.loadStateLoadFlags() = mLoadStateLoadFlags;
aArgs.loadStateLoadType() = mLoadStateLoadType; aArgs.loadStateLoadType() = mLoadStateLoadType;
aArgs.originalUriString() = mOriginalUriString;
if (mSessionHistoryInfo) { if (mSessionHistoryInfo) {
aArgs.sessionHistoryInfo().emplace( aArgs.sessionHistoryInfo().emplace(
mSessionHistoryInfo->mId, MakeUnique<mozilla::dom::SessionHistoryInfo>( mSessionHistoryInfo->mId, MakeUnique<mozilla::dom::SessionHistoryInfo>(
@ -1541,48 +1537,6 @@ void DocumentLoadListener::TriggerRedirectToRealChannel(
}); });
} }
void DocumentLoadListener::MaybeReportBlockedByURLClassifier(nsresult aStatus) {
if (!GetBrowsingContext() || GetBrowsingContext()->IsTop() ||
!StaticPrefs::privacy_trackingprotection_testing_report_blocked_node()) {
return;
}
if (!UrlClassifierFeatureFactory::IsClassifierBlockingErrorCode(aStatus)) {
return;
}
RefPtr<WindowGlobalParent> parent =
GetBrowsingContext()->GetParentWindowContext();
if (parent) {
Unused << parent->SendAddBlockedFrameNodeByClassifier(GetBrowsingContext());
}
}
bool DocumentLoadListener::DocShellWillDisplayContent(nsresult aStatus) {
if (NS_SUCCEEDED(aStatus)) {
return true;
}
// nsDocShell attempts urifixup on some failure types,
// but also of those also display an error page if we don't
// succeed with fixup, so we don't need to check for it
// here.
bool isInitialDocument = true;
if (WindowGlobalParent* currentWindow =
GetBrowsingContext()->GetCurrentWindowGlobal()) {
isInitialDocument = currentWindow->IsInitialDocument();
}
nsresult rv = nsDocShell::FilterStatusForErrorPage(
aStatus, mChannel, mLoadStateLoadType, GetBrowsingContext()->IsTop(),
GetBrowsingContext()->GetUseErrorPages(), isInitialDocument, nullptr);
// If filtering returned a failure code, then an error page will
// be display for that code, so return true;
return NS_FAILED(rv);
}
NS_IMETHODIMP NS_IMETHODIMP
DocumentLoadListener::OnStartRequest(nsIRequest* aRequest) { DocumentLoadListener::OnStartRequest(nsIRequest* aRequest) {
LOG(("DocumentLoadListener OnStartRequest [this=%p]", this)); LOG(("DocumentLoadListener OnStartRequest [this=%p]", this));
@ -1629,16 +1583,11 @@ DocumentLoadListener::OnStartRequest(nsIRequest* aRequest) {
mInitiatedRedirectToRealChannel = true; mInitiatedRedirectToRealChannel = true;
MaybeReportBlockedByURLClassifier(status);
// Determine if a new process needs to be spawned. If it does, this will // Determine if a new process needs to be spawned. If it does, this will
// trigger a cross process switch, and we should hold off on redirecting to // trigger a cross process switch, and we should hold off on redirecting to
// the real channel. // the real channel.
// If the channel has failed, and the docshell isn't going to display an
// error page for that failure, then don't allow process switching, since
// we just want to keep our existing document.
bool willBeRemote = false; bool willBeRemote = false;
if (!DocShellWillDisplayContent(status) || if (status == NS_BINDING_ABORTED ||
!MaybeTriggerProcessSwitch(&willBeRemote)) { !MaybeTriggerProcessSwitch(&willBeRemote)) {
TriggerRedirectToRealChannel(); TriggerRedirectToRealChannel();

View File

@ -284,14 +284,6 @@ class DocumentLoadListener : public nsIInterfaceRequestor,
void Disconnect(); void Disconnect();
void MaybeReportBlockedByURLClassifier(nsresult aStatus);
// Returns true if a channel with aStatus will display
// some sort of content (could be the actual channel data,
// attempt a uri fixup and new load, or an error page).
// Returns false if the docshell will ignore the load entirely.
bool DocShellWillDisplayContent(nsresult aStatus);
// This defines a variant that describes all the attribute setters (and their // This defines a variant that describes all the attribute setters (and their
// parameters) from nsIParentChannel // parameters) from nsIParentChannel
// //
@ -452,8 +444,6 @@ class DocumentLoadListener : public nsIInterfaceRequestor,
// True if cancelled. // True if cancelled.
bool mCancelled = false; bool mCancelled = false;
Maybe<nsCString> mOriginalUriString;
// The process id of the content process that we are being called from // The process id of the content process that we are being called from
// or 0 initiated from a parent process load. // or 0 initiated from a parent process load.
base::ProcessId mOtherPid = 0; base::ProcessId mOtherPid = 0;

View File

@ -469,7 +469,6 @@ struct RedirectToRealChannelArgs {
nsIURI baseUri; nsIURI baseUri;
SessionHistoryInfoAndId? sessionHistoryInfo; SessionHistoryInfoAndId? sessionHistoryInfo;
uint64_t loadIdentifier; uint64_t loadIdentifier;
nsCString? originalUriString;
}; };
struct TimingStructArgs { struct TimingStructArgs {