зеркало из https://github.com/mozilla/gecko-dev.git
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:
Родитель
bdaad3b232
Коммит
e67ceab432
|
@ -1,3 +0,0 @@
|
|||
function handleRequest(request, response) {
|
||||
response.setStatusLine(request.httpVersion, 204, "No Content");
|
||||
}
|
|
@ -1,2 +0,0 @@
|
|||
<!doctype html>
|
||||
This page intentionally left blank.
|
|
@ -19,10 +19,6 @@ tags = audiochannel
|
|||
skip-if = (verify && debug && (os == 'linux'))
|
||||
support-files =
|
||||
test_bug1358314.html
|
||||
[browser_dont_process_switch_204.js]
|
||||
support-files =
|
||||
blank.html
|
||||
204.sjs
|
||||
[browser_e10s_about_page_triggeringprincipal.js]
|
||||
skip-if = verify
|
||||
support-files =
|
||||
|
|
|
@ -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");
|
||||
});
|
||||
});
|
|
@ -321,8 +321,6 @@ already_AddRefed<BrowsingContext> BrowsingContext::CreateDetached(
|
|||
inherit ? inherit->GetUseGlobalHistory() : false;
|
||||
context->mFields.SetWithoutSyncing<IDX_UseGlobalHistory>(useGlobalHistory);
|
||||
|
||||
context->mFields.SetWithoutSyncing<IDX_UseErrorPages>(true);
|
||||
|
||||
nsCOMPtr<nsIRequestContextService> rcsvc =
|
||||
net::RequestContextService::GetOrCreate();
|
||||
if (rcsvc) {
|
||||
|
@ -2078,12 +2076,6 @@ bool BrowsingContext::CanSet(FieldIndex<IDX_FullscreenAllowedByOwner>,
|
|||
return CheckOnlyEmbedderCanSet(aSource);
|
||||
}
|
||||
|
||||
bool BrowsingContext::CanSet(FieldIndex<IDX_UseErrorPages>,
|
||||
const bool& aUseErrorPages,
|
||||
ContentParent* aSource) {
|
||||
return CheckOnlyEmbedderCanSet(aSource);
|
||||
}
|
||||
|
||||
// We map `watchedByDevTools` WebIDL attribute to `watchedByDevToolsInternal`
|
||||
// BC field. And we map it to the top level BrowsingContext.
|
||||
bool BrowsingContext::WatchedByDevTools() {
|
||||
|
|
|
@ -147,8 +147,7 @@ class WindowProxyHolder;
|
|||
/* 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 \
|
||||
* the value from the top BC! */ \
|
||||
FIELD(HasSessionHistory, bool) \
|
||||
FIELD(UseErrorPages, bool)
|
||||
FIELD(HasSessionHistory, bool)
|
||||
|
||||
// BrowsingContext, in this context, is the cross process replicated
|
||||
// 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,
|
||||
ContentParent* aSource);
|
||||
|
||||
bool CanSet(FieldIndex<IDX_UseErrorPages>, const bool& aUseErrorPages,
|
||||
ContentParent* aSource);
|
||||
|
||||
template <size_t I, typename T>
|
||||
bool CanSet(FieldIndex<I>, const T&, ContentParent*) {
|
||||
return true;
|
||||
|
|
|
@ -378,6 +378,7 @@ nsDocShell::nsDocShell(BrowsingContext* aBrowsingContext,
|
|||
mAllowMedia(true),
|
||||
mAllowDNSPrefetch(true),
|
||||
mAllowWindowControl(true),
|
||||
mUseErrorPages(true),
|
||||
mCSSErrorReportingEnabled(false),
|
||||
mAllowAuth(mItemType == typeContent),
|
||||
mAllowKeywordFixup(false),
|
||||
|
@ -712,6 +713,12 @@ nsDocShell::LoadURI(nsDocShellLoadState* aLoadState, bool aSetNavigating) {
|
|||
}
|
||||
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()) {
|
||||
SetCancelContentJSEpoch(*aLoadState->GetCancelContentJSEpoch());
|
||||
}
|
||||
|
@ -800,16 +807,7 @@ nsDocShell::LoadURI(nsDocShellLoadState* aLoadState, bool aSetNavigating) {
|
|||
MOZ_ASSERT(aLoadState->SHEntry() == nullptr,
|
||||
"SHEntry should be null when calling InternalLoad from LoadURI");
|
||||
|
||||
rv = InternalLoad(aLoadState);
|
||||
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;
|
||||
return InternalLoad(aLoadState); // no nsIRequest
|
||||
}
|
||||
|
||||
void nsDocShell::MaybeHandleSubframeHistory(nsDocShellLoadState* aLoadState) {
|
||||
|
@ -1870,13 +1868,13 @@ already_AddRefed<nsILoadURIDelegate> nsDocShell::GetLoadURIDelegate() {
|
|||
|
||||
NS_IMETHODIMP
|
||||
nsDocShell::GetUseErrorPages(bool* aUseErrorPages) {
|
||||
*aUseErrorPages = mBrowsingContext->GetUseErrorPages();
|
||||
*aUseErrorPages = mUseErrorPages;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDocShell::SetUseErrorPages(bool aUseErrorPages) {
|
||||
mBrowsingContext->SetUseErrorPages(aUseErrorPages);
|
||||
mUseErrorPages = aUseErrorPages;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -3610,7 +3608,7 @@ nsDocShell::DisplayLoadError(nsresult aError, nsIURI* aURI,
|
|||
error = "nssFailure2";
|
||||
}
|
||||
|
||||
if (mBrowsingContext->GetUseErrorPages()) {
|
||||
if (mUseErrorPages) {
|
||||
// Display an error page
|
||||
nsresult loadedPage =
|
||||
LoadErrorPage(aURI, aURL, errorPage.get(), error, messageStr.get(),
|
||||
|
@ -5614,279 +5612,6 @@ already_AddRefed<nsIURIFixupInfo> nsDocShell::KeywordToURI(
|
|||
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,
|
||||
nsIChannel* aChannel, nsresult aStatus) {
|
||||
MOZ_LOG(gDocShellLeakLog, LogLevel::Debug,
|
||||
|
@ -6019,56 +5744,287 @@ nsresult nsDocShell::EndPageLoad(nsIWebProgress* aProgress,
|
|||
// (if appropriate).
|
||||
// 5. Throw an error dialog box...
|
||||
//
|
||||
if (NS_FAILED(aStatus)) {
|
||||
nsCOMPtr<nsIInputStream> newPostData;
|
||||
nsCOMPtr<nsIURI> newURI =
|
||||
AttemptURIFixup(aChannel, aStatus, Some(mOriginalUriString), mLoadType,
|
||||
isTopFrame, mAllowKeywordFixup, UsePrivateBrowsing(),
|
||||
true, getter_AddRefs(newPostData));
|
||||
if (newURI) {
|
||||
nsAutoCString newSpec;
|
||||
newURI->GetSpec(newSpec);
|
||||
NS_ConvertUTF8toUTF16 newSpecW(newSpec);
|
||||
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;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsILoadInfo> loadInfo = aChannel->LoadInfo();
|
||||
MOZ_ASSERT(loadInfo, "loadInfo is required on all channels");
|
||||
nsCOMPtr<nsIPrincipal> triggeringPrincipal =
|
||||
loadInfo->TriggeringPrincipal();
|
||||
// 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();
|
||||
|
||||
// If the new URI is HTTP, it may not work and we may want to fall
|
||||
// back to HTTPS, so kick off a speculative connect to get that
|
||||
// started. Even if we don't adjust to HTTPS here, there could be a
|
||||
// redirect to HTTPS coming so this could speed things up.
|
||||
if (SchemeIsHTTP(url)) {
|
||||
int32_t port = 0;
|
||||
rv = url->GetPort(&port);
|
||||
// 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;
|
||||
}
|
||||
|
||||
// only do this if the port is default.
|
||||
if (NS_SUCCEEDED(rv) && port == -1) {
|
||||
nsCOMPtr<nsIURI> httpsURI;
|
||||
rv = NS_MutateURI(url)
|
||||
.SetScheme(NS_LITERAL_CSTRING("https"))
|
||||
.Finalize(getter_AddRefs(httpsURI));
|
||||
RefPtr<BrowsingContext> bc = GetBrowsingContext();
|
||||
RefPtr<BrowsingContext> parentBC = bc->GetParent();
|
||||
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
nsCOMPtr<nsIIOService> ios = do_GetIOService();
|
||||
if (ios) {
|
||||
nsCOMPtr<nsISpeculativeConnect> speculativeService =
|
||||
do_QueryInterface(ios);
|
||||
if (speculativeService) {
|
||||
speculativeService->SpeculativeConnect(
|
||||
httpsURI, triggeringPrincipal, nullptr);
|
||||
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;
|
||||
|
||||
nsAutoCString oldSpec;
|
||||
url->GetSpec(oldSpec);
|
||||
|
||||
//
|
||||
// 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) {
|
||||
info->GetKeywordAsSent(keywordAsSent);
|
||||
info->GetKeywordProviderName(keywordProviderName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LoadURIOptions loadURIOptions;
|
||||
loadURIOptions.mTriggeringPrincipal = triggeringPrincipal;
|
||||
loadURIOptions.mCsp = loadInfo->GetCspToInherit();
|
||||
loadURIOptions.mPostData = newPostData;
|
||||
return LoadURI(newSpecW, loadURIOptions);
|
||||
//
|
||||
// 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;
|
||||
newURI->GetSpec(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();
|
||||
MOZ_ASSERT(loadInfo, "loadInfo is required on all channels");
|
||||
nsCOMPtr<nsIPrincipal> triggeringPrincipal =
|
||||
loadInfo->TriggeringPrincipal();
|
||||
|
||||
// If the new URI is HTTP, it may not work and we may want to fall
|
||||
// back to HTTPS, so kick off a speculative connect to get that
|
||||
// started. Even if we don't adjust to HTTPS here, there could be a
|
||||
// redirect to HTTPS coming so this could speed things up.
|
||||
if (SchemeIsHTTP(url)) {
|
||||
int32_t port = 0;
|
||||
rv = url->GetPort(&port);
|
||||
|
||||
// only do this if the port is default.
|
||||
if (NS_SUCCEEDED(rv) && port == -1) {
|
||||
nsCOMPtr<nsIURI> httpsURI;
|
||||
rv = NS_MutateURI(url)
|
||||
.SetScheme(NS_LITERAL_CSTRING("https"))
|
||||
.Finalize(getter_AddRefs(httpsURI));
|
||||
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
nsCOMPtr<nsIIOService> ios = do_GetIOService();
|
||||
if (ios) {
|
||||
nsCOMPtr<nsISpeculativeConnect> speculativeService =
|
||||
do_QueryInterface(ios);
|
||||
if (speculativeService) {
|
||||
speculativeService->SpeculativeConnect(
|
||||
httpsURI, triggeringPrincipal, nullptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LoadURIOptions loadURIOptions;
|
||||
loadURIOptions.mTriggeringPrincipal = triggeringPrincipal;
|
||||
loadURIOptions.mCsp = loadInfo->GetCspToInherit();
|
||||
loadURIOptions.mPostData = newPostData;
|
||||
return LoadURI(newSpecW, loadURIOptions);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Well, fixup didn't work :-(
|
||||
|
@ -6084,27 +6040,77 @@ nsresult nsDocShell::EndPageLoad(nsIWebProgress* aProgress,
|
|||
aStatus == NS_ERROR_CONTENT_BLOCKED);
|
||||
UnblockEmbedderLoadEventForFailure(fireFrameErrorEvent);
|
||||
|
||||
bool isInitialDocument =
|
||||
!GetExtantDocument() || GetExtantDocument()->IsInitialDocument();
|
||||
bool skippedUnknownProtocolNavigation = false;
|
||||
aStatus = FilterStatusForErrorPage(aStatus, aChannel, mLoadType, isTopFrame,
|
||||
mBrowsingContext->GetUseErrorPages(),
|
||||
isInitialDocument,
|
||||
&skippedUnknownProtocolNavigation);
|
||||
if (NS_FAILED(aStatus)) {
|
||||
// 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) &&
|
||||
(isTopFrame || mUseErrorPages)) {
|
||||
DisplayLoadError(aStatus, url, nullptr, aChannel);
|
||||
} else if (skippedUnknownProtocolNavigation) {
|
||||
nsTArray<nsString> params;
|
||||
if (NS_FAILED(
|
||||
NS_GetSanitizedURIStringFromURI(url, *params.AppendElement()))) {
|
||||
params.LastElement().AssignLiteral(u"(unknown uri)");
|
||||
} 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;
|
||||
if (NS_FAILED(NS_GetSanitizedURIStringFromURI(
|
||||
url, *params.AppendElement()))) {
|
||||
params.LastElement().AssignLiteral(u"(unknown uri)");
|
||||
}
|
||||
nsContentUtils::ReportToConsole(
|
||||
nsIScriptError::warningFlag, NS_LITERAL_CSTRING("DOM"), doc,
|
||||
nsContentUtils::eDOM_PROPERTIES,
|
||||
"UnknownProtocolNavigationPrevented", params);
|
||||
} else {
|
||||
DisplayLoadError(aStatus, url, nullptr, aChannel);
|
||||
}
|
||||
nsContentUtils::ReportToConsole(
|
||||
nsIScriptError::warningFlag, NS_LITERAL_CSTRING("DOM"),
|
||||
GetExtantDocument(), nsContentUtils::eDOM_PROPERTIES,
|
||||
"UnknownProtocolNavigationPrevented", params);
|
||||
} 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 {
|
||||
} else if (url && NS_SUCCEEDED(aStatus)) {
|
||||
// If we have a host
|
||||
nsCOMPtr<nsILoadInfo> loadInfo = aChannel->LoadInfo();
|
||||
PredictorLearnRedirect(url, aChannel, loadInfo->GetOriginAttributes());
|
||||
|
@ -12062,12 +12068,6 @@ nsDocShell::ResumeRedirectedLoad(uint64_t aIdentifier, int32_t aHistoryIndex) {
|
|||
|
||||
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) {
|
||||
extensions::StreamFilterParent::Attach(
|
||||
aLoadState->GetPendingRedirectedChannel(), std::move(endpoint));
|
||||
|
|
|
@ -436,25 +436,6 @@ class nsDocShell final : public nsDocLoader,
|
|||
nsLoadFlags aLoadFlags, uint32_t aCacheKey, nsresult& rv,
|
||||
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:
|
||||
static void MaybeNotifyKeywordSearchLoading(const nsString& aProvider,
|
||||
const nsString& aKeyword);
|
||||
|
@ -759,9 +740,9 @@ class nsDocShell final : public nsDocLoader,
|
|||
uint32_t aResponseStatus, mozilla::dom::BrowsingContext* aBrowsingContext,
|
||||
nsIWidget* aWidget, uint32_t aLoadType);
|
||||
|
||||
static already_AddRefed<nsIURIFixupInfo> KeywordToURI(
|
||||
const nsACString& aKeyword, bool aIsPrivateContext,
|
||||
nsIInputStream** aPostData);
|
||||
already_AddRefed<nsIURIFixupInfo> KeywordToURI(const nsACString& aKeyword,
|
||||
bool aIsPrivateContext,
|
||||
nsIInputStream** aPostData);
|
||||
|
||||
// Sets the current document's current state object to the given SHEntry's
|
||||
// state object. The current state object is eventually given to the page
|
||||
|
@ -1183,6 +1164,7 @@ class nsDocShell final : public nsDocLoader,
|
|||
bool mAllowMedia : 1;
|
||||
bool mAllowDNSPrefetch : 1;
|
||||
bool mAllowWindowControl : 1;
|
||||
bool mUseErrorPages : 1;
|
||||
bool mCSSErrorReportingEnabled : 1;
|
||||
bool mAllowAuth : 1;
|
||||
bool mAllowKeywordFixup : 1;
|
||||
|
|
|
@ -221,6 +221,21 @@ mozilla::ipc::IPCResult BrowserBridgeChild::RecvSubFrameCrashed() {
|
|||
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) {
|
||||
if (!mBrowsingContext) {
|
||||
// This BBC was never valid, skip teardown.
|
||||
|
|
|
@ -94,6 +94,8 @@ class BrowserBridgeChild : public PBrowserBridgeChild {
|
|||
|
||||
mozilla::ipc::IPCResult RecvSubFrameCrashed();
|
||||
|
||||
mozilla::ipc::IPCResult RecvAddBlockedNodeByClassifier();
|
||||
|
||||
void ActorDestroy(ActorDestroyReason aWhy) override;
|
||||
|
||||
private:
|
||||
|
|
|
@ -2763,6 +2763,18 @@ mozilla::ipc::IPCResult BrowserParent::RecvNotifyContentBlockingEvent(
|
|||
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() {
|
||||
nsCOMPtr<nsIBrowser> browser;
|
||||
RefPtr<Element> currentElement = mFrameElement;
|
||||
|
|
|
@ -314,6 +314,8 @@ class BrowserParent final : public PBrowserParent,
|
|||
const Maybe<mozilla::ContentBlockingNotifier::
|
||||
StorageAccessPermissionGrantedReason>& aReason);
|
||||
|
||||
mozilla::ipc::IPCResult RecvReportBlockedEmbedderNodeByClassifier();
|
||||
|
||||
mozilla::ipc::IPCResult RecvNavigationFinished();
|
||||
|
||||
already_AddRefed<nsIBrowser> GetBrowser();
|
||||
|
|
|
@ -3459,9 +3459,6 @@ mozilla::ipc::IPCResult ContentChild::RecvCrossProcessRedirect(
|
|||
if (aArgs.sessionHistoryInfo().isSome()) {
|
||||
loadState->SetSessionHistoryInfo(aArgs.sessionHistoryInfo().ref());
|
||||
}
|
||||
if (aArgs.originalUriString().isSome()) {
|
||||
loadState->SetOriginalURIString(aArgs.originalUriString().ref());
|
||||
}
|
||||
|
||||
RefPtr<ChildProcessChannelListener> processListener =
|
||||
ChildProcessChannelListener::GetSingleton();
|
||||
|
|
|
@ -672,6 +672,8 @@ parent:
|
|||
ScrollAxis aHorizontal, ScrollFlags aScrollFlags,
|
||||
int32_t aAppUnitsPerDevPixel);
|
||||
|
||||
async ReportBlockedEmbedderNodeByClassifier();
|
||||
|
||||
child:
|
||||
/**
|
||||
* Notify the remote browser that it has been Show()n on this side. This
|
||||
|
|
|
@ -66,6 +66,8 @@ child:
|
|||
|
||||
async SubFrameCrashed();
|
||||
|
||||
async AddBlockedNodeByClassifier();
|
||||
|
||||
parent:
|
||||
// Destroy the remote web browser due to the nsFrameLoader going away.
|
||||
async __delete__();
|
||||
|
|
|
@ -72,8 +72,6 @@ child:
|
|||
|
||||
async SaveStorageAccessPermissionGranted();
|
||||
|
||||
async AddBlockedFrameNodeByClassifier(MaybeDiscardedBrowsingContext aNode);
|
||||
|
||||
both:
|
||||
async RawMessage(JSActorMessageMeta aMetadata, ClonedMessageData aData,
|
||||
ClonedMessageData aStack);
|
||||
|
|
|
@ -525,27 +525,6 @@ mozilla::ipc::IPCResult WindowGlobalChild::RecvDispatchSecurityPolicyViolation(
|
|||
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,
|
||||
const ClonedMessageData& aData,
|
||||
const ClonedMessageData& aStack) {
|
||||
|
|
|
@ -146,9 +146,6 @@ class WindowGlobalChild final : public WindowGlobalActor,
|
|||
|
||||
mozilla::ipc::IPCResult RecvSaveStorageAccessPermissionGranted();
|
||||
|
||||
mozilla::ipc::IPCResult RecvAddBlockedFrameNodeByClassifier(
|
||||
const MaybeDiscardedBrowsingContext& aNode);
|
||||
|
||||
virtual void ActorDestroy(ActorDestroyReason aWhy) override;
|
||||
|
||||
private:
|
||||
|
|
|
@ -44,7 +44,6 @@
|
|||
#include "mozilla/dom/Element.h"
|
||||
#include "mozilla/dom/RemoteWebProgress.h"
|
||||
#include "mozilla/dom/RemoteWebProgressRequest.h"
|
||||
#include "mozilla/net/UrlClassifierFeatureFactory.h"
|
||||
|
||||
#ifdef ANDROID
|
||||
# include "mozilla/widget/nsWindow.h"
|
||||
|
@ -176,7 +175,7 @@ class ParentProcessDocumentOpenInfo final : public nsDocumentOpenInfo,
|
|||
// default listener. This happens when the channel is in
|
||||
// an error state, and we want to just forward that on to be
|
||||
// handled in the content process.
|
||||
if (NS_SUCCEEDED(rv) && !mUsedContentHandler && !m_targetStreamListener) {
|
||||
if (!mUsedContentHandler && !m_targetStreamListener) {
|
||||
m_targetStreamListener = mListener;
|
||||
return m_targetStreamListener->OnStartRequest(request);
|
||||
}
|
||||
|
@ -199,8 +198,7 @@ class ParentProcessDocumentOpenInfo final : public nsDocumentOpenInfo,
|
|||
nsCOMPtr<nsIMultiPartChannel> multiPartChannel =
|
||||
do_QueryInterface(request);
|
||||
if (!multiPartChannel && !mCloned) {
|
||||
DisconnectChildListeners(NS_FAILED(rv) ? rv : NS_BINDING_RETARGETED,
|
||||
rv);
|
||||
DisconnectChildListeners();
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
|
@ -216,14 +214,14 @@ class ParentProcessDocumentOpenInfo final : public nsDocumentOpenInfo,
|
|||
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
|
||||
// been entirely retargeted, and to stop waiting.
|
||||
// Clear mListener's pointer to the DocumentLoadListener to break the
|
||||
// reference cycle.
|
||||
RefPtr<DocumentLoadListener> doc = do_GetInterface(ToSupports(mListener));
|
||||
MOZ_ASSERT(doc);
|
||||
doc->DisconnectListeners(aStatus, aLoadGroupStatus);
|
||||
doc->DisconnectListeners(NS_BINDING_RETARGETED, NS_OK);
|
||||
mListener->SetListenerAfterRedirect(nullptr);
|
||||
}
|
||||
|
||||
|
@ -522,7 +520,6 @@ auto DocumentLoadListener::Open(
|
|||
mTiming = aTiming;
|
||||
mSrcdocData = aLoadState->SrcdocData();
|
||||
mBaseURI = aLoadState->BaseURI();
|
||||
mOriginalUriString = aLoadState->GetOriginalURIString();
|
||||
if (StaticPrefs::fission_sessionHistoryInParent() &&
|
||||
browsingContext->GetSessionHistory()) {
|
||||
mSessionHistoryInfo =
|
||||
|
@ -1086,7 +1083,6 @@ void DocumentLoadListener::SerializeRedirectData(
|
|||
aArgs.baseUri() = mBaseURI;
|
||||
aArgs.loadStateLoadFlags() = mLoadStateLoadFlags;
|
||||
aArgs.loadStateLoadType() = mLoadStateLoadType;
|
||||
aArgs.originalUriString() = mOriginalUriString;
|
||||
if (mSessionHistoryInfo) {
|
||||
aArgs.sessionHistoryInfo().emplace(
|
||||
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
|
||||
DocumentLoadListener::OnStartRequest(nsIRequest* aRequest) {
|
||||
LOG(("DocumentLoadListener OnStartRequest [this=%p]", this));
|
||||
|
@ -1629,16 +1583,11 @@ DocumentLoadListener::OnStartRequest(nsIRequest* aRequest) {
|
|||
|
||||
mInitiatedRedirectToRealChannel = true;
|
||||
|
||||
MaybeReportBlockedByURLClassifier(status);
|
||||
|
||||
// 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
|
||||
// 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;
|
||||
if (!DocShellWillDisplayContent(status) ||
|
||||
if (status == NS_BINDING_ABORTED ||
|
||||
!MaybeTriggerProcessSwitch(&willBeRemote)) {
|
||||
TriggerRedirectToRealChannel();
|
||||
|
||||
|
|
|
@ -284,14 +284,6 @@ class DocumentLoadListener : public nsIInterfaceRequestor,
|
|||
|
||||
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
|
||||
// parameters) from nsIParentChannel
|
||||
//
|
||||
|
@ -452,8 +444,6 @@ class DocumentLoadListener : public nsIInterfaceRequestor,
|
|||
// True if cancelled.
|
||||
bool mCancelled = false;
|
||||
|
||||
Maybe<nsCString> mOriginalUriString;
|
||||
|
||||
// The process id of the content process that we are being called from
|
||||
// or 0 initiated from a parent process load.
|
||||
base::ProcessId mOtherPid = 0;
|
||||
|
|
|
@ -469,7 +469,6 @@ struct RedirectToRealChannelArgs {
|
|||
nsIURI baseUri;
|
||||
SessionHistoryInfoAndId? sessionHistoryInfo;
|
||||
uint64_t loadIdentifier;
|
||||
nsCString? originalUriString;
|
||||
};
|
||||
|
||||
struct TimingStructArgs {
|
||||
|
|
Загрузка…
Ссылка в новой задаче