commit 3de98e520cea74e1f1bdc8a112bb66a8f2a19541
Author: Karandeep Bhatia <
karan...@chromium.org>
AuthorDate: Sat Mar 13 03:48:45 2021
Commit: Chromium LUCI CQ <
chromiu...@luci-project-accounts.iam.gserviceaccount.com>
CommitDate: Sat Mar 13 03:48:45 2021
Extensions: Plumb whether request was blocked by an extension.
Currently navigation requests blocked with net::ERR_BLOCKED_BY_CLIENT
error code are all incorrectly reported as being blocked by extensions.
This CL plumbs whether the request was blocked by an extension using the
opaque "extended_error_code" field of URLLoaderCompletionStatus. To
avoid layering violations, blink::ResourceRequestBlockedReason is
extended by embedders.
This helps in showing a more correct error message to the user when a
non-extensions client blocked a main-frame request using
net::ERR_BLOCKED_BY_CLIENT. The "extended_error_code" can further be
used by other net::ERR_BLOCKED_BY_CLIENT clients to improve the error
message shown to the user.
This information can also be used by Devtools in a future CL to show
whether a request was blocked by an extension.
Also, the ResourceRequestBlockedReason::kCollapsedByClient is now
removed and is replaced with a separate field. This was necessary since
the "extended_error_code" needed to be kExtension in this case. It also
makes semantic sense since "collapsing" is an action to take and not a
reason.
BUG=649869
Change-Id: Iab66268ef9110b73301cfeaa79724f00036594af
Reviewed-on:
https://chromium-review.googlesource.com/c/chromium/src/+/2721253
Commit-Queue: Karan Bhatia <
karan...@chromium.org>
Reviewed-by: Andrey Kosyakov <
ca...@chromium.org>
Reviewed-by: Dominick Ng <
domi...@chromium.org>
Reviewed-by: Colin Blundell <
blun...@chromium.org>
Reviewed-by: Gauthier Ambard <
gam...@chromium.org>
Reviewed-by: Edward Jung (EMEA) <
edwar...@chromium.org>
Reviewed-by: John Abd-El-Malek <
j...@chromium.org>
Reviewed-by: Devlin <
rdevlin...@chromium.org>
Cr-Commit-Position: refs/heads/master@{#862652}
diff --git a/chrome/browser/extensions/api/declarative_net_request/declarative_net_request_browsertest.cc b/chrome/browser/extensions/api/declarative_net_request/declarative_net_request_browsertest.cc
index a79f268..386074b 100644
--- a/chrome/browser/extensions/api/declarative_net_request/declarative_net_request_browsertest.cc
+++ b/chrome/browser/extensions/api/declarative_net_request/declarative_net_request_browsertest.cc
@@ -1887,6 +1887,27 @@
EXPECT_TRUE(IsNavigationBlocked(url));
}
+// Ensure that when an extension blocks a main-frame request using
+// declarativeNetRequest, the resultant error page attributes this to an
+// extension.
+IN_PROC_BROWSER_TEST_P(DeclarativeNetRequestBrowserTest,
+ ErrorPageForBlockedMainFrameNavigation) {
+ ASSERT_NO_FATAL_FAILURE(
+ LoadExtensionWithRules({CreateMainFrameBlockRule("
example.com")}));
+
+ ui_test_utils::NavigateToURL(browser(), GetURLForFilter("
example.com"));
+ EXPECT_EQ(content::PAGE_TYPE_ERROR, GetPageType());
+
+ std::string body;
+ ASSERT_TRUE(content::ExecuteScriptAndExtractString(
+ web_contents(),
+ "window.domAutomationController.send(document.body.textContent)", &body));
+
+ EXPECT_TRUE(
+ base::Contains(body, "This page has been blocked by an extension"));
+ EXPECT_TRUE(base::Contains(body, "Try disabling your extensions."));
+}
+
// Test an extension with multiple static rulesets.
IN_PROC_BROWSER_TEST_P(DeclarativeNetRequestBrowserTest, MultipleRulesets) {
set_config_flags(ConfigFlag::kConfig_HasBackgroundScript);
diff --git a/chrome/browser/extensions/api/web_request/web_request_apitest.cc b/chrome/browser/extensions/api/web_request/web_request_apitest.cc
index c7cbf33..86160ab 100644
--- a/chrome/browser/extensions/api/web_request/web_request_apitest.cc
+++ b/chrome/browser/extensions/api/web_request/web_request_apitest.cc
@@ -3027,6 +3027,26 @@
1);
}
+// Ensure that when an extension blocks a main-frame request, the resultant
+// error page attributes this to an extension.
+IN_PROC_BROWSER_TEST_F(ExtensionWebRequestApiTest,
+ ErrorPageForBlockedMainFrameNavigation) {
+ ASSERT_TRUE(StartEmbeddedTestServer());
+ ASSERT_TRUE(
+ RunExtensionSubtest("webrequest", "test_simple_cancel_navigation.html"))
+ << message_;
+
+ std::string body;
+ WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
+ ASSERT_TRUE(content::ExecuteScriptAndExtractString(
+ tab, "window.domAutomationController.send(document.body.textContent)",
+ &body));
+
+ EXPECT_TRUE(
+ base::Contains(body, "This page has been blocked by an extension"));
+ EXPECT_TRUE(base::Contains(body, "Try disabling your extensions."));
+}
+
// Regression test for
http://crbug.com/996940. Requests that redirected to an
// appcache handled URL could have request ID collisions.
// This test is flaky on Linux:
https://crbug.com/1094834.
diff --git a/chrome/browser/extensions/extension_resource_request_policy_apitest.cc b/chrome/browser/extensions/extension_resource_request_policy_apitest.cc
index f88d9d33..6000b9a 100644
--- a/chrome/browser/extensions/extension_resource_request_policy_apitest.cc
+++ b/chrome/browser/extensions/extension_resource_request_policy_apitest.cc
@@ -3,12 +3,15 @@
// found in the LICENSE file.
#include "base/command_line.h"
+#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
+#include "build/branding_buildflags.h"
#include "build/build_config.h"
#include "chrome/browser/extensions/extension_apitest.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/test/base/ui_test_utils.h"
+#include "components/crx_file/id_util.h"
#include "content/public/browser/navigation_controller.h"
#include "content/public/browser/navigation_entry.h"
#include "content/public/browser/navigation_handle.h"
@@ -785,4 +788,35 @@
inaccessible_resource, "local-frame", url_blocked_by_renderer);
}
+// Regression test for
crbug.com/649869. Ensures that on navigation to an
+// invalid extension resource (or more generally for navigations blocked by the
+// browser with net::ERR_BLOCKED_BY_CLIENT), the error page doesn't incorrectly
+// attribute extensions as the cause of the blocked request.
+IN_PROC_BROWSER_TEST_F(ExtensionResourceRequestPolicyTest,
+ NavigationToInvalidExtensionPage) {
+ std::string url =
+ base::StringPrintf("chrome-extension://%s/manifest.json",
+ crx_file::id_util::GenerateId("foo").c_str());
+ ui_test_utils::NavigateToURL(browser(), GURL(url));
+
+ std::string body;
+ content::WebContents* tab =
+ browser()->tab_strip_model()->GetActiveWebContents();
+ ASSERT_TRUE(content::ExecuteScriptAndExtractString(
+ tab, "window.domAutomationController.send(document.body.textContent)",
+ &body));
+
+ std::string expected_error;
+#if BUILDFLAG(GOOGLE_CHROME_BRANDING)
+ expected_error = "This page has been blocked by Chrome";
+#else
+ expected_error = "This page has been blocked by Chromium";
+#endif
+
+ EXPECT_TRUE(base::Contains(body, expected_error));
+ EXPECT_FALSE(
+ base::Contains(body, "This page has been blocked by an extension"));
+ EXPECT_FALSE(base::Contains(body, "Try disabling your extensions."));
+}
+
} // namespace extensions
diff --git a/chrome/common/BUILD.gn b/chrome/common/BUILD.gn
index 39b1950..36c47c8 100644
--- a/chrome/common/BUILD.gn
+++ b/chrome/common/BUILD.gn
@@ -106,6 +106,7 @@
"chrome_content_client_constants.cc",
"chrome_descriptors.h",
"chrome_isolated_world_ids.h",
+ "chrome_resource_request_blocked_reason.h",
"chrome_result_codes.h",
"common_message_generator.cc",
"common_message_generator.h",
diff --git a/chrome/common/chrome_resource_request_blocked_reason.h b/chrome/common/chrome_resource_request_blocked_reason.h
new file mode 100644
index 0000000..ed589d7
--- /dev/null
+++ b/chrome/common/chrome_resource_request_blocked_reason.h
@@ -0,0 +1,17 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_COMMON_CHROME_RESOURCE_REQUEST_BLOCKED_REASON_H_
+#define CHROME_COMMON_CHROME_RESOURCE_REQUEST_BLOCKED_REASON_H_
+
+#include "content/public/common/resource_request_blocked_reason.h"
+
+// Extends content::ResourceRequestBlockedReason with Chrome specific reasons.
+enum class ChromeResourceRequestBlockedReason {
+ kExtension =
+ static_cast<int>(content::ResourceRequestBlockedReason::kMax) + 1,
+ kMax = kExtension,
+};
+
+#endif // CHROME_COMMON_CHROME_RESOURCE_REQUEST_BLOCKED_REASON_H_
diff --git a/chrome/common/extensions/chrome_extensions_client.cc b/chrome/common/extensions/chrome_extensions_client.cc
index 8e0a063..e0651bc 100644
--- a/chrome/common/extensions/chrome_extensions_client.cc
+++ b/chrome/common/extensions/chrome_extensions_client.cc
@@ -13,6 +13,7 @@
#include "base/metrics/histogram_macros.h"
#include "base/strings/string_util.h"
#include "base/values.h"
+#include "chrome/common/chrome_resource_request_blocked_reason.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/extensions/chrome_extensions_api_provider.h"
#include "chrome/common/extensions/manifest_handlers/theme_handler.h"
@@ -251,4 +252,9 @@
}
}
+base::Optional<int> ChromeExtensionsClient::GetExtensionExtendedErrorCode()
+ const {
+ return static_cast<int>(ChromeResourceRequestBlockedReason::kExtension);
+}
+
} // namespace extensions
diff --git a/chrome/common/extensions/chrome_extensions_client.h b/chrome/common/extensions/chrome_extensions_client.h
index 914816f..aa134ff 100644
--- a/chrome/common/extensions/chrome_extensions_client.h
+++ b/chrome/common/extensions/chrome_extensions_client.h
@@ -48,6 +48,7 @@
bool is_extension_active,
std::vector<network::mojom::CorsOriginPatternPtr>* origin_patterns)
const override;
+ base::Optional<int> GetExtensionExtendedErrorCode() const override;
private:
const ChromePermissionMessageProvider permission_message_provider_;
diff --git a/chrome/renderer/chrome_content_renderer_client.cc b/chrome/renderer/chrome_content_renderer_client.cc
index 9c69377..08dda0d 100644
--- a/chrome/renderer/chrome_content_renderer_client.cc
+++ b/chrome/renderer/chrome_content_renderer_client.cc
@@ -1223,9 +1223,9 @@
std::string* error_html) {
NetErrorHelper::Get(render_frame)
->PrepareErrorPage(
- error_page::Error::NetError(web_error.url(), web_error.reason(),
- web_error.resolve_error_info(),
- web_error.has_copy_in_cache()),
+ error_page::Error::NetError(
+ web_error.url(), web_error.reason(), web_error.extended_reason(),
+ web_error.resolve_error_info(), web_error.has_copy_in_cache()),
http_method == "POST", error_html);
#if BUILDFLAG(ENABLE_SUPERVISED_USERS)
diff --git a/chrome/renderer/net/net_error_helper.cc b/chrome/renderer/net/net_error_helper.cc
index 2441627..448697e 100644
--- a/chrome/renderer/net/net_error_helper.cc
+++ b/chrome/renderer/net/net_error_helper.cc
@@ -20,6 +20,7 @@
#include "base/strings/utf_string_conversions.h"
#include "base/values.h"
#include "build/build_config.h"
+#include "chrome/common/chrome_resource_request_blocked_reason.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/renderer/chrome_render_thread_observer.h"
#include "components/error_page/common/error.h"
@@ -82,6 +83,11 @@
return NetErrorHelperCore::SUB_FRAME;
}
+bool IsExtensionExtendedErrorCode(int extended_error_code) {
+ return extended_error_code ==
+ static_cast<int>(ChromeResourceRequestBlockedReason::kExtension);
+}
+
#if defined(OS_ANDROID)
bool IsOfflineContentOnNetErrorFeatureEnabled() {
return true;
@@ -251,7 +257,8 @@
error.stale_copy_in_cache(), can_show_network_diagnostics_dialog,
ChromeRenderThreadObserver::is_incognito_process(),
IsOfflineContentOnNetErrorFeatureEnabled(), IsAutoFetchFeatureEnabled(),
- IsRunningInForcedAppMode(), RenderThread::Get()->GetLocale());
+ IsRunningInForcedAppMode(), RenderThread::Get()->GetLocale(),
+ IsExtensionExtendedErrorCode(error.extended_reason()));
DCHECK(!template_html.empty()) << "unable to load template.";
// "t" is the id of the template's root node.
*error_html =
@@ -276,7 +283,8 @@
error.stale_copy_in_cache(), can_show_network_diagnostics_dialog,
ChromeRenderThreadObserver::is_incognito_process(),
IsOfflineContentOnNetErrorFeatureEnabled(), IsAutoFetchFeatureEnabled(),
- IsRunningInForcedAppMode(), RenderThread::Get()->GetLocale());
+ IsRunningInForcedAppMode(), RenderThread::Get()->GetLocale(),
+ IsExtensionExtendedErrorCode(error.extended_reason()));
std::string json;
JSONWriter::Write(page_state.strings, &json);
diff --git a/chrome/renderer/net/net_error_helper_core_unittest.cc b/chrome/renderer/net/net_error_helper_core_unittest.cc
index ef34b78..9ccb67c 100644
--- a/chrome/renderer/net/net_error_helper_core_unittest.cc
+++ b/chrome/renderer/net/net_error_helper_core_unittest.cc
@@ -59,12 +59,13 @@
}
error_page::Error NetErrorForURL(net::Error net_error, const GURL& url) {
- return error_page::Error::NetError(url, net_error,
+ return error_page::Error::NetError(url, net_error, 0 /* extended_reason */,
net::ResolveErrorInfo(net::OK), false);
}
error_page::Error NetError(net::Error net_error) {
return error_page::Error::NetError(GURL(kFailedUrl), net_error,
+ 0 /* extended_reason */,
net::ResolveErrorInfo(net::OK), false);
}
diff --git a/components/components_chromium_strings.grd b/components/components_chromium_strings.grd
index 2a8cf5c..f627c9c 100644
--- a/components/components_chromium_strings.grd
+++ b/components/components_chromium_strings.grd
@@ -213,6 +213,9 @@
settings.
</message>
</if>
+ <message name="IDS_ERRORPAGES_SUMMARY_BLOCKED_BY_CLIENT" desc="Summary in the error page when a request is blocked by the browser.">
+ This page has been blocked by Chromium
+ </message>
<message name="IDS_ERRORPAGES_SUMMARY_BLOCKED_ENROLLMENT_CHECK_PENDING" desc="Summary in the error page when the user tries to browse before the forced enrollment check has finished.">
Chromium OS hasn’t completed its initial setup.
</message>
diff --git a/components/components_chromium_strings_grd/IDS_ERRORPAGES_SUMMARY_BLOCKED_BY_CLIENT.png.sha1 b/components/components_chromium_strings_grd/IDS_ERRORPAGES_SUMMARY_BLOCKED_BY_CLIENT.png.sha1
new file mode 100644
index 0000000..b542092
--- /dev/null
+++ b/components/components_chromium_strings_grd/IDS_ERRORPAGES_SUMMARY_BLOCKED_BY_CLIENT.png.sha1
@@ -0,0 +1 @@
+095d0ae82d88d26967b4f2ce45b7517506cee0bd
\ No newline at end of file
diff --git a/components/components_google_chrome_strings.grd b/components/components_google_chrome_strings.grd
index 3799227..08f603b 100644
--- a/components/components_google_chrome_strings.grd
+++ b/components/components_google_chrome_strings.grd
@@ -213,6 +213,9 @@
settings.
</message>
</if>
+ <message name="IDS_ERRORPAGES_SUMMARY_BLOCKED_BY_CLIENT" desc="Summary in the error page when a request is blocked by the browser.">
+ This page has been blocked by Chrome
+ </message>
<message name="IDS_ERRORPAGES_SUMMARY_BLOCKED_ENROLLMENT_CHECK_PENDING" desc="Summary in the error page when the user tries to browse before the forced enrollment check has finished.">
Chrome OS hasn’t completed its initial setup.
</message>
diff --git a/components/components_google_chrome_strings_grd/IDS_ERRORPAGES_SUMMARY_BLOCKED_BY_CLIENT.png.sha1 b/components/components_google_chrome_strings_grd/IDS_ERRORPAGES_SUMMARY_BLOCKED_BY_CLIENT.png.sha1
new file mode 100644
index 0000000..3360ec5
--- /dev/null
+++ b/components/components_google_chrome_strings_grd/IDS_ERRORPAGES_SUMMARY_BLOCKED_BY_CLIENT.png.sha1
@@ -0,0 +1 @@
+5fb6b742a7f6c7d92658e92ab7a54c5177a0b60c
\ No newline at end of file
diff --git a/components/error_page/common/error.cc b/components/error_page/common/error.cc
index 957febd..7d516c0 100644
--- a/components/error_page/common/error.cc
+++ b/components/error_page/common/error.cc
@@ -14,32 +14,39 @@
Error Error::NetError(const GURL& url,
int reason,
+ int extended_reason,
net::ResolveErrorInfo resolve_error_info,
bool stale_copy_in_cache) {
- return Error(url, kNetErrorDomain, reason, std::move(resolve_error_info),
- stale_copy_in_cache);
+ return Error(url, kNetErrorDomain, reason, extended_reason,
+ std::move(resolve_error_info), stale_copy_in_cache);
}
Error Error::HttpError(const GURL& url, int http_status_code) {
- return Error(url, kHttpErrorDomain, http_status_code,
+ return Error(url, kHttpErrorDomain, http_status_code, 0,
net::ResolveErrorInfo(net::OK), false);
}
Error Error::DnsProbeError(const GURL& url,
int status,
bool stale_copy_in_cache) {
- return Error(url, kDnsProbeErrorDomain, status,
+ return Error(url, kDnsProbeErrorDomain, status, 0,
net::ResolveErrorInfo(net::OK), stale_copy_in_cache);
}
+Error::~Error() = default;
+Error::Error(const Error&) = default;
+Error& Error::operator=(const Error&) = default;
+
Error::Error(const GURL& url,
const std::string& domain,
int reason,
+ int extended_reason,
net::ResolveErrorInfo resolve_error_info,
bool stale_copy_in_cache)
: url_(url),
domain_(domain),
reason_(reason),
+ extended_reason_(extended_reason),
resolve_error_info_(std::move(resolve_error_info)),
stale_copy_in_cache_(stale_copy_in_cache) {}
diff --git a/components/error_page/common/error.h b/components/error_page/common/error.h
index 16c9095..b9dd7ad 100644
--- a/components/error_page/common/error.h
+++ b/components/error_page/common/error.h
@@ -26,6 +26,7 @@
// Returns a kNetErrorDomain error.
static Error NetError(const GURL& url,
int reason,
+ int extended_reason,
net::ResolveErrorInfo resolve_error_info,
bool stale_copy_in_cache);
// Returns a kHttpErrorDomain error.
@@ -35,6 +36,10 @@
int status,
bool stale_copy_in_cache);
+ ~Error();
+ Error(const Error&);
+ Error& operator=(const Error&);
+
// Returns the url that failed to load.
const GURL& url() const { return url_; }
// Returns the domain of this error.
@@ -42,6 +47,10 @@
// Returns a numeric error code. The meaning of this code depends on the
// domain string.
int reason() const { return reason_; }
+ // Returns a numeric error code containing additional information about the
+ // error. Note that the extended reason is only relevant when `reason()` is
+ // `kNetErrorDomain`.
+ int extended_reason() const { return extended_reason_; }
// Returns error details of the host resolution.
const net::ResolveErrorInfo& resolve_error_info() const {
return resolve_error_info_;
@@ -53,12 +62,14 @@
Error(const GURL& url,
const std::string& domain,
int reason,
+ int extended_reason,
net::ResolveErrorInfo resolve_error_info,
bool stale_copy_in_cache);
GURL url_;
std::string domain_;
int reason_;
+ int extended_reason_;
net::ResolveErrorInfo resolve_error_info_;
bool stale_copy_in_cache_;
};
diff --git a/components/error_page/common/localized_error.cc b/components/error_page/common/localized_error.cc
index 58f83f92..47f7650b 100644
--- a/components/error_page/common/localized_error.cc
+++ b/components/error_page/common/localized_error.cc
@@ -17,7 +17,6 @@
#include "base/metrics/field_trial.h"
#include "base/notreached.h"
#include "base/stl_util.h"
-#include "base/strings/string16.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
@@ -283,8 +282,8 @@
},
{net::ERR_BLOCKED_BY_CLIENT,
IDS_ERRORPAGES_HEADING_BLOCKED,
- IDS_ERRORPAGES_SUMMARY_BLOCKED_BY_EXTENSION,
- SUGGEST_DISABLE_EXTENSION,
+ IDS_ERRORPAGES_SUMMARY_BLOCKED_BY_CLIENT,
+ SUGGEST_NONE,
SHOW_BUTTON_RELOAD,
},
{net::ERR_BLOCKED_BY_CSP,
@@ -907,7 +906,8 @@
bool offline_content_feature_enabled,
bool auto_fetch_feature_enabled,
bool is_kiosk_mode,
- const std::string& locale) {
+ const std::string& locale,
+ bool is_blocked_by_extension) {
LocalizedError::PageState result;
result.is_offline_error = IsOfflineError(error_domain, error_code);
@@ -994,8 +994,18 @@
auto summary = std::make_unique<base::DictionaryValue>();
// Set summary message under the heading.
- summary->SetString("msg",
- l10n_util::GetStringUTF16(options.summary_resource_id));
+ std::u16string message;
+ if (is_blocked_by_extension) {
+ // Use a custom message if an extension blocked the request.
+ message =
+ l10n_util::GetStringUTF16(IDS_ERRORPAGES_SUMMARY_BLOCKED_BY_EXTENSION);
+ options.suggestions = SUGGEST_DISABLE_EXTENSION;
+ } else {
+ message = l10n_util::GetStringUTF16(options.summary_resource_id);
+ }
+
+ summary->SetString("msg", std::move(message));
+
summary->SetString("failedUrl", failed_url_string);
summary->SetString("hostName", host_name);
diff --git a/components/error_page/common/localized_error.h b/components/error_page/common/localized_error.h
index f72e30c..1d80c342 100644
--- a/components/error_page/common/localized_error.h
+++ b/components/error_page/common/localized_error.h
@@ -54,7 +54,8 @@
bool auto_fetch_feature_enabled,
bool is_kiosk_mode, // whether device is currently in single app (kiosk)
// mode
- const std::string& locale);
+ const std::string& locale,
+ bool is_blocked_by_extension);
// Returns a description of the encountered error.
static std::u16string GetErrorDetails(const std::string& error_domain,
diff --git a/components/error_page_strings.grdp b/components/error_page_strings.grdp
index c91ff8c..f933a34 100644
--- a/components/error_page_strings.grdp
+++ b/components/error_page_strings.grdp
@@ -248,7 +248,7 @@
<ph name="HOST_NAME"><strong jscontent="hostName"></strong><ex>
www.whatever.com</ex></ph> didn’t accept your login certificate, or one may not have been provided.
</message>
<message name="IDS_ERRORPAGES_SUMMARY_BLOCKED_BY_EXTENSION" desc="Summary in the error page when an extension blocks a request.">
- Requests to the server have been blocked by an extension.
+ This page has been blocked by an extension
</message>
<message name="IDS_ERRORPAGES_SUMMARY_BLOCKED_BY_ADMINISTRATOR" desc="Summary in the error page when an administrator policy blocks a request.">
The person who set up this computer has chosen to block this site.
diff --git a/components/error_page_strings_grdp/IDS_ERRORPAGES_SUMMARY_BLOCKED_BY_EXTENSION.png.sha1 b/components/error_page_strings_grdp/IDS_ERRORPAGES_SUMMARY_BLOCKED_BY_EXTENSION.png.sha1
new file mode 100644
index 0000000..0debf68
--- /dev/null
+++ b/components/error_page_strings_grdp/IDS_ERRORPAGES_SUMMARY_BLOCKED_BY_EXTENSION.png.sha1
@@ -0,0 +1 @@
+75cd8d008d2dfeb9ba9c837b3b2bf41be678a0f6
\ No newline at end of file
diff --git a/content/browser/devtools/protocol/network_handler.cc b/content/browser/devtools/protocol/network_handler.cc
index 79f6b0d..f81ff5a 100644
--- a/content/browser/devtools/protocol/network_handler.cc
+++ b/content/browser/devtools/protocol/network_handler.cc
@@ -1723,8 +1723,6 @@
return protocol::Network::BlockedReasonEnum::ContentType;
case blink::ResourceRequestBlockedReason::kOther:
return protocol::Network::BlockedReasonEnum::Other;
- case blink::ResourceRequestBlockedReason::kCollapsedByClient:
- return protocol::Network::BlockedReasonEnum::CollapsedByClient;
case blink::ResourceRequestBlockedReason::kCoepFrameResourceNeedsCoepHeader:
return protocol::Network::BlockedReasonEnum::
CoepFrameResourceNeedsCoepHeader;
@@ -1776,8 +1774,16 @@
if (status.error_code != net::ERR_BLOCKED_BY_CLIENT &&
status.error_code != net::ERR_BLOCKED_BY_RESPONSE)
return Maybe<String>();
- return blockedReason(static_cast<blink::ResourceRequestBlockedReason>(
- status.extended_error_code));
+
+ if (status.extended_error_code <=
+ static_cast<int>(blink::ResourceRequestBlockedReason::kMax)) {
+ return blockedReason(static_cast<blink::ResourceRequestBlockedReason>(
+ status.extended_error_code));
+ }
+
+ // TODO(karandeepb): Embedder would know how to interpret the
+ // `status.extended_error_code` in this case. For now just return Other.
+ return {protocol::Network::BlockedReasonEnum::Other};
}
String GetTrustTokenOperationType(
diff --git a/content/browser/renderer_host/navigation_request.cc b/content/browser/renderer_host/navigation_request.cc
index baac322..615b50b 100644
--- a/content/browser/renderer_host/navigation_request.cc
+++ b/content/browser/renderer_host/navigation_request.cc
@@ -2799,12 +2799,10 @@
const network::URLLoaderCompletionStatus& status) {
DCHECK_NE(status.error_code, net::OK);
- bool collapse_frame =
- status.extended_error_code ==
- static_cast<int>(blink::ResourceRequestBlockedReason::kCollapsedByClient);
- OnRequestFailedInternal(status, false /* skip_throttles */,
- base::nullopt /* error_page_content */,
- collapse_frame);
+ OnRequestFailedInternal(
+ status, false /* skip_throttles */,
+ base::nullopt /* error_page_content */,
+ status.should_collapse_initiator /* collapse_frame */);
}
void NavigationRequest::OnRequestFailedInternal(
@@ -2837,6 +2835,7 @@
pending_entry_ref_.reset();
net_error_ = static_cast<net::Error>(status.error_code);
+ extended_error_code_ = status.extended_error_code;
resolve_error_info_ = status.resolve_error_info;
if (MaybeCancelFailedNavigation())
@@ -3279,6 +3278,8 @@
net::Error old_net_error = net_error_;
net_error_ = result.net_error_code();
+ // FIXME: Should we clear out |extended_error_code_| here?
+
// Ensure that WillFailRequest() isn't changing the error code in a way that
// switches the destination process for the error page - see
//
https://crbug.com/817881.
@@ -3437,9 +3438,9 @@
ReadyToCommitNavigation(true);
// Use a separate cache shard, and no cookies, for error pages.
isolation_info_for_subresources_ = net::IsolationInfo::CreateTransient();
- render_frame_host_->FailedNavigation(this, *common_params_, *commit_params_,
- has_stale_copy_in_cache_, net_error_,
- error_page_content);
+ render_frame_host_->FailedNavigation(
+ this, *common_params_, *commit_params_, has_stale_copy_in_cache_,
+ net_error_, extended_error_code_, error_page_content);
}
void NavigationRequest::AddOldPageInfoToCommitParamsIfNeeded() {
diff --git a/content/browser/renderer_host/navigation_request.h b/content/browser/renderer_host/navigation_request.h
index 74c3bfb4..fb6af61 100644
--- a/content/browser/renderer_host/navigation_request.h
+++ b/content/browser/renderer_host/navigation_request.h
@@ -1327,6 +1327,8 @@
// checks are performed by the NavigationHandle.
bool has_stale_copy_in_cache_ = false;
net::Error net_error_ = net::OK;
+ int extended_error_code_ = 0;
+
// Detailed host resolution error information. The error code in
// |resolve_error_info_.error| should be consistent with (but not necessarily
// the same as) |net_error_|. In the case of a host resolution error, for
diff --git a/content/browser/renderer_host/render_frame_host_impl.cc b/content/browser/renderer_host/render_frame_host_impl.cc
index dacea0f..f2d027d3 100644
--- a/content/browser/renderer_host/render_frame_host_impl.cc
+++ b/content/browser/renderer_host/render_frame_host_impl.cc
@@ -6858,6 +6858,7 @@
const mojom::CommitNavigationParams& commit_params,
bool has_stale_copy_in_cache,
int error_code,
+ int extended_error_code,
const base::Optional<std::string>& error_page_content) {
TRACE_EVENT2("navigation", "RenderFrameHostImpl::FailedNavigation",
"frame_tree_node", frame_tree_node_->frame_tree_node_id(),
@@ -6897,8 +6898,8 @@
SendCommitFailedNavigation(
navigation_client, navigation_request, common_params.Clone(),
commit_params.Clone(), has_stale_copy_in_cache, error_code,
- error_page_content, std::move(subresource_loader_factories),
- std::move(policy_container));
+ extended_error_code, error_page_content,
+ std::move(subresource_loader_factories), std::move(policy_container));
// TODO(crbug/1129537): support UKM source creation for failed navigations
// too.
@@ -9316,6 +9317,7 @@
mojom::CommitNavigationParamsPtr commit_params,
bool has_stale_copy_in_cache,
int32_t error_code,
+ int32_t extended_error_code,
const base::Optional<std::string>& error_page_content,
std::unique_ptr<blink::PendingURLLoaderFactoryBundle>
subresource_loader_factories,
@@ -9324,7 +9326,7 @@
DCHECK_NE(GURL(), common_params->url);
navigation_client->CommitFailedNavigation(
std::move(common_params), std::move(commit_params),
- has_stale_copy_in_cache, error_code,
+ has_stale_copy_in_cache, error_code, extended_error_code,
navigation_request->GetResolveErrorInfo(), error_page_content,
std::move(subresource_loader_factories), std::move(policy_container),
BuildCommitFailedNavigationCallback(navigation_request));
diff --git a/content/browser/renderer_host/render_frame_host_impl.h b/content/browser/renderer_host/render_frame_host_impl.h
index 2dd48f8..49bfcb5 100644
--- a/content/browser/renderer_host/render_frame_host_impl.h
+++ b/content/browser/renderer_host/render_frame_host_impl.h
@@ -1024,6 +1024,7 @@
const mojom::CommitNavigationParams& commit_params,
bool has_stale_copy_in_cache,
int error_code,
+ int extended_error_code,
const base::Optional<std::string>& error_page_content);
// Seneds a renderer-debug URL to the renderer process for handling.
@@ -2041,6 +2042,7 @@
mojom::CommitNavigationParamsPtr commit_params,
bool has_stale_copy_in_cache,
int32_t error_code,
+ int32_t extended_error_code,
const base::Optional<std::string>& error_page_content,
std::unique_ptr<blink::PendingURLLoaderFactoryBundle>
subresource_loader_factories,
diff --git a/content/browser/service_worker/service_worker_test_utils.cc b/content/browser/service_worker/service_worker_test_utils.cc
index a5f7444..30a4236 100644
--- a/content/browser/service_worker/service_worker_test_utils.cc
+++ b/content/browser/service_worker/service_worker_test_utils.cc
@@ -92,6 +92,7 @@
mojom::CommitNavigationParamsPtr commit_params,
bool has_stale_copy_in_cache,
int error_code,
+ int extended_error_code,
const net::ResolveErrorInfo& resolve_error_info,
const base::Optional<std::string>& error_page_content,
std::unique_ptr<blink::PendingURLLoaderFactoryBundle> subresource_loaders,
diff --git a/content/common/navigation_client.mojom b/content/common/navigation_client.mojom
index 45b889f3..e6fee95 100644
--- a/content/common/navigation_client.mojom
+++ b/content/common/navigation_client.mojom
@@ -254,6 +254,7 @@
CommitNavigationParams request_params,
bool has_stale_copy_in_cache,
int32 error_code,
+ int32 extended_error_code,
network.mojom.ResolveErrorInfo resolve_error_info,
string? error_page_content,
blink.mojom.URLLoaderFactoryBundle? subresource_loader_factories,
diff --git a/content/public/common/BUILD.gn b/content/public/common/BUILD.gn
index d50372f..964c4de 100644
--- a/content/public/common/BUILD.gn
+++ b/content/public/common/BUILD.gn
@@ -141,6 +141,7 @@
"referrer.h",
"referrer_type_converters.cc",
"referrer_type_converters.h",
+ "resource_request_blocked_reason.h",
"resource_usage_reporter_type_converters.cc",
"resource_usage_reporter_type_converters.h",
"result_codes.h",
diff --git a/content/public/common/resource_request_blocked_reason.h b/content/public/common/resource_request_blocked_reason.h
new file mode 100644
index 0000000..187d1e0
--- /dev/null
+++ b/content/public/common/resource_request_blocked_reason.h
@@ -0,0 +1,24 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_PUBLIC_COMMON_RESOURCE_REQUEST_BLOCKED_REASON_H_
+#define CONTENT_PUBLIC_COMMON_RESOURCE_REQUEST_BLOCKED_REASON_H_
+
+#include "third_party/blink/public/platform/resource_request_blocked_reason.h"
+
+namespace content {
+
+// Extends blink::ResourceRequestBlockedReason with Content specific reasons.
+enum class ResourceRequestBlockedReason {
+ kContentStart =
+ static_cast<int>(blink::ResourceRequestBlockedReason::kMax) + 1,
+
+ // Any reasons specific to content/ should be added here, and the `kMax` value
+ // below should be appropriately modified.
+ kMax = kContentStart,
+};
+
+} // namespace content
+
+#endif // CONTENT_PUBLIC_COMMON_RESOURCE_REQUEST_BLOCKED_REASON_H_
diff --git a/content/renderer/navigation_client.cc b/content/renderer/navigation_client.cc
index 7c91430..182edb7 100644
--- a/content/renderer/navigation_client.cc
+++ b/content/renderer/navigation_client.cc
@@ -51,6 +51,7 @@
mojom::CommitNavigationParamsPtr commit_params,
bool has_stale_copy_in_cache,
int error_code,
+ int extended_error_code,
const net::ResolveErrorInfo& resolve_error_info,
const base::Optional<std::string>& error_page_content,
std::unique_ptr<blink::PendingURLLoaderFactoryBundle> subresource_loaders,
@@ -59,8 +60,8 @@
ResetDisconnectionHandler();
render_frame_->CommitFailedNavigation(
std::move(common_params), std::move(commit_params),
- has_stale_copy_in_cache, error_code, resolve_error_info,
- error_page_content, std::move(subresource_loaders),
+ has_stale_copy_in_cache, error_code, extended_error_code,
+ resolve_error_info, error_page_content, std::move(subresource_loaders),
std::move(policy_container), std::move(callback));
}
diff --git a/content/renderer/navigation_client.h b/content/renderer/navigation_client.h
index 5a278fb..12e0a31 100644
--- a/content/renderer/navigation_client.h
+++ b/content/renderer/navigation_client.h
@@ -41,6 +41,7 @@
mojom::CommitNavigationParamsPtr commit_params,
bool has_stale_copy_in_cache,
int error_code,
+ int extended_error_code,
const net::ResolveErrorInfo& resolve_error_info,
const base::Optional<std::string>& error_page_content,
std::unique_ptr<blink::PendingURLLoaderFactoryBundle> subresource_loaders,
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc
index 128ecac..0970915 100644
--- a/content/renderer/render_frame_impl.cc
+++ b/content/renderer/render_frame_impl.cc
@@ -3177,6 +3177,7 @@
mojom::CommitNavigationParamsPtr commit_params,
bool has_stale_copy_in_cache,
int error_code,
+ int extended_error_code,
net::ResolveErrorInfo resolve_error_info,
const base::Optional<std::string>& error_page_content,
std::unique_ptr<blink::PendingURLLoaderFactoryBundle>
@@ -3214,10 +3215,11 @@
// Send the provisional load failure.
WebURLError error(
- error_code, 0, resolve_error_info,
+ error_code, extended_error_code, resolve_error_info,
has_stale_copy_in_cache ? WebURLError::HasCopyInCache::kTrue
: WebURLError::HasCopyInCache::kFalse,
- WebURLError::IsWebSecurityViolation::kFalse, common_params->url);
+ WebURLError::IsWebSecurityViolation::kFalse, common_params->url,
+ WebURLError::ShouldCollapseInitiator::kFalse);
auto navigation_params = std::make_unique<WebNavigationParams>();
FillNavigationParamsRequest(*common_params, *commit_params,
diff --git a/content/renderer/render_frame_impl.h b/content/renderer/render_frame_impl.h
index 62d2f9c..9ab20de 100644
--- a/content/renderer/render_frame_impl.h
+++ b/content/renderer/render_frame_impl.h
@@ -461,6 +461,7 @@
mojom::CommitNavigationParamsPtr commit_params,
bool has_stale_copy_in_cache,
int error_code,
+ int extended_error_code,
net::ResolveErrorInfo resolve_error_info,
const base::Optional<std::string>& error_page_content,
std::unique_ptr<blink::PendingURLLoaderFactoryBundle>
diff --git a/content/test/test_render_frame.cc b/content/test/test_render_frame.cc
index 7a6a3e0..a7cae13 100644
--- a/content/test/test_render_frame.cc
+++ b/content/test/test_render_frame.cc
@@ -293,9 +293,9 @@
network::NotImplementedURLLoaderFactory::Create());
mock_navigation_client_->CommitFailedNavigation(
std::move(common_params), std::move(commit_params),
- false /* has_stale_copy_in_cache */, error_code, resolve_error_info,
- error_page_content, std::move(pending_factory_bundle),
- CreateStubPolicyContainer(),
+ false /* has_stale_copy_in_cache */, error_code,
+ 0 /* extended_error_code */, resolve_error_info, error_page_content,
+ std::move(pending_factory_bundle), CreateStubPolicyContainer(),
base::BindOnce(&MockFrameHost::DidCommitProvisionalLoad,
base::Unretained(mock_frame_host_.get())));
}
diff --git a/content/test/test_render_frame_host.cc b/content/test/test_render_frame_host.cc
index 7a5beea..abb86065 100644
--- a/content/test/test_render_frame_host.cc
+++ b/content/test/test_render_frame_host.cc
@@ -499,6 +499,7 @@
mojom::CommitNavigationParamsPtr commit_params,
bool has_stale_copy_in_cache,
int32_t error_code,
+ int32_t extended_error_code,
const base::Optional<std::string>& error_page_content,
std::unique_ptr<blink::PendingURLLoaderFactoryBundle>
subresource_loader_factories,
diff --git a/content/test/test_render_frame_host.h b/content/test/test_render_frame_host.h
index 847a384..a2f09a3 100644
--- a/content/test/test_render_frame_host.h
+++ b/content/test/test_render_frame_host.h
@@ -234,6 +234,7 @@
mojom::CommitNavigationParamsPtr commit_params,
bool has_stale_copy_in_cache,
int32_t error_code,
+ int32_t extended_error_code,
const base::Optional<std::string>& error_page_content,
std::unique_ptr<blink::PendingURLLoaderFactoryBundle>
subresource_loader_factories,
diff --git a/extensions/browser/api/web_request/web_request_proxying_url_loader_factory.cc b/extensions/browser/api/web_request/web_request_proxying_url_loader_factory.cc
index bbb4497..a774f68 100644
--- a/extensions/browser/api/web_request/web_request_proxying_url_loader_factory.cc
+++ b/extensions/browser/api/web_request/web_request_proxying_url_loader_factory.cc
@@ -25,6 +25,7 @@
#include "extensions/browser/extension_navigation_ui_data.h"
#include "extensions/browser/extension_registry.h"
#include "extensions/common/extension_features.h"
+#include "extensions/common/extensions_client.h"
#include "extensions/common/manifest_handlers/web_accessible_resources_info.h"
#include "net/base/completion_repeating_callback.h"
#include "net/http/http_response_headers.h"
@@ -37,7 +38,6 @@
#include "services/metrics/public/cpp/ukm_source_id.h"
#include "services/network/public/cpp/features.h"
#include "third_party/blink/public/common/loader/throttling_url_loader.h"
-#include "third_party/blink/public/platform/resource_request_blocked_reason.h"
#include "url/origin.h"
namespace extensions {
@@ -238,11 +238,8 @@
if (result == net::ERR_BLOCKED_BY_CLIENT) {
// The request was cancelled synchronously. Dispatch an error notification
// and terminate the request.
- network::URLLoaderCompletionStatus status(result);
- if (should_collapse_initiator) {
- status.extended_error_code = static_cast<int>(
- blink::ResourceRequestBlockedReason::kCollapsedByClient);
- }
+ network::URLLoaderCompletionStatus status =
+ CreateURLLoaderCompletionStatus(result, should_collapse_initiator);
OnRequestError(status, state_on_error);
return;
}
@@ -355,8 +352,7 @@
if (redirect_url_ != redirect_info.new_url &&
!IsRedirectSafe(request_.url, redirect_info.new_url,
info_->is_navigation_request)) {
- OnNetworkError(
- network::URLLoaderCompletionStatus(net::ERR_UNSAFE_REDIRECT));
+ OnNetworkError(CreateURLLoaderCompletionStatus(net::ERR_UNSAFE_REDIRECT));
return;
}
@@ -469,7 +465,7 @@
header_client_receiver_.set_disconnect_handler(base::BindOnce(
&WebRequestProxyingURLLoaderFactory::InProgressRequest::OnNetworkError,
weak_factory_.GetWeakPtr(),
- network::URLLoaderCompletionStatus(net::ERR_FAILED)));
+ CreateURLLoaderCompletionStatus(net::ERR_FAILED)));
}
}
@@ -564,8 +560,7 @@
void WebRequestProxyingURLLoaderFactory::InProgressRequest::
ContinueToBeforeSendHeaders(State state_on_error, int error_code) {
if (error_code != net::OK) {
- OnRequestError(network::URLLoaderCompletionStatus(error_code),
- state_on_error);
+ OnRequestError(CreateURLLoaderCompletionStatus(error_code), state_on_error);
return;
}
@@ -595,8 +590,7 @@
if (result == net::ERR_BLOCKED_BY_CLIENT) {
// The request was cancelled synchronously. Dispatch an error notification
// and terminate the request.
- OnRequestError(network::URLLoaderCompletionStatus(result),
- state_on_error);
+ OnRequestError(CreateURLLoaderCompletionStatus(result), state_on_error);
return;
}
@@ -623,15 +617,14 @@
void WebRequestProxyingURLLoaderFactory::InProgressRequest::
ContinueToStartRequest(State state_on_error, int error_code) {
if (error_code != net::OK) {
- OnRequestError(network::URLLoaderCompletionStatus(error_code),
- state_on_error);
+ OnRequestError(CreateURLLoaderCompletionStatus(error_code), state_on_error);
return;
}
if (current_request_uses_header_client_ && !redirect_url_.is_empty()) {
if (for_cors_preflight_) {
// CORS preflight doesn't support redirect.
- OnRequestError(network::URLLoaderCompletionStatus(net::ERR_FAILED),
+ OnRequestError(CreateURLLoaderCompletionStatus(net::ERR_FAILED),
state_on_error);
return;
}
@@ -685,8 +678,7 @@
const std::set<std::string>& set_headers,
int error_code) {
if (error_code != net::OK) {
- OnRequestError(network::URLLoaderCompletionStatus(error_code),
- state_on_error);
+ OnRequestError(CreateURLLoaderCompletionStatus(error_code), state_on_error);
return;
}
@@ -833,7 +825,7 @@
} else {
state = State::kRejectedByOnHeadersReceivedForFinalResponse;
}
- OnRequestError(network::URLLoaderCompletionStatus(error_code), state);
+ OnRequestError(CreateURLLoaderCompletionStatus(error_code), state);
return;
}
@@ -850,7 +842,7 @@
}
if (for_cors_preflight_ && !redirect_url_.is_empty()) {
- OnRequestError(network::URLLoaderCompletionStatus(net::ERR_FAILED),
+ OnRequestError(CreateURLLoaderCompletionStatus(net::ERR_FAILED),
State::kRejectedByOnHeadersReceivedForRedirect);
return;
}
@@ -880,7 +872,7 @@
ContinueToResponseStarted(int error_code) {
DCHECK(!for_cors_preflight_);
if (error_code != net::OK) {
- OnRequestError(network::URLLoaderCompletionStatus(error_code),
+ OnRequestError(CreateURLLoaderCompletionStatus(error_code),
State::kRejectedByOnHeadersReceivedForFinalResponse);
return;
}
@@ -932,7 +924,7 @@
ContinueToBeforeRedirect(const net::RedirectInfo& redirect_info,
int error_code) {
if (error_code != net::OK) {
- OnRequestError(network::URLLoaderCompletionStatus(error_code),
+ OnRequestError(CreateURLLoaderCompletionStatus(error_code),
kRejectedByOnHeadersReceivedForRedirect);
return;
}
@@ -990,7 +982,7 @@
} else {
state = State::kRejectedByOnHeadersReceivedForFinalResponse;
}
- OnRequestError(network::URLLoaderCompletionStatus(result), state);
+ OnRequestError(CreateURLLoaderCompletionStatus(result), state);
return;
}
@@ -1045,7 +1037,7 @@
} else if (state_ == State::kInProgressWithFinalResponseReceived) {
state = State::kDetachedFromClientAfterReceivingResponse;
}
- OnRequestError(network::URLLoaderCompletionStatus(net::ERR_ABORTED), state);
+ OnRequestError(CreateURLLoaderCompletionStatus(net::ERR_ABORTED), state);
}
void WebRequestProxyingURLLoaderFactory::InProgressRequest::
@@ -1064,7 +1056,7 @@
// Deletes |this|.
factory_->RemoveRequest(network_service_request_id_, request_id_);
} else {
- OnNetworkError(network::URLLoaderCompletionStatus(net::ERR_ABORTED));
+ OnNetworkError(CreateURLLoaderCompletionStatus(net::ERR_ABORTED));
}
}
@@ -1088,6 +1080,20 @@
return content::IsSafeRedirectTarget(from_url, to_url);
}
+network::URLLoaderCompletionStatus WebRequestProxyingURLLoaderFactory::
+ InProgressRequest::CreateURLLoaderCompletionStatus(
+ int error_code,
+ bool collapse_initiator) {
+ network::URLLoaderCompletionStatus status(error_code);
+ status.should_collapse_initiator = collapse_initiator;
+ if (error_code == net::ERR_BLOCKED_BY_CLIENT) {
+ status.extended_error_code =
+ ExtensionsClient::Get()->GetExtensionExtendedErrorCode().value_or(0);
+ }
+
+ return status;
+}
+
WebRequestProxyingURLLoaderFactory::WebRequestProxyingURLLoaderFactory(
content::BrowserContext* browser_context,
int render_process_id,
diff --git a/extensions/browser/api/web_request/web_request_proxying_url_loader_factory.h b/extensions/browser/api/web_request/web_request_proxying_url_loader_factory.h
index 0e436d8..16b0a836 100644
--- a/extensions/browser/api/web_request/web_request_proxying_url_loader_factory.h
+++ b/extensions/browser/api/web_request/web_request_proxying_url_loader_factory.h
@@ -18,6 +18,7 @@
#include "content/public/browser/content_browser_client.h"
#include "extensions/browser/api/web_request/web_request_api.h"
#include "extensions/browser/api/web_request/web_request_info.h"
+#include "extensions/common/extension_id.h"
#include "mojo/public/cpp/bindings/pending_receiver.h"
#include "mojo/public/cpp/bindings/pending_remote.h"
#include "mojo/public/cpp/bindings/receiver.h"
@@ -168,6 +169,10 @@
bool is_navigation_request);
void HandleBeforeRequestRedirect();
+ network::URLLoaderCompletionStatus CreateURLLoaderCompletionStatus(
+ int error_code,
+ bool collapse_initiator = false);
+
WebRequestProxyingURLLoaderFactory* const factory_;
network::ResourceRequest request_;
const base::Optional<url::Origin> original_initiator_;
diff --git a/extensions/common/extensions_client.cc b/extensions/common/extensions_client.cc
index c691944..a7e325c 100644
--- a/extensions/common/extensions_client.cc
+++ b/extensions/common/extensions_client.cc
@@ -107,6 +107,10 @@
bool is_extension_active,
std::vector<network::mojom::CorsOriginPatternPtr>* origin_patterns) const {}
+base::Optional<int> ExtensionsClient::GetExtensionExtendedErrorCode() const {
+ return base::nullopt;
+}
+
void ExtensionsClient::DoInitialize() {
initialize_called_ = true;
diff --git a/extensions/common/extensions_client.h b/extensions/common/extensions_client.h
index 759b4d80..3f15ea4 100644
--- a/extensions/common/extensions_client.h
+++ b/extensions/common/extensions_client.h
@@ -141,6 +141,11 @@
bool is_extension_active,
std::vector<network::mojom::CorsOriginPatternPtr>* origin_patterns) const;
+ // Returns the extended error code used by the embedder when an extension
+ // blocks a request. Returns base::nullopt if the embedder doesn't define such
+ // an error code.
+ virtual base::Optional<int> GetExtensionExtendedErrorCode() const;
+
private:
// Performs common initialization and calls Initialize() to allow subclasses
// to do any extra initialization.
diff --git a/ios/chrome/browser/web/
error_page_util.mm b/ios/chrome/browser/web/
error_page_util.mm
index 1c2e46d63a..b4015e9 100644
--- a/ios/chrome/browser/web/
error_page_util.mm
+++ b/ios/chrome/browser/web/
error_page_util.mm
@@ -56,7 +56,8 @@
/*offline_content_feature_enabled=*/false,
/*auto_fetch_feature_enabled=*/false,
/*is_kiosk_mode=*/false,
- GetApplicationContext()->GetApplicationLocale());
+ GetApplicationContext()->GetApplicationLocale(),
+ /*is_blocked_by_extension=*/false);
ui::ScaleFactor scale_factor =
ui::ResourceBundle::GetSharedInstance().GetMaxScaleFactor();
diff --git a/services/network/public/cpp/network_ipc_param_traits.h b/services/network/public/cpp/network_ipc_param_traits.h
index 647824d2..dda95c96b 100644
--- a/services/network/public/cpp/network_ipc_param_traits.h
+++ b/services/network/public/cpp/network_ipc_param_traits.h
@@ -84,7 +84,7 @@
IPC_STRUCT_TRAITS_MEMBER(should_report_corb_blocking)
IPC_STRUCT_TRAITS_MEMBER(proxy_server)
IPC_STRUCT_TRAITS_MEMBER(resolve_error_info)
-
+ IPC_STRUCT_TRAITS_MEMBER(should_collapse_initiator)
IPC_STRUCT_TRAITS_END()
IPC_ENUM_TRAITS_MAX_VALUE(network::mojom::FetchResponseType,
diff --git a/services/network/public/cpp/url_loader_completion_status.cc b/services/network/public/cpp/url_loader_completion_status.cc
index 0fbf50b..45eea53 100644
--- a/services/network/public/cpp/url_loader_completion_status.cc
+++ b/services/network/public/cpp/url_loader_completion_status.cc
@@ -41,7 +41,8 @@
cors_error_status == rhs.cors_error_status &&
blocked_by_response_reason == rhs.blocked_by_response_reason &&
should_report_corb_blocking == rhs.should_report_corb_blocking &&
- proxy_server == rhs.proxy_server;
+ proxy_server == rhs.proxy_server &&
+ should_collapse_initiator == rhs.should_collapse_initiator;
}
} // namespace network
diff --git a/services/network/public/cpp/url_loader_completion_status.h b/services/network/public/cpp/url_loader_completion_status.h
index 4c3b678..266d099 100644
--- a/services/network/public/cpp/url_loader_completion_status.h
+++ b/services/network/public/cpp/url_loader_completion_status.h
@@ -21,8 +21,9 @@
namespace network {
-// NOTE: When adding/removing fields to this struct, don't forget to
-// update services/network/public/cpp/network_ipc_param_traits.h.
+// NOTE: When adding/removing fields to this struct, don't forget to update
+// services/network/public/cpp/network_ipc_param_traits.h and the equals (==)
+// operator below.
struct COMPONENT_EXPORT(NETWORK_CPP_BASE) URLLoaderCompletionStatus {
URLLoaderCompletionStatus();
@@ -99,6 +100,9 @@
// Host resolution error info for this request.
net::ResolveErrorInfo resolve_error_info;
+
+ // Whether the initiator of this request should be collapsed.
+ bool should_collapse_initiator = false;
};
} // namespace network
diff --git a/third_party/blink/public/devtools_protocol/browser_protocol.pdl b/third_party/blink/public/devtools_protocol/browser_protocol.pdl
index 25c7127..c4e7a895 100644
--- a/third_party/blink/public/devtools_protocol/browser_protocol.pdl
+++ b/third_party/blink/public/devtools_protocol/browser_protocol.pdl
@@ -4605,7 +4605,6 @@
inspector
subresource-filter
content-type
- collapsed-by-client
coep-frame-resource-needs-coep-header
coop-sandboxed-iframe-cannot-navigate-to-coop-page
corp-not-same-origin
diff --git a/third_party/blink/public/platform/resource_request_blocked_reason.h b/third_party/blink/public/platform/resource_request_blocked_reason.h
index dd43021..fe1f000 100644
--- a/third_party/blink/public/platform/resource_request_blocked_reason.h
+++ b/third_party/blink/public/platform/resource_request_blocked_reason.h
@@ -9,21 +9,22 @@
// If updating this enum, also update DevTools protocol usages.
// Contact devtools owners for help.
enum class ResourceRequestBlockedReason {
- kOther,
+ kOther = 0,
kCSP,
kMixedContent,
kOrigin,
kInspector,
kSubresourceFilter,
kContentType,
- kCollapsedByClient,
kCoepFrameResourceNeedsCoepHeader,
kCoopSandboxedIFrameCannotNavigateToCoopPage,
kCorpNotSameOrigin,
kCorpNotSameOriginAfterDefaultedToSameOriginByCoep,
kCorpNotSameSite,
kConversionRequest,
+ kMax = kConversionRequest,
};
+
} // namespace blink
#endif
diff --git a/third_party/blink/public/platform/web_url_error.h b/third_party/blink/public/platform/web_url_error.h
index 89aabf3..d4516a4 100644
--- a/third_party/blink/public/platform/web_url_error.h
+++ b/third_party/blink/public/platform/web_url_error.h
@@ -51,6 +51,10 @@
kFalse,
kTrue,
};
+ enum class ShouldCollapseInitiator {
+ kFalse,
+ kTrue,
+ };
WebURLError() = delete;
// |reason| must not be 0.
@@ -61,7 +65,8 @@
net::ResolveErrorInfo resolve_error_info,
HasCopyInCache,
IsWebSecurityViolation,
- const WebURL&);
+ const WebURL&,
+ ShouldCollapseInitiator);
BLINK_PLATFORM_EXPORT WebURLError(
network::mojom::BlockedByResponseReason blocked_reason,
net::ResolveErrorInfo resolve_error_info,
@@ -100,6 +105,7 @@
const {
return trust_token_operation_error_;
}
+ bool should_collapse_initiator() const { return should_collapse_initiator_; }
private:
// A numeric error code detailing the reason for this error. The value must
@@ -125,6 +131,9 @@
// Optional CORS error details.
base::Optional<network::CorsErrorStatus> cors_error_status_;
+ // True if the initiator of this request should be collapsed.
+ bool should_collapse_initiator_ = false;
+
// More detailed reason for failing the response with
// ERR_net::ERR_BLOCKED_BY_RESPONSE |error_code|.
base::Optional<network::mojom::BlockedByResponseReason>
diff --git a/third_party/blink/renderer/core/inspector/inspector_network_agent.cc b/third_party/blink/renderer/core/inspector/inspector_network_agent.cc
index 01b5927..3c56bac 100644
--- a/third_party/blink/renderer/core/inspector/inspector_network_agent.cc
+++ b/third_party/blink/renderer/core/inspector/inspector_network_agent.cc
@@ -373,8 +373,6 @@
return protocol::Network::BlockedReasonEnum::ContentType;
case ResourceRequestBlockedReason::kOther:
return protocol::Network::BlockedReasonEnum::Other;
- case ResourceRequestBlockedReason::kCollapsedByClient:
- return protocol::Network::BlockedReasonEnum::CollapsedByClient;
case blink::ResourceRequestBlockedReason::kCoepFrameResourceNeedsCoepHeader:
return protocol::Network::BlockedReasonEnum::
CoepFrameResourceNeedsCoepHeader;
@@ -400,6 +398,23 @@
return protocol::Network::BlockedReasonEnum::Other;
}
+Maybe<String> BuildBlockedReason(const ResourceError& error) {
+ int error_code = error.ErrorCode();
+ if (error_code != net::ERR_BLOCKED_BY_CLIENT &&
+ error_code != net::ERR_BLOCKED_BY_RESPONSE) {
+ return Maybe<String>();
+ }
+
+ base::Optional<ResourceRequestBlockedReason> resource_request_blocked_reason =
+ error.GetResourceRequestBlockedReason();
+ if (resource_request_blocked_reason)
+ return BuildBlockedReason(*resource_request_blocked_reason);
+
+ // TODO(karandeepb): Embedder would know how to interpret the
+ // `error.extended_error_code_` in this case. For now just return Other.
+ return {protocol::Network::BlockedReasonEnum::Other};
+}
+
String BuildCorsError(network::mojom::CorsError cors_error) {
switch (cors_error) {
case network::mojom::CorsError::kDisallowedByMode:
@@ -1411,12 +1426,8 @@
}
bool canceled = error.IsCancellation();
- base::Optional<ResourceRequestBlockedReason> resource_request_blocked_reason =
- error.GetResourceRequestBlockedReason();
- protocol::Maybe<String> blocked_reason;
- if (resource_request_blocked_reason) {
- blocked_reason = BuildBlockedReason(*resource_request_blocked_reason);
- }
+
+ protocol::Maybe<String> blocked_reason = BuildBlockedReason(error);
auto cors_error_status = error.CorsErrorStatus();
protocol::Maybe<protocol::Network::CorsErrorStatus>
protocol_cors_error_status;
diff --git a/third_party/blink/renderer/platform/exported/web_url_error.cc b/third_party/blink/renderer/platform/exported/web_url_error.cc
index 6db8b13..cb549e2 100644
--- a/third_party/blink/renderer/platform/exported/web_url_error.cc
+++ b/third_party/blink/renderer/platform/exported/web_url_error.cc
@@ -19,14 +19,17 @@
net::ResolveErrorInfo resolve_error_info,
HasCopyInCache has_copy_in_cache,
IsWebSecurityViolation is_web_security_violation,
- const WebURL& url)
+ const WebURL& url,
+ ShouldCollapseInitiator should_collapse_initiator)
: reason_(reason),
extended_reason_(extended_reason),
resolve_error_info_(resolve_error_info),
has_copy_in_cache_(has_copy_in_cache == HasCopyInCache::kTrue),
is_web_security_violation_(is_web_security_violation ==
IsWebSecurityViolation::kTrue),
- url_(url) {
+ url_(url),
+ should_collapse_initiator_(should_collapse_initiator ==
+ ShouldCollapseInitiator::kTrue) {
DCHECK_NE(reason_, 0);
}
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource_error.cc b/third_party/blink/renderer/platform/loader/fetch/resource_error.cc
index adb8770..22cfc7b8 100644
--- a/third_party/blink/renderer/platform/loader/fetch/resource_error.cc
+++ b/third_party/blink/renderer/platform/loader/fetch/resource_error.cc
@@ -54,7 +54,7 @@
ResourceRequestBlockedReason blocked_reason) {
ResourceError error = CancelledError(url);
error.is_access_check_ = true;
- error.blocked_by_subresource_filter_ =
+ error.should_collapse_inititator_ =
blocked_reason == ResourceRequestBlockedReason::kSubresourceFilter;
return error;
}
@@ -112,6 +112,7 @@
is_access_check_(error.is_web_security_violation()),
has_copy_in_cache_(error.has_copy_in_cache()),
cors_error_status_(error.cors_error_status()),
+ should_collapse_inititator_(error.should_collapse_initiator()),
blocked_by_response_reason_(error.blocked_by_response_reason()),
trust_token_operation_error_(error.trust_token_operation_error()) {
DCHECK_NE(error_code_, 0);
@@ -137,7 +138,10 @@
error_code_, extended_error_code_, resolve_error_info_, has_copy_in_cache,
is_access_check_ ? WebURLError::IsWebSecurityViolation::kTrue
: WebURLError::IsWebSecurityViolation::kFalse,
- failing_url_);
+ failing_url_,
+ should_collapse_inititator_
+ ? WebURLError::ShouldCollapseInitiator::kTrue
+ : WebURLError::ShouldCollapseInitiator::kFalse);
}
bool ResourceError::Compare(const ResourceError& a, const ResourceError& b) {
@@ -168,6 +172,9 @@
if (a.trust_token_operation_error_ != b.trust_token_operation_error_)
return false;
+ if (a.should_collapse_inititator_ != b.should_collapse_inititator_)
+ return false;
+
return true;
}
@@ -199,12 +206,6 @@
return error_code_ == net::ERR_BLOCKED_BY_RESPONSE;
}
-bool ResourceError::ShouldCollapseInitiator() const {
- return blocked_by_subresource_filter_ ||
- GetResourceRequestBlockedReason() ==
- ResourceRequestBlockedReason::kCollapsedByClient;
-}
-
namespace {
blink::ResourceRequestBlockedReason
BlockedByResponseReasonToResourceRequestBlockedReason(
@@ -242,7 +243,13 @@
return BlockedByResponseReasonToResourceRequestBlockedReason(
*blocked_by_response_reason_);
}
- return static_cast<ResourceRequestBlockedReason>(extended_error_code_);
+
+ if (extended_error_code_ <=
+ static_cast<int>(ResourceRequestBlockedReason::kMax)) {
+ return static_cast<ResourceRequestBlockedReason>(extended_error_code_);
+ }
+
+ return base::nullopt;
}
base::Optional<network::mojom::BlockedByResponseReason>
@@ -255,13 +262,15 @@
}
namespace {
-String DescriptionForBlockedByClientOrResponse(int error, int extended_error) {
- if (extended_error == 0)
+String DescriptionForBlockedByClientOrResponse(
+ int error,
+ const base::Optional<blink::ResourceRequestBlockedReason>& reason) {
+ if (!reason || *reason == ResourceRequestBlockedReason::kOther)
return WebString::FromASCII(net::ErrorToString(error));
std::string detail;
- switch (static_cast<ResourceRequestBlockedReason>(extended_error)) {
+ switch (*reason) {
case ResourceRequestBlockedReason::kOther:
- NOTREACHED(); // extended_error == 0, handled above
+ NOTREACHED(); // handled above
break;
case ResourceRequestBlockedReason::kCSP:
detail = "CSP";
@@ -281,9 +290,6 @@
case ResourceRequestBlockedReason::kContentType:
detail = "ContentType";
break;
- case ResourceRequestBlockedReason::kCollapsedByClient:
- detail = "Collapsed";
- break;
case ResourceRequestBlockedReason::kCoepFrameResourceNeedsCoepHeader:
detail = "ResponseNeedsCrossOriginEmbedderPolicy";
break;
@@ -314,8 +320,10 @@
localized_description_ = WebString::FromASCII(kThrottledErrorDescription);
} else if (error_code_ == net::ERR_BLOCKED_BY_CLIENT ||
error_code_ == net::ERR_BLOCKED_BY_RESPONSE) {
- localized_description_ = DescriptionForBlockedByClientOrResponse(
- error_code_, extended_error_code_);
+ base::Optional<ResourceRequestBlockedReason> reason =
+ GetResourceRequestBlockedReason();
+ localized_description_ =
+ DescriptionForBlockedByClientOrResponse(error_code_, reason);
} else {
localized_description_ = WebString::FromASCII(
net::ExtendedErrorToString(error_code_, extended_error_code_));
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource_error.h b/third_party/blink/renderer/platform/loader/fetch/resource_error.h
index ddcf2ba..4518d6c 100644
--- a/third_party/blink/renderer/platform/loader/fetch/resource_error.h
+++ b/third_party/blink/renderer/platform/loader/fetch/resource_error.h
@@ -99,7 +99,8 @@
bool IsTimeout() const;
bool IsCacheMiss() const;
bool WasBlockedByResponse() const;
- bool ShouldCollapseInitiator() const;
+ bool ShouldCollapseInitiator() const { return should_collapse_inititator_; }
+
base::Optional<ResourceRequestBlockedReason> GetResourceRequestBlockedReason()
const;
base::Optional<network::mojom::BlockedByResponseReason>
@@ -128,8 +129,8 @@
String localized_description_;
bool is_access_check_ = false;
bool has_copy_in_cache_ = false;
- bool blocked_by_subresource_filter_ = false;
base::Optional<network::CorsErrorStatus> cors_error_status_;
+ bool should_collapse_inititator_ = false;
base::Optional<network::mojom::BlockedByResponseReason>
blocked_by_response_reason_;
diff --git a/third_party/blink/renderer/platform/loader/fetch/url_loader/sync_load_context.cc b/third_party/blink/renderer/platform/loader/fetch/url_loader/sync_load_context.cc
index 4daeea0..7fdb866 100644
--- a/third_party/blink/renderer/platform/loader/fetch/url_loader/sync_load_context.cc
+++ b/third_party/blink/renderer/platform/loader/fetch/url_loader/sync_load_context.cc
@@ -248,6 +248,7 @@
response_->error_code = status.error_code;
response_->extended_error_code = status.extended_error_code;
response_->resolve_error_info = status.resolve_error_info;
+ response_->should_collapse_initiator = status.should_collapse_initiator;
response_->cors_error = status.cors_error_status;
response_->head->encoded_data_length = status.encoded_data_length;
response_->head->encoded_body_length = status.encoded_body_length;
diff --git a/third_party/blink/renderer/platform/loader/fetch/url_loader/sync_load_response.h b/third_party/blink/renderer/platform/loader/fetch/url_loader/sync_load_response.h
index 01203eb..825c0c93 100644
--- a/third_party/blink/renderer/platform/loader/fetch/url_loader/sync_load_response.h
+++ b/third_party/blink/renderer/platform/loader/fetch/url_loader/sync_load_response.h
@@ -36,6 +36,8 @@
// The response extended error code.
int extended_error_code = 0;
+ bool should_collapse_initiator = false;
+
// Detailed host resolution error information.
net::ResolveErrorInfo resolve_error_info;
diff --git a/third_party/blink/renderer/platform/loader/fetch/url_loader/web_url_loader.cc b/third_party/blink/renderer/platform/loader/fetch/url_loader/web_url_loader.cc
index aa0d194..d176a5a 100644
--- a/third_party/blink/renderer/platform/loader/fetch/url_loader/web_url_loader.cc
+++ b/third_party/blink/renderer/platform/loader/fetch/url_loader/web_url_loader.cc
@@ -936,7 +936,10 @@
return WebURLError(status.error_code, status.extended_error_code,
status.resolve_error_info, has_copy_in_cache,
- WebURLError::IsWebSecurityViolation::kFalse, url);
+ WebURLError::IsWebSecurityViolation::kFalse, url,
+ status.should_collapse_initiator
+ ? WebURLError::ShouldCollapseInitiator::kTrue
+ : WebURLError::ShouldCollapseInitiator::kFalse);
}
void WebURLLoader::LoadSynchronously(
@@ -989,7 +992,10 @@
error = WebURLError(error_code, sync_load_response.extended_error_code,
sync_load_response.resolve_error_info,
WebURLError::HasCopyInCache::kFalse,
- is_web_security_violation, final_url);
+ is_web_security_violation, final_url,
+ sync_load_response.should_collapse_initiator
+ ? WebURLError::ShouldCollapseInitiator::kTrue
+ : WebURLError::ShouldCollapseInitiator::kFalse);
}
return;
}
diff --git a/third_party/blink/web_tests/http/tests/inspector-protocol/network/cross-origin-isolation/coep-load-error-reporting-expected.txt b/third_party/blink/web_tests/http/tests/inspector-protocol/network/cross-origin-isolation/coep-load-error-reporting-expected.txt
index 727abcb..f18d431 100644
--- a/third_party/blink/web_tests/http/tests/inspector-protocol/network/cross-origin-isolation/coep-load-error-reporting-expected.txt
+++ b/third_party/blink/web_tests/http/tests/inspector-protocol/network/cross-origin-isolation/coep-load-error-reporting-expected.txt
@@ -4,9 +4,9 @@
https://devtools.oopif.test:8443/inspector-protocol/network/cross-origin-isolation/resources/page-with-coep-corp.php?coep&corp=same-origin: net::ERR_BLOCKED_BY_RESPONSE corp-not-same-origin
https://devtools.oopif.test:8443/inspector-protocol/network/cross-origin-isolation/resources/page-with-coep-corp.php?coep&corp=same-site: net::ERR_BLOCKED_BY_RESPONSE corp-not-same-site
https://devtools.oopif.test:8443/inspector-protocol/network/cross-origin-isolation/resources/page-with-coep-corp.php?coop: net::ERR_BLOCKED_BY_RESPONSE corp-not-same-origin-after-defaulted-to-same-origin-by-coep
-
https://devtools.oopif.test:8443/inspector-protocol/network/cross-origin-isolation/resources/page-with-coep-corp.php?script&: net::ERR_BLOCKED_BY_RESPONSE corp-not-same-origin-after-defaulted-to-same-origin-by-coep
+
https://devtools.oopif.test:8443/inspector-protocol/network/cross-origin-isolation/resources/page-with-coep-corp.php?script&: net::ERR_BLOCKED_BY_RESPONSE.NotSameOriginAfterDefaultedToSameOriginByCoep corp-not-same-origin-after-defaulted-to-same-origin-by-coep
https://devtools.oopif.test:8443/inspector-protocol/network/cross-origin-isolation/resources/page-with-coep-corp.php?script&corp=cross-origin: *loading finished*
-
https://devtools.oopif.test:8443/inspector-protocol/network/cross-origin-isolation/resources/page-with-coep-corp.php?script&corp=same-origin: net::ERR_BLOCKED_BY_RESPONSE corp-not-same-origin
-
https://devtools.oopif.test:8443/inspector-protocol/network/cross-origin-isolation/resources/page-with-coep-corp.php?script&corp=same-site: net::ERR_BLOCKED_BY_RESPONSE corp-not-same-site
+
https://devtools.oopif.test:8443/inspector-protocol/network/cross-origin-isolation/resources/page-with-coep-corp.php?script&corp=same-origin: net::ERR_BLOCKED_BY_RESPONSE.NotSameOrigin corp-not-same-origin
+
https://devtools.oopif.test:8443/inspector-protocol/network/cross-origin-isolation/resources/page-with-coep-corp.php?script&corp=same-site: net::ERR_BLOCKED_BY_RESPONSE.NotSameSite corp-not-same-site
https://devtools.test:8443/inspector-protocol/network/cross-origin-isolation/resources/coep-page-with-resources.php: *loading finished*