summaryrefslogtreecommitdiffstats
path: root/chromium/chrome/browser/extensions/api/declarative_net_request
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/chrome/browser/extensions/api/declarative_net_request')
-rw-r--r--chromium/chrome/browser/extensions/api/declarative_net_request/declarative_net_request_browsertest.cc214
-rw-r--r--chromium/chrome/browser/extensions/api/declarative_net_request/ruleset_manager_unittest.cc284
2 files changed, 414 insertions, 84 deletions
diff --git a/chromium/chrome/browser/extensions/api/declarative_net_request/declarative_net_request_browsertest.cc b/chromium/chrome/browser/extensions/api/declarative_net_request/declarative_net_request_browsertest.cc
index e704227958c..7ebbb0567b3 100644
--- a/chromium/chrome/browser/extensions/api/declarative_net_request/declarative_net_request_browsertest.cc
+++ b/chromium/chrome/browser/extensions/api/declarative_net_request/declarative_net_request_browsertest.cc
@@ -2798,6 +2798,110 @@ IN_PROC_BROWSER_TEST_P(DeclarativeNetRequestBrowserTest,
EXPECT_EQ(first_tab_badge_text, action->GetDisplayBadgeText(first_tab_id));
}
+// Ensure web request events are still dispatched even if DNR blocks/redirects
+// the request. (Regression test for crbug.com/999744).
+IN_PROC_BROWSER_TEST_P(DeclarativeNetRequestBrowserTest, WebRequestEvents) {
+ // Load the extension with a background script so scripts can be run from its
+ // generated background page.
+ set_has_background_script(true);
+
+ TestRule rule = CreateGenericRule();
+ rule.condition->url_filter = "||example.com";
+ rule.condition->resource_types = std::vector<std::string>({"main_frame"});
+ ASSERT_NO_FATAL_FAILURE(LoadExtensionWithRules(
+ {rule}, "test_extension", {URLPattern::kAllUrlsPattern}));
+
+ GURL url = embedded_test_server()->GetURL("example.com",
+ "/pages_with_script/index.html");
+
+ // Set up web request listeners listening to request to |url|.
+ const char kWebRequestListenerScript[] = R"(
+ let filter = {'urls' : ['%s'], 'types' : ['main_frame']};
+
+ let onBeforeRequestSeen = false;
+ chrome.webRequest.onBeforeRequest.addListener(() => {
+ onBeforeRequestSeen = true;
+ }, filter);
+
+ // The request will fail since it will be blocked by DNR.
+ chrome.webRequest.onErrorOccurred.addListener(() => {
+ if (onBeforeRequestSeen)
+ chrome.test.sendMessage('PASS');
+ }, filter);
+
+ chrome.test.sendMessage('INSTALLED');
+ )";
+
+ ExtensionTestMessageListener pass_listener("PASS", false /* will_reply */);
+ ExtensionTestMessageListener installed_listener("INSTALLED",
+ false /* will_reply */);
+ ExecuteScriptInBackgroundPageNoWait(
+ last_loaded_extension_id(),
+ base::StringPrintf(kWebRequestListenerScript, url.spec().c_str()));
+
+ // Wait for the web request listeners to be installed before navigating.
+ ASSERT_TRUE(installed_listener.WaitUntilSatisfied());
+
+ ui_test_utils::NavigateToURL(browser(), url);
+
+ ASSERT_FALSE(WasFrameWithScriptLoaded(GetMainFrame()));
+ EXPECT_TRUE(pass_listener.WaitUntilSatisfied());
+}
+
+// Ensure Declarative Net Request gets priority over the web request API.
+IN_PROC_BROWSER_TEST_P(DeclarativeNetRequestBrowserTest, WebRequestPriority) {
+ // Load the extension with a background script so scripts can be run from its
+ // generated background page.
+ set_has_background_script(true);
+
+ GURL url = embedded_test_server()->GetURL("example.com",
+ "/pages_with_script/index.html");
+ GURL redirect_url = embedded_test_server()->GetURL(
+ "redirect.com", "/pages_with_script/index.html");
+
+ TestRule example_com_redirect_rule = CreateGenericRule();
+ example_com_redirect_rule.condition->url_filter = "||example.com";
+ example_com_redirect_rule.condition->resource_types =
+ std::vector<std::string>({"main_frame"});
+ example_com_redirect_rule.action->type = std::string("redirect");
+ example_com_redirect_rule.action->redirect.emplace();
+ example_com_redirect_rule.action->redirect->url = redirect_url.spec();
+ example_com_redirect_rule.priority = kMinValidPriority;
+
+ ASSERT_NO_FATAL_FAILURE(
+ LoadExtensionWithRules({example_com_redirect_rule}, "test_extension",
+ {URLPattern::kAllUrlsPattern}));
+
+ // Set up a web request listener to block the request to example.com.
+ const char kWebRequestBlockScript[] = R"(
+ let filter = {'urls' : ['%s'], 'types' : ['main_frame']};
+ chrome.webRequest.onBeforeRequest.addListener((details) => {
+ chrome.test.sendMessage('SEEN')
+ }, filter, ['blocking']);
+ chrome.test.sendMessage('INSTALLED');
+ )";
+
+ ExtensionTestMessageListener seen_listener("SEEN", false /* will_reply */);
+ ExtensionTestMessageListener installed_listener("INSTALLED",
+ false /* will_reply */);
+ ExecuteScriptInBackgroundPageNoWait(
+ last_loaded_extension_id(),
+ base::StringPrintf(kWebRequestBlockScript, url.spec().c_str()));
+
+ // Wait for the web request listeners to be installed before navigating.
+ ASSERT_TRUE(installed_listener.WaitUntilSatisfied());
+
+ ui_test_utils::NavigateToURL(browser(), url);
+
+ // Ensure the response from the web request listener was ignored and the
+ // request was redirected.
+ ASSERT_TRUE(WasFrameWithScriptLoaded(GetMainFrame()));
+ EXPECT_EQ(web_contents()->GetLastCommittedURL(), redirect_url);
+
+ // Ensure onBeforeRequest is seen by the web request extension.
+ EXPECT_TRUE(seen_listener.WaitUntilSatisfied());
+}
+
// Test that the extension cannot retrieve the number of actions matched
// from the badge text by calling chrome.browserAction.getBadgeText.
IN_PROC_BROWSER_TEST_P(DeclarativeNetRequestBrowserTest,
@@ -3046,6 +3150,116 @@ IN_PROC_BROWSER_TEST_P(DeclarativeNetRequestBrowserTest,
}
}
+// Test that the badge text for extensions will update correctly for
+// removeHeader rules.
+IN_PROC_BROWSER_TEST_P(DeclarativeNetRequestBrowserTest,
+ RemoveHeadersBadgeText) {
+ auto referer_url = embedded_test_server()->GetURL(
+ "example.com", "/set-header?referer: none");
+ auto set_cookie_url =
+ embedded_test_server()->GetURL("example.com", "/set-cookie?a=b");
+
+ // Navigates frame with name |frame_name| to |url|.
+ auto navigate_frame = [this](const std::string& frame_name, const GURL& url,
+ bool use_frame_referrer) {
+ content::TestNavigationObserver navigation_observer(
+ web_contents(), 1 /*number_of_navigations*/);
+
+ const char* referrer_policy = use_frame_referrer ? "origin" : "no-referrer";
+
+ ASSERT_TRUE(content::ExecuteScript(
+ GetMainFrame(),
+ base::StringPrintf(R"(
+ document.getElementsByName('%s')[0].referrerPolicy = '%s';
+ document.getElementsByName('%s')[0].src = '%s';)",
+ frame_name.c_str(), referrer_policy,
+ frame_name.c_str(), url.spec().c_str())));
+ navigation_observer.Wait();
+ };
+
+ const std::string kFrameName1 = "frame1";
+ const GURL page_url = embedded_test_server()->GetURL(
+ "nomatch.com", "/page_with_two_frames.html");
+
+ // Create an extension with a rule to remove the Set-Cookie header, and get
+ // the ExtensionAction for it.
+ TestRule rule1 = CreateGenericRule();
+ rule1.id = kMinValidID;
+ rule1.condition->url_filter = "example.com";
+ rule1.condition->resource_types = std::vector<std::string>({"sub_frame"});
+ rule1.action->type = "removeHeaders";
+ rule1.action->remove_headers_list = std::vector<std::string>({"setCookie"});
+
+ ASSERT_NO_FATAL_FAILURE(LoadExtensionWithRules({rule1}, "extension_1", {}));
+
+ const ExtensionId remove_set_cookie_ext_id = last_loaded_extension_id();
+ ExtensionPrefs::Get(profile())->SetDNRUseActionCountAsBadgeText(
+ remove_set_cookie_ext_id, true);
+
+ ExtensionAction* remove_set_cookie_action =
+ ExtensionActionManager::Get(web_contents()->GetBrowserContext())
+ ->GetExtensionAction(*extension_registry()->GetExtensionById(
+ remove_set_cookie_ext_id,
+ extensions::ExtensionRegistry::ENABLED));
+
+ // Create an extension with a rule to remove the referer header, and get the
+ // ExtensionAction for it.
+ TestRule rule2 = CreateGenericRule();
+ rule2.id = kMinValidID;
+ rule2.condition->url_filter = "example.com";
+ rule2.condition->resource_types = std::vector<std::string>({"sub_frame"});
+ rule2.action->type = "removeHeaders";
+ rule2.action->remove_headers_list = std::vector<std::string>({"referer"});
+
+ ASSERT_NO_FATAL_FAILURE(LoadExtensionWithRules({rule2}, "extension_2", {}));
+
+ const ExtensionId remove_referer_ext_id = last_loaded_extension_id();
+ ExtensionPrefs::Get(profile())->SetDNRUseActionCountAsBadgeText(
+ remove_referer_ext_id, true);
+
+ ExtensionAction* remove_referer_action =
+ ExtensionActionManager::Get(web_contents()->GetBrowserContext())
+ ->GetExtensionAction(*extension_registry()->GetExtensionById(
+ remove_referer_ext_id, extensions::ExtensionRegistry::ENABLED));
+
+ struct {
+ GURL url;
+ bool use_referrer;
+ std::string expected_remove_referer_badge_text;
+ std::string expected_remove_set_cookie_badge_text;
+ } test_cases[] = {
+ // This request only has a Set-Cookie header. Only the badge text for the
+ // extension with a remove Set-Cookie header rule should be incremented.
+ {set_cookie_url, false, "0", "1"},
+ // This request only has a Referer header. Only the badge text for the
+ // extension with a remove Referer header rule should be incremented.
+ {referer_url, true, "1", "1"},
+ // This request has both a Referer and a Set-Cookie header. The badge text
+ // for both extensions should be incremented.
+ {set_cookie_url, true, "2", "2"},
+ };
+
+ ui_test_utils::NavigateToURL(browser(), page_url);
+ ASSERT_TRUE(WasFrameWithScriptLoaded(GetMainFrame()));
+
+ int first_tab_id = ExtensionTabUtil::GetTabId(web_contents());
+ EXPECT_EQ("0", remove_set_cookie_action->GetDisplayBadgeText(first_tab_id));
+ EXPECT_EQ("0", remove_referer_action->GetDisplayBadgeText(first_tab_id));
+
+ for (const auto& test_case : test_cases) {
+ SCOPED_TRACE(base::StringPrintf("Testing URL: %s, using referrer: %s",
+ test_case.url.spec().c_str(),
+ test_case.use_referrer ? "true" : "false"));
+
+ navigate_frame(kFrameName1, test_case.url, test_case.use_referrer);
+ EXPECT_EQ(test_case.expected_remove_set_cookie_badge_text,
+ remove_set_cookie_action->GetDisplayBadgeText(first_tab_id));
+
+ EXPECT_EQ(test_case.expected_remove_referer_badge_text,
+ remove_referer_action->GetDisplayBadgeText(first_tab_id));
+ }
+}
+
// Test fixture to verify that host permissions for the request url and the
// request initiator are properly checked when redirecting requests. Loads an
// example.com url with four sub-frames named frame_[1..4] from hosts
diff --git a/chromium/chrome/browser/extensions/api/declarative_net_request/ruleset_manager_unittest.cc b/chromium/chrome/browser/extensions/api/declarative_net_request/ruleset_manager_unittest.cc
index 808d1b52973..1251a3a2281 100644
--- a/chromium/chrome/browser/extensions/api/declarative_net_request/ruleset_manager_unittest.cc
+++ b/chromium/chrome/browser/extensions/api/declarative_net_request/ruleset_manager_unittest.cc
@@ -15,6 +15,7 @@
#include "chrome/browser/extensions/chrome_test_extension_loader.h"
#include "chrome/browser/extensions/extension_util.h"
#include "extensions/browser/api/declarative_net_request/composite_matcher.h"
+#include "extensions/browser/api/declarative_net_request/request_action.h"
#include "extensions/browser/api/declarative_net_request/ruleset_matcher.h"
#include "extensions/browser/api/declarative_net_request/ruleset_source.h"
#include "extensions/browser/api/declarative_net_request/test_utils.h"
@@ -28,6 +29,7 @@
#include "extensions/common/file_util.h"
#include "extensions/common/manifest_handlers/background_info.h"
#include "extensions/common/url_pattern.h"
+#include "net/http/http_util.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "url/gurl.h"
#include "url/origin.h"
@@ -37,8 +39,7 @@ namespace declarative_net_request {
// Note: This is not declared in the anonymous namespace so that we can use it
// with gtest.
-bool operator==(const RulesetManager::Action& lhs,
- const RulesetManager::Action& rhs) {
+bool operator==(const RequestAction& lhs, const RequestAction& rhs) {
static_assert(flat::ActionIndex_count == 7,
"Modify this method to ensure it stays updated as new actions "
"are added.");
@@ -72,8 +73,7 @@ class RulesetManagerTest : public DNRTestBase {
}
protected:
- using Action = RulesetManager::Action;
- using ActionType = Action::Type;
+ using RequestActionType = RequestAction::Type;
// Helper to create a composite matcher instance for the given |rules|.
void CreateMatcherForRules(
@@ -133,6 +133,24 @@ class RulesetManagerTest : public DNRTestBase {
return info;
}
+ // Returns renderer-initiated request params for the given |url| and
+ // |request_headers| request headers.
+ WebRequestInfoInitParams GetRequestParamsForURLWithHeaders(
+ base::StringPiece url,
+ const std::vector<std::string>& request_headers) {
+ const int kRendererId = 1;
+ WebRequestInfoInitParams info;
+ info.url = GURL(url);
+ info.render_process_id = kRendererId;
+
+ net::HttpRequestHeaders extra_request_headers;
+ for (const auto& header : request_headers)
+ extra_request_headers.SetHeaderIfMissing(header, "foo");
+
+ info.extra_request_headers = extra_request_headers;
+ return info;
+ }
+
RulesetManager* manager() { return manager_.get(); }
private:
@@ -156,9 +174,10 @@ TEST_P(RulesetManagerTest, MultipleRulesets) {
rule_two.condition->url_filter = std::string("two.com");
auto should_block_request = [this](const WebRequestInfo& request) {
- return manager()->EvaluateRequest(request,
- false /*is_incognito_context*/) ==
- Action(ActionType::BLOCK);
+ manager()->EvaluateRequest(request, false /*is_incognito_context*/);
+ return !request.dnr_actions->empty() &&
+ ((*request.dnr_actions)[0] ==
+ RequestAction(RequestActionType::BLOCK));
};
for (int mask = 0; mask < 4; mask++) {
@@ -228,28 +247,34 @@ TEST_P(RulesetManagerTest, IncognitoRequests) {
// incognito contexts should not be evaluated.
EXPECT_FALSE(util::IsIncognitoEnabled(last_loaded_extension()->id(),
browser_context()));
- EXPECT_EQ(
- Action(ActionType::NONE),
- manager()->EvaluateRequest(request_info, true /*is_incognito_context*/));
- request_info.dnr_action.reset();
- EXPECT_EQ(
- Action(ActionType::BLOCK),
- manager()->EvaluateRequest(request_info, false /*is_incognito_context*/));
- request_info.dnr_action.reset();
+
+ manager()->EvaluateRequest(request_info, true /*is_incognito_context*/);
+ EXPECT_TRUE(request_info.dnr_actions->empty());
+ request_info.dnr_actions.reset();
+
+ manager()->EvaluateRequest(request_info, false /*is_incognito_context*/);
+ ASSERT_EQ(1u, request_info.dnr_actions->size());
+ EXPECT_EQ(RequestAction(RequestActionType::BLOCK),
+ (*request_info.dnr_actions)[0]);
+ request_info.dnr_actions.reset();
// Enabling the extension in incognito mode, should cause requests from
// incognito contexts to also be evaluated.
SetIncognitoEnabled(last_loaded_extension(), true /*incognito_enabled*/);
EXPECT_TRUE(util::IsIncognitoEnabled(last_loaded_extension()->id(),
browser_context()));
- EXPECT_EQ(
- Action(ActionType::BLOCK),
- manager()->EvaluateRequest(request_info, true /*is_incognito_context*/));
- request_info.dnr_action.reset();
- EXPECT_EQ(
- Action(ActionType::BLOCK),
- manager()->EvaluateRequest(request_info, false /*is_incognito_context*/));
- request_info.dnr_action.reset();
+
+ manager()->EvaluateRequest(request_info, true /*is_incognito_context*/);
+ ASSERT_EQ(1u, request_info.dnr_actions->size());
+ EXPECT_EQ(RequestAction(RequestActionType::BLOCK),
+ (*request_info.dnr_actions)[0]);
+ request_info.dnr_actions.reset();
+
+ manager()->EvaluateRequest(request_info, false /*is_incognito_context*/);
+ ASSERT_EQ(1u, request_info.dnr_actions->size());
+ EXPECT_EQ(RequestAction(RequestActionType::BLOCK),
+ (*request_info.dnr_actions)[0]);
+ request_info.dnr_actions.reset();
}
// Tests that
@@ -265,15 +290,16 @@ TEST_P(RulesetManagerTest, TotalEvaluationTimeHistogram) {
"Extensions.DeclarativeNetRequest.EvaluateRequestTime.AllExtensions2";
{
base::HistogramTester tester;
- EXPECT_EQ(
- Action(ActionType::NONE),
- manager()->EvaluateRequest(example_com_request, is_incognito_context));
- EXPECT_EQ(
- Action(ActionType::NONE),
- manager()->EvaluateRequest(google_com_request, is_incognito_context));
+
+ manager()->EvaluateRequest(example_com_request, is_incognito_context);
+ EXPECT_TRUE(example_com_request.dnr_actions->empty());
+
+ manager()->EvaluateRequest(google_com_request, is_incognito_context);
+ EXPECT_TRUE(google_com_request.dnr_actions->empty());
+
tester.ExpectTotalCount(kHistogramName, 0);
- example_com_request.dnr_action.reset();
- google_com_request.dnr_action.reset();
+ example_com_request.dnr_actions.reset();
+ google_com_request.dnr_actions.reset();
}
// Add an extension ruleset which blocks requests to "example.com".
@@ -287,16 +313,20 @@ TEST_P(RulesetManagerTest, TotalEvaluationTimeHistogram) {
{
base::HistogramTester tester;
- EXPECT_EQ(
- Action(ActionType::BLOCK),
- manager()->EvaluateRequest(example_com_request, is_incognito_context));
+
+ manager()->EvaluateRequest(example_com_request, is_incognito_context);
+ ASSERT_EQ(1u, example_com_request.dnr_actions->size());
+ EXPECT_EQ(RequestAction(RequestActionType::BLOCK),
+ (*example_com_request.dnr_actions)[0]);
+
tester.ExpectTotalCount(kHistogramName, 1);
- EXPECT_EQ(
- Action(ActionType::NONE),
- manager()->EvaluateRequest(google_com_request, is_incognito_context));
+
+ manager()->EvaluateRequest(google_com_request, is_incognito_context);
+ EXPECT_TRUE(google_com_request.dnr_actions->empty());
+
tester.ExpectTotalCount(kHistogramName, 2);
- example_com_request.dnr_action.reset();
- google_com_request.dnr_action.reset();
+ example_com_request.dnr_actions.reset();
+ google_com_request.dnr_actions.reset();
}
}
@@ -320,31 +350,33 @@ TEST_P(RulesetManagerTest, Redirect) {
// redirected to "google.com".
const bool is_incognito_context = false;
const char* kExampleURL = "http://example.com";
- Action expected_redirect_action(ActionType::REDIRECT);
+ RequestAction expected_redirect_action(RequestActionType::REDIRECT);
expected_redirect_action.redirect_url = GURL("http://google.com");
WebRequestInfo request_1(GetRequestParamsForURL(kExampleURL, base::nullopt));
- EXPECT_EQ(expected_redirect_action,
- manager()->EvaluateRequest(request_1, is_incognito_context));
+ manager()->EvaluateRequest(request_1, is_incognito_context);
+ ASSERT_EQ(1u, request_1.dnr_actions->size());
+ EXPECT_EQ(expected_redirect_action, (*request_1.dnr_actions)[0]);
// Change the initiator to "xyz.com". It should not be redirected since we
// don't have host permissions to the request initiator.
WebRequestInfo request_2(GetRequestParamsForURL(
kExampleURL, url::Origin::Create(GURL("http://xyz.com"))));
- EXPECT_EQ(Action(ActionType::NONE),
- manager()->EvaluateRequest(request_2, is_incognito_context));
+ manager()->EvaluateRequest(request_2, is_incognito_context);
+ EXPECT_TRUE(request_2.dnr_actions->empty());
// Change the initiator to "abc.com". It should be redirected since we have
// the required host permissions.
WebRequestInfo request_3(GetRequestParamsForURL(
kExampleURL, url::Origin::Create(GURL("http://abc.com"))));
- EXPECT_EQ(expected_redirect_action,
- manager()->EvaluateRequest(request_3, is_incognito_context));
+ manager()->EvaluateRequest(request_3, is_incognito_context);
+ ASSERT_EQ(1u, request_3.dnr_actions->size());
+ EXPECT_EQ(expected_redirect_action, (*request_3.dnr_actions)[0]);
// Ensure web-socket requests are not redirected.
WebRequestInfo request_4(
GetRequestParamsForURL("ws://example.com", base::nullopt));
- EXPECT_EQ(Action(ActionType::NONE),
- manager()->EvaluateRequest(request_4, is_incognito_context));
+ manager()->EvaluateRequest(request_4, is_incognito_context);
+ EXPECT_TRUE(request_4.dnr_actions->empty());
}
// Tests that an extension can't block or redirect resources on the chrome-
@@ -390,9 +422,10 @@ TEST_P(RulesetManagerTest, ExtensionScheme) {
// Ensure that "http://example.com" will be blocked (with blocking taking
// priority over redirection).
WebRequestInfo request_1(GetRequestParamsForURL("http://example.com"));
- EXPECT_EQ(
- Action(ActionType::BLOCK),
- manager()->EvaluateRequest(request_1, false /*is_incognito_context*/));
+ manager()->EvaluateRequest(request_1, false /*is_incognito_context*/);
+ ASSERT_EQ(1u, request_1.dnr_actions->size());
+ EXPECT_EQ(RequestAction(RequestActionType::BLOCK),
+ (*request_1.dnr_actions)[0]);
// Ensure that the background page for |extension_1| won't be blocked or
// redirected.
@@ -400,9 +433,8 @@ TEST_P(RulesetManagerTest, ExtensionScheme) {
EXPECT_TRUE(!background_page_url_1.is_empty());
WebRequestInfo request_2(
GetRequestParamsForURL(background_page_url_1.spec()));
- EXPECT_EQ(
- Action(ActionType::NONE),
- manager()->EvaluateRequest(request_2, false /*is_incognito_context*/));
+ manager()->EvaluateRequest(request_2, false /*is_incognito_context*/);
+ EXPECT_TRUE(request_2.dnr_actions->empty());
// Ensure that the background page for |extension_2| won't be blocked or
// redirected.
@@ -410,17 +442,89 @@ TEST_P(RulesetManagerTest, ExtensionScheme) {
EXPECT_TRUE(!background_page_url_2.is_empty());
WebRequestInfo request_3(
GetRequestParamsForURL(background_page_url_2.spec()));
- EXPECT_EQ(
- Action(ActionType::NONE),
- manager()->EvaluateRequest(request_3, false /*is_incognito_context*/));
+ manager()->EvaluateRequest(request_3, false /*is_incognito_context*/);
+ EXPECT_TRUE(request_3.dnr_actions->empty());
// Also ensure that an arbitrary url on the chrome extension scheme is also
// not blocked or redirected.
WebRequestInfo request_4(GetRequestParamsForURL(base::StringPrintf(
"%s://%s/%s", kExtensionScheme, "extension_id", "path")));
- EXPECT_EQ(
- Action(ActionType::NONE),
- manager()->EvaluateRequest(request_4, false /*is_incognito_context*/));
+ manager()->EvaluateRequest(request_4, false /*is_incognito_context*/);
+ EXPECT_TRUE(request_4.dnr_actions->empty());
+}
+
+// Test that headers to be removed in removeHeaders rules are attributed to the
+// correct extension.
+TEST_P(RulesetManagerTest, RemoveHeaders) {
+ const Extension* extension_1 = nullptr;
+ const Extension* extension_2 = nullptr;
+ // Add an extension with a background page which removes the "cookie" and
+ // "setCookie" headers.
+ {
+ std::unique_ptr<CompositeMatcher> matcher;
+ TestRule rule = CreateGenericRule();
+ rule.condition->url_filter = std::string("*");
+ rule.action->type = std::string("removeHeaders");
+ rule.action->remove_headers_list =
+ std::vector<std::string>({"cookie", "setCookie"});
+
+ ASSERT_NO_FATAL_FAILURE(
+ CreateMatcherForRules({rule}, "test extension", &matcher));
+ extension_1 = last_loaded_extension();
+ manager()->AddRuleset(extension_1->id(), std::move(matcher),
+ URLPatternSet());
+ }
+
+ // Add another extension with a background page which removes the "cookie" and
+ // "referer" headers.
+ {
+ std::unique_ptr<CompositeMatcher> matcher;
+ TestRule rule = CreateGenericRule();
+ rule.condition->url_filter = std::string("*");
+ rule.action->type = std::string("removeHeaders");
+ rule.action->remove_headers_list =
+ std::vector<std::string>({"cookie", "referer"});
+
+ ASSERT_NO_FATAL_FAILURE(
+ CreateMatcherForRules({rule}, "test extension 2", &matcher));
+ extension_2 = last_loaded_extension();
+ manager()->AddRuleset(extension_2->id(), std::move(matcher),
+ URLPatternSet());
+ }
+
+ EXPECT_EQ(2u, manager()->GetMatcherCountForTest());
+
+ // Create a request with the "cookie" and "referer" request headers, and the
+ // "set-cookie" response header.
+ WebRequestInfo request_1(GetRequestParamsForURLWithHeaders(
+ "http://example.com", std::vector<std::string>({"cookie", "referer"})));
+ request_1.response_headers = base::MakeRefCounted<net::HttpResponseHeaders>(
+ net::HttpUtil::AssembleRawHeaders("HTTP/1.1 200 OK\r\n"
+ "Content-Type: text/plain; UTF-8\r\n"
+ "Set-Cookie: custom/value\r\n"));
+
+ const std::vector<RequestAction>& actual_actions =
+ manager()->EvaluateRequest(request_1, false /*is_incognito_context*/);
+ ASSERT_EQ(2u, actual_actions.size());
+
+ // Removal of the cookie header should be attributed to |extension_2| because
+ // it was installed later than |extension_1| and thus has more priority.
+ RequestAction expected_action_1(RequestActionType::REMOVE_HEADERS);
+ expected_action_1.request_headers_to_remove.push_back(
+ net::HttpRequestHeaders::kCookie);
+
+ // Removal of the referer header should be attributed to |extension_2|.
+ expected_action_1.request_headers_to_remove.push_back(
+ net::HttpRequestHeaders::kReferer);
+
+ RequestAction expected_action_2(RequestActionType::REMOVE_HEADERS);
+ expected_action_2.response_headers_to_remove.push_back("set-cookie");
+
+ EXPECT_EQ(expected_action_1, actual_actions[0]);
+ EXPECT_EQ(extension_2->id(), actual_actions[0].extension_id);
+
+ EXPECT_EQ(expected_action_2, actual_actions[1]);
+ EXPECT_EQ(extension_1->id(), actual_actions[1].extension_id);
}
TEST_P(RulesetManagerTest, PageAllowingAPI) {
@@ -571,12 +675,16 @@ TEST_P(RulesetManagerTest, PageAllowingAPI) {
frame_params.pending_main_frame_url);
}
- Action expected_action = test_case.expect_blocked_with_allowed_pages
- ? Action(ActionType::BLOCK)
- : Action(ActionType::NONE);
- EXPECT_EQ(expected_action,
- manager()->EvaluateRequest(WebRequestInfo(std::move(params)),
- false /*is_incognito_context*/));
+ WebRequestInfo request_info(std::move(params));
+ const std::vector<RequestAction>& actions = manager()->EvaluateRequest(
+ request_info, false /*is_incognito_context*/);
+
+ if (test_case.expect_blocked_with_allowed_pages) {
+ ASSERT_EQ(1u, actions.size());
+ EXPECT_EQ(RequestAction(RequestActionType::BLOCK), actions[0]);
+ } else {
+ EXPECT_TRUE(actions.empty());
+ }
}
}
@@ -618,30 +726,28 @@ TEST_P(RulesetManagerTest, HostPermissionForInitiator) {
struct TestCase {
std::string url;
base::Optional<url::Origin> initiator;
- ActionType expected_action_redirect_extension;
- ActionType expected_action_blocking_extension;
+ bool expected_action_redirect_extension;
+ bool expected_action_blocking_extension;
} cases[] = {
// Empty initiator. Has access.
- {"https://example.com", base::nullopt, ActionType::REDIRECT,
- ActionType::BLOCK},
+ {"https://example.com", base::nullopt, true, true},
// Opaque origin as initiator. Has access.
- {"https://example.com", url::Origin(), ActionType::REDIRECT,
- ActionType::BLOCK},
+ {"https://example.com", url::Origin(), true, true},
// yahoo.com as initiator. Has access.
{"https://example.com", url::Origin::Create(GURL("http://yahoo.com")),
- ActionType::REDIRECT, ActionType::BLOCK},
+ true, true},
// No matching rule.
{"https://yahoo.com", url::Origin::Create(GURL("http://example.com")),
- ActionType::NONE, ActionType::NONE},
+ false, false},
// Doesn't have access to initiator. But blocking a request doesn't
// require host permissions.
{"https://example.com", url::Origin::Create(GURL("http://google.com")),
- ActionType::NONE, ActionType::BLOCK},
+ false, true},
};
auto verify_test_case = [this](const std::string& url,
const base::Optional<url::Origin>& initiator,
- const Action& expected_action) {
+ RequestAction* expected_action) {
SCOPED_TRACE(base::StringPrintf(
"Url-%s initiator-%s", url.c_str(),
initiator ? initiator->Serialize().c_str() : "empty"));
@@ -649,8 +755,14 @@ TEST_P(RulesetManagerTest, HostPermissionForInitiator) {
WebRequestInfo request(GetRequestParamsForURL(url, initiator));
bool is_incognito_context = false;
- EXPECT_EQ(expected_action,
- manager()->EvaluateRequest(request, is_incognito_context));
+ manager()->EvaluateRequest(request, is_incognito_context);
+
+ if (expected_action) {
+ ASSERT_EQ(1u, request.dnr_actions->size());
+ EXPECT_EQ(*expected_action, (*request.dnr_actions)[0]);
+ } else {
+ EXPECT_TRUE(request.dnr_actions->empty());
+ }
};
// Test redirect extension.
@@ -659,11 +771,12 @@ TEST_P(RulesetManagerTest, HostPermissionForInitiator) {
manager()->AddRuleset(redirect_extension_id, std::move(redirect_matcher),
URLPatternSet());
for (const auto& test : cases) {
- Action expected_action(test.expected_action_redirect_extension);
- if (test.expected_action_redirect_extension == ActionType::REDIRECT)
- expected_action.redirect_url = GURL("https://foo.com/");
+ RequestAction redirect_action(RequestActionType::REDIRECT);
+ redirect_action.redirect_url = GURL("https://foo.com/");
- verify_test_case(test.url, test.initiator, expected_action);
+ verify_test_case(
+ test.url, test.initiator,
+ test.expected_action_redirect_extension ? &redirect_action : nullptr);
}
manager()->RemoveRuleset(redirect_extension_id);
}
@@ -674,8 +787,11 @@ TEST_P(RulesetManagerTest, HostPermissionForInitiator) {
manager()->AddRuleset(blocking_extension_id, std::move(blocking_matcher),
URLPatternSet());
for (const auto& test : cases) {
- verify_test_case(test.url, test.initiator,
- Action(test.expected_action_blocking_extension));
+ RequestAction block_action(RequestActionType::BLOCK);
+
+ verify_test_case(
+ test.url, test.initiator,
+ test.expected_action_blocking_extension ? &block_action : nullptr);
}
manager()->RemoveRuleset(blocking_extension_id);
}