Commit 3a2a02a6 authored by Kevin Marshall's avatar Kevin Marshall Committed by Commit Bot

[fuchsia] Implement allow/deny enforcement in URLRequestRewriter.

Implements the UrlRequestAction FIDL API, which allows embedders to
specify requests to block based on the the requests' host and/or scheme.

* Fix issue where wildcards passed in "hosts_filter" are URL-escaped.
* Add "page_type" edge transition detection to TestNavigationListener.
* Report early navigation errors in NavigationControllerImpl.

Bug: 1054475
Change-Id: If4df4889f980c5a239719d09f039eee32efd1c1d
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2070103Reviewed-by: default avatarDaniel Cheng <dcheng@chromium.org>
Reviewed-by: default avatarFabrice de Gans-Riberi <fdegans@chromium.org>
Commit-Queue: Kevin Marshall <kmarshall@chromium.org>
Cr-Commit-Position: refs/heads/master@{#762033}
parent d3aa798b
...@@ -106,34 +106,51 @@ void TestNavigationListener::OnNavigationStateChanged( ...@@ -106,34 +106,51 @@ void TestNavigationListener::OnNavigationStateChanged(
current_state_.set_can_go_back(change.can_go_back()); current_state_.set_can_go_back(change.can_go_back());
if (change.has_can_go_forward()) if (change.has_can_go_forward())
current_state_.set_can_go_forward(change.can_go_forward()); current_state_.set_can_go_forward(change.can_go_forward());
if (change.has_is_main_document_loaded()) if (change.has_page_type())
current_state_.set_page_type(change.page_type());
if (change.has_is_main_document_loaded()) {
current_state_.set_is_main_document_loaded( current_state_.set_is_main_document_loaded(
change.is_main_document_loaded()); change.is_main_document_loaded());
}
if (VLOG_IS_ON(1)) { if (VLOG_IS_ON(1)) {
std::string state_string; std::string state_string;
state_string.reserve(100); state_string.reserve(100);
if (current_state_.has_url()) if (current_state_.has_url()) {
state_string.append( state_string.append(
base::StringPrintf(" url=%s ", current_state_.url().c_str())); base::StringPrintf(" url=%s ", current_state_.url().c_str()));
}
if (current_state_.has_title()) if (current_state_.has_title()) {
state_string.append( state_string.append(
base::StringPrintf(" title='%s' ", current_state_.title().c_str())); base::StringPrintf(" title='%s' ", current_state_.title().c_str()));
}
if (current_state_.has_can_go_back()) if (current_state_.has_can_go_back()) {
state_string.append( state_string.append(
base::StringPrintf(" can_go_back=%d ", current_state_.can_go_back())); base::StringPrintf(" can_go_back=%d ", current_state_.can_go_back()));
}
if (current_state_.has_can_go_forward()) if (current_state_.has_can_go_forward()) {
state_string.append(base::StringPrintf(" can_go_forward=%d ", state_string.append(base::StringPrintf(" can_go_forward=%d ",
current_state_.can_go_forward())); current_state_.can_go_forward()));
}
if (current_state_.has_page_type()) {
state_string.append(base::StringPrintf(
" page_type=%s ",
(current_state_.page_type() == fuchsia::web::PageType::NORMAL
? "NORMAL"
: "ERROR")));
}
if (current_state_.has_is_main_document_loaded()) if (current_state_.has_is_main_document_loaded()) {
state_string.append( state_string.append(
base::StringPrintf(" is_main_document_loaded=%d ", base::StringPrintf(" is_main_document_loaded=%d ",
current_state_.is_main_document_loaded())); current_state_.is_main_document_loaded()));
}
VLOG(1) << "Navigation state changed: " << state_string; VLOG(1) << "Navigation state changed: " << state_string;
} }
...@@ -175,6 +192,12 @@ bool TestNavigationListener::AllFieldsMatch( ...@@ -175,6 +192,12 @@ bool TestNavigationListener::AllFieldsMatch(
return false; return false;
} }
if (expected.has_page_type() &&
(!current_state_.has_page_type() ||
expected.page_type() != current_state_.page_type())) {
return false;
}
if (expected.has_is_main_document_loaded() && if (expected.has_is_main_document_loaded() &&
(!current_state_.has_is_main_document_loaded() || (!current_state_.has_is_main_document_loaded() ||
expected.is_main_document_loaded() != expected.is_main_document_loaded() !=
......
...@@ -1710,6 +1710,131 @@ IN_PROC_BROWSER_TEST_F(RequestMonitoringFrameImplBrowserTest, ExtraHeaders) { ...@@ -1710,6 +1710,131 @@ IN_PROC_BROWSER_TEST_F(RequestMonitoringFrameImplBrowserTest, ExtraHeaders) {
testing::Contains(testing::Key("X-2ExtraHeaders"))); testing::Contains(testing::Key("X-2ExtraHeaders")));
} }
// Tests that UrlRequestActions can be set up to deny requests to specific
// hosts.
IN_PROC_BROWSER_TEST_F(RequestMonitoringFrameImplBrowserTest,
UrlRequestRewriteDeny) {
fuchsia::web::FramePtr frame = CreateFrame();
fuchsia::web::UrlRequestRewriteRule rule;
rule.set_hosts_filter({"127.0.0.1"});
rule.set_action(fuchsia::web::UrlRequestAction::DENY);
std::vector<fuchsia::web::UrlRequestRewriteRule> rules;
rules.push_back(std::move(rule));
frame->SetUrlRequestRewriteRules(std::move(rules), []() {});
fuchsia::web::NavigationControllerPtr controller;
frame->GetNavigationController(controller.NewRequest());
// 127.0.0.1 should be blocked.
const GURL page_url(embedded_test_server()->GetURL(kPage4Path));
{
fuchsia::web::NavigationState error_state;
error_state.set_page_type(fuchsia::web::PageType::ERROR);
EXPECT_TRUE(cr_fuchsia::LoadUrlAndExpectResponse(
controller.get(), fuchsia::web::LoadUrlParams(), page_url.spec()));
navigation_listener_.RunUntilNavigationStateMatches(error_state);
}
// However, "localhost" is not blocked, so this request should be allowed.
{
GURL::Replacements replacements;
replacements.SetHostStr("localhost");
GURL page_url_localhost = page_url.ReplaceComponents(replacements);
EXPECT_TRUE(cr_fuchsia::LoadUrlAndExpectResponse(
controller.get(), fuchsia::web::LoadUrlParams(),
page_url_localhost.spec()));
navigation_listener_.RunUntilUrlEquals(page_url_localhost);
}
}
// Tests that a UrlRequestAction with no filter criteria will apply to all
// requests.
IN_PROC_BROWSER_TEST_F(RequestMonitoringFrameImplBrowserTest,
UrlRequestRewriteDenyAll) {
fuchsia::web::FramePtr frame = CreateFrame();
// No filter criteria are set, so everything is denied.
fuchsia::web::UrlRequestRewriteRule rule;
rule.set_action(fuchsia::web::UrlRequestAction::DENY);
std::vector<fuchsia::web::UrlRequestRewriteRule> rules;
rules.push_back(std::move(rule));
frame->SetUrlRequestRewriteRules(std::move(rules), []() {});
fuchsia::web::NavigationControllerPtr controller;
frame->GetNavigationController(controller.NewRequest());
// 127.0.0.1 should be blocked.
const GURL page_url(embedded_test_server()->GetURL(kPage4Path));
{
fuchsia::web::NavigationState error_state;
error_state.set_page_type(fuchsia::web::PageType::ERROR);
EXPECT_TRUE(cr_fuchsia::LoadUrlAndExpectResponse(
controller.get(), fuchsia::web::LoadUrlParams(), page_url.spec()));
navigation_listener_.RunUntilNavigationStateMatches(error_state);
}
// "localhost" should be blocked.
{
GURL::Replacements replacements;
replacements.SetHostStr("localhost");
GURL page_url_localhost = page_url.ReplaceComponents(replacements);
fuchsia::web::NavigationState error_state;
error_state.set_page_type(fuchsia::web::PageType::ERROR);
EXPECT_TRUE(cr_fuchsia::LoadUrlAndExpectResponse(
controller.get(), fuchsia::web::LoadUrlParams(), page_url.spec()));
navigation_listener_.RunUntilNavigationStateMatches(error_state);
EXPECT_TRUE(cr_fuchsia::LoadUrlAndExpectResponse(
controller.get(), fuchsia::web::LoadUrlParams(),
page_url_localhost.spec()));
navigation_listener_.RunUntilNavigationStateMatches(error_state);
}
}
// Tests that UrlRequestActions can be set up to only allow requests for a
// single host, while denying everything else.
IN_PROC_BROWSER_TEST_F(RequestMonitoringFrameImplBrowserTest,
UrlRequestRewriteSelectiveAllow) {
fuchsia::web::FramePtr frame = CreateFrame();
// Allow 127.0.0.1.
fuchsia::web::UrlRequestRewriteRule rule;
rule.set_hosts_filter({"127.0.0.1"});
rule.set_action(fuchsia::web::UrlRequestAction::ALLOW);
std::vector<fuchsia::web::UrlRequestRewriteRule> rules;
rules.push_back(std::move(rule));
// Deny everything else.
rule = {};
rule.set_action(fuchsia::web::UrlRequestAction::DENY);
rules.push_back(std::move(rule));
frame->SetUrlRequestRewriteRules(std::move(rules), []() {});
fuchsia::web::NavigationControllerPtr controller;
frame->GetNavigationController(controller.NewRequest());
// 127.0.0.1 should be allowed.
const GURL page_url(embedded_test_server()->GetURL(kPage4Path));
{
EXPECT_TRUE(cr_fuchsia::LoadUrlAndExpectResponse(
controller.get(), fuchsia::web::LoadUrlParams(), page_url.spec()));
navigation_listener_.RunUntilUrlEquals(page_url);
}
// "localhost" should be blocked.
{
GURL::Replacements replacements;
replacements.SetHostStr("localhost");
GURL page_url_localhost = page_url.ReplaceComponents(replacements);
fuchsia::web::NavigationState error_state;
error_state.set_page_type(fuchsia::web::PageType::ERROR);
EXPECT_TRUE(cr_fuchsia::LoadUrlAndExpectResponse(
controller.get(), fuchsia::web::LoadUrlParams(),
page_url_localhost.spec()));
navigation_listener_.RunUntilNavigationStateMatches(error_state);
}
}
// Tests the URLRequestRewrite API properly adds headers on every requests. // Tests the URLRequestRewrite API properly adds headers on every requests.
IN_PROC_BROWSER_TEST_F(RequestMonitoringFrameImplBrowserTest, IN_PROC_BROWSER_TEST_F(RequestMonitoringFrameImplBrowserTest,
UrlRequestRewriteAddHeaders) { UrlRequestRewriteAddHeaders) {
......
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#include "content/public/browser/web_contents.h" #include "content/public/browser/web_contents.h"
#include "content/public/common/was_activated_option.mojom.h" #include "content/public/common/was_activated_option.mojom.h"
#include "fuchsia/base/string_util.h" #include "fuchsia/base/string_util.h"
#include "net/base/net_errors.h"
#include "net/http/http_util.h" #include "net/http/http_util.h"
#include "ui/base/page_transition_types.h" #include "ui/base/page_transition_types.h"
...@@ -93,6 +94,12 @@ void NavigationControllerImpl::OnNavigationEntryChanged() { ...@@ -93,6 +94,12 @@ void NavigationControllerImpl::OnNavigationEntryChanged() {
UpdateNavigationStateFromNavigationEntry( UpdateNavigationStateFromNavigationEntry(
web_contents_->GetController().GetVisibleEntry(), web_contents_, web_contents_->GetController().GetVisibleEntry(), web_contents_,
&new_state); &new_state);
if (new_state.page_type() != fuchsia::web::PageType::ERROR &&
uncommitted_load_error_) {
// If there was a loading error which prevented the navigation entry from
// being committed, then reflect the error in |new_state|.
new_state.set_page_type(fuchsia::web::PageType::ERROR);
}
DiffNavigationEntries(previous_navigation_state_, new_state, DiffNavigationEntries(previous_navigation_state_, new_state,
&pending_navigation_event_); &pending_navigation_event_);
...@@ -237,6 +244,7 @@ void NavigationControllerImpl::DidFinishLoad( ...@@ -237,6 +244,7 @@ void NavigationControllerImpl::DidFinishLoad(
void NavigationControllerImpl::DidStartNavigation( void NavigationControllerImpl::DidStartNavigation(
content::NavigationHandle* navigation_handle) { content::NavigationHandle* navigation_handle) {
uncommitted_load_error_ = false;
if (!navigation_handle->IsInMainFrame() || if (!navigation_handle->IsInMainFrame() ||
navigation_handle->IsSameDocument()) { navigation_handle->IsSameDocument()) {
return; return;
...@@ -246,6 +254,13 @@ void NavigationControllerImpl::DidStartNavigation( ...@@ -246,6 +254,13 @@ void NavigationControllerImpl::DidStartNavigation(
OnNavigationEntryChanged(); OnNavigationEntryChanged();
} }
void NavigationControllerImpl::DidFinishNavigation(
content::NavigationHandle* navigation_handle) {
uncommitted_load_error_ = !navigation_handle->HasCommitted() &&
navigation_handle->GetNetErrorCode() != net::OK;
OnNavigationEntryChanged();
}
void DiffNavigationEntries(const fuchsia::web::NavigationState& old_entry, void DiffNavigationEntries(const fuchsia::web::NavigationState& old_entry,
const fuchsia::web::NavigationState& new_entry, const fuchsia::web::NavigationState& new_entry,
fuchsia::web::NavigationState* difference) { fuchsia::web::NavigationState* difference) {
......
...@@ -52,12 +52,12 @@ class NavigationControllerImpl : public fuchsia::web::NavigationController, ...@@ -52,12 +52,12 @@ class NavigationControllerImpl : public fuchsia::web::NavigationController,
void GetVisibleEntry(GetVisibleEntryCallback callback) final; void GetVisibleEntry(GetVisibleEntryCallback callback) final;
// content::WebContentsObserver implementation. // content::WebContentsObserver implementation.
void TitleWasSet(content::NavigationEntry*) override; void TitleWasSet(content::NavigationEntry*) final;
void DocumentAvailableInMainFrame() override; void DocumentAvailableInMainFrame() final;
void DidFinishLoad(content::RenderFrameHost* render_frame_host, void DidFinishLoad(content::RenderFrameHost* render_frame_host,
const GURL& validated_url) override; const GURL& validated_url) final;
void DidStartNavigation( void DidStartNavigation(content::NavigationHandle* navigation_handle) final;
content::NavigationHandle* navigation_handle) override; void DidFinishNavigation(content::NavigationHandle* navigation_handle) final;
content::WebContents* const web_contents_; content::WebContents* const web_contents_;
...@@ -73,6 +73,9 @@ class NavigationControllerImpl : public fuchsia::web::NavigationController, ...@@ -73,6 +73,9 @@ class NavigationControllerImpl : public fuchsia::web::NavigationController,
// True once the main document finishes loading. // True once the main document finishes loading.
bool is_main_document_loaded_ = false; bool is_main_document_loaded_ = false;
// True if navigation failed due to an error during page load.
bool uncommitted_load_error_ = false;
base::WeakPtrFactory<NavigationControllerImpl> weak_factory_; base::WeakPtrFactory<NavigationControllerImpl> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(NavigationControllerImpl); DISALLOW_COPY_AND_ASSIGN(NavigationControllerImpl);
......
...@@ -106,11 +106,18 @@ bool ValidateRules( ...@@ -106,11 +106,18 @@ bool ValidateRules(
} }
if (rule.has_schemes_filter() && rule.schemes_filter().empty()) if (rule.has_schemes_filter() && rule.schemes_filter().empty())
return false; return false;
if (!rule.has_rewrites())
return false; if (rule.has_rewrites()) {
for (const auto& rewrite : rule.rewrites()) { if (rule.has_action())
if (!ValidateRewrite(rewrite))
return false; return false;
for (const auto& rewrite : rule.rewrites()) {
if (!ValidateRewrite(rewrite))
return false;
}
} else if (!rule.has_action()) {
// No rewrites, no action = no point!
return false;
} }
} }
return true; return true;
...@@ -159,7 +166,7 @@ zx_status_t UrlRequestRewriteRulesManager::OnRulesUpdated( ...@@ -159,7 +166,7 @@ zx_status_t UrlRequestRewriteRulesManager::OnRulesUpdated(
base::AutoLock auto_lock(lock_); base::AutoLock auto_lock(lock_);
cached_rules_ = cached_rules_ =
base::MakeRefCounted<WebEngineURLLoaderThrottle::UrlRequestRewriteRules>( base::MakeRefCounted<WebEngineURLLoaderThrottle::UrlRequestRewriteRules>(
mojo::ConvertTo<std::vector<mojom::UrlRequestRewriteRulePtr>>( mojo::ConvertTo<std::vector<mojom::UrlRequestRulePtr>>(
std::move(rules))); std::move(rules)));
// Send the updated rules to the receivers. // Send the updated rules to the receivers.
......
...@@ -50,11 +50,11 @@ TEST_F(UrlRequestRewriteRulesManagerTest, ConvertAddHeader) { ...@@ -50,11 +50,11 @@ TEST_F(UrlRequestRewriteRulesManagerTest, ConvertAddHeader) {
ASSERT_EQ(cached_rules->data.size(), 1u); ASSERT_EQ(cached_rules->data.size(), 1u);
ASSERT_FALSE(cached_rules->data[0]->hosts_filter); ASSERT_FALSE(cached_rules->data[0]->hosts_filter);
ASSERT_FALSE(cached_rules->data[0]->schemes_filter); ASSERT_FALSE(cached_rules->data[0]->schemes_filter);
ASSERT_EQ(cached_rules->data[0]->rewrites.size(), 1u); ASSERT_EQ(cached_rules->data[0]->actions.size(), 1u);
ASSERT_TRUE(cached_rules->data[0]->rewrites[0]->is_add_headers()); ASSERT_TRUE(cached_rules->data[0]->actions[0]->is_add_headers());
const net::HttpRequestHeaders& headers = const net::HttpRequestHeaders& headers =
cached_rules->data[0]->rewrites[0]->get_add_headers()->headers; cached_rules->data[0]->actions[0]->get_add_headers()->headers;
ASSERT_EQ(headers.GetHeaderVector().size(), 1u); ASSERT_EQ(headers.GetHeaderVector().size(), 1u);
std::string value; std::string value;
...@@ -72,11 +72,11 @@ TEST_F(UrlRequestRewriteRulesManagerTest, ConvertRemoveHeader) { ...@@ -72,11 +72,11 @@ TEST_F(UrlRequestRewriteRulesManagerTest, ConvertRemoveHeader) {
ASSERT_EQ(cached_rules->data.size(), 1u); ASSERT_EQ(cached_rules->data.size(), 1u);
ASSERT_FALSE(cached_rules->data[0]->hosts_filter); ASSERT_FALSE(cached_rules->data[0]->hosts_filter);
ASSERT_FALSE(cached_rules->data[0]->schemes_filter); ASSERT_FALSE(cached_rules->data[0]->schemes_filter);
ASSERT_EQ(cached_rules->data[0]->rewrites.size(), 1u); ASSERT_EQ(cached_rules->data[0]->actions.size(), 1u);
ASSERT_TRUE(cached_rules->data[0]->rewrites[0]->is_remove_header()); ASSERT_TRUE(cached_rules->data[0]->actions[0]->is_remove_header());
const mojom::UrlRequestRewriteRemoveHeaderPtr& remove_header1 = const mojom::UrlRequestRewriteRemoveHeaderPtr& remove_header1 =
cached_rules->data[0]->rewrites[0]->get_remove_header(); cached_rules->data[0]->actions[0]->get_remove_header();
ASSERT_TRUE(remove_header1->query_pattern); ASSERT_TRUE(remove_header1->query_pattern);
ASSERT_EQ(remove_header1->query_pattern.value().compare("Test"), 0); ASSERT_EQ(remove_header1->query_pattern.value().compare("Test"), 0);
ASSERT_EQ(remove_header1->header_name.compare("Header"), 0); ASSERT_EQ(remove_header1->header_name.compare("Header"), 0);
...@@ -89,11 +89,11 @@ TEST_F(UrlRequestRewriteRulesManagerTest, ConvertRemoveHeader) { ...@@ -89,11 +89,11 @@ TEST_F(UrlRequestRewriteRulesManagerTest, ConvertRemoveHeader) {
ASSERT_EQ(cached_rules->data.size(), 1u); ASSERT_EQ(cached_rules->data.size(), 1u);
ASSERT_FALSE(cached_rules->data[0]->hosts_filter); ASSERT_FALSE(cached_rules->data[0]->hosts_filter);
ASSERT_FALSE(cached_rules->data[0]->schemes_filter); ASSERT_FALSE(cached_rules->data[0]->schemes_filter);
ASSERT_EQ(cached_rules->data[0]->rewrites.size(), 1u); ASSERT_EQ(cached_rules->data[0]->actions.size(), 1u);
ASSERT_TRUE(cached_rules->data[0]->rewrites[0]->is_remove_header()); ASSERT_TRUE(cached_rules->data[0]->actions[0]->is_remove_header());
const mojom::UrlRequestRewriteRemoveHeaderPtr& remove_header2 = const mojom::UrlRequestRewriteRemoveHeaderPtr& remove_header2 =
cached_rules->data[0]->rewrites[0]->get_remove_header(); cached_rules->data[0]->actions[0]->get_remove_header();
ASSERT_FALSE(remove_header2->query_pattern); ASSERT_FALSE(remove_header2->query_pattern);
ASSERT_EQ(remove_header2->header_name.compare("Header"), 0); ASSERT_EQ(remove_header2->header_name.compare("Header"), 0);
} }
...@@ -110,13 +110,12 @@ TEST_F(UrlRequestRewriteRulesManagerTest, ConvertSubstituteQueryPattern) { ...@@ -110,13 +110,12 @@ TEST_F(UrlRequestRewriteRulesManagerTest, ConvertSubstituteQueryPattern) {
ASSERT_EQ(cached_rules->data.size(), 1u); ASSERT_EQ(cached_rules->data.size(), 1u);
ASSERT_FALSE(cached_rules->data[0]->hosts_filter); ASSERT_FALSE(cached_rules->data[0]->hosts_filter);
ASSERT_FALSE(cached_rules->data[0]->schemes_filter); ASSERT_FALSE(cached_rules->data[0]->schemes_filter);
ASSERT_EQ(cached_rules->data[0]->rewrites.size(), 1u); ASSERT_EQ(cached_rules->data[0]->actions.size(), 1u);
ASSERT_TRUE( ASSERT_TRUE(cached_rules->data[0]->actions[0]->is_substitute_query_pattern());
cached_rules->data[0]->rewrites[0]->is_substitute_query_pattern());
const mojom::UrlRequestRewriteSubstituteQueryPatternPtr& const mojom::UrlRequestRewriteSubstituteQueryPatternPtr&
substitute_query_pattern = substitute_query_pattern =
cached_rules->data[0]->rewrites[0]->get_substitute_query_pattern(); cached_rules->data[0]->actions[0]->get_substitute_query_pattern();
ASSERT_EQ(substitute_query_pattern->pattern.compare("Pattern"), 0); ASSERT_EQ(substitute_query_pattern->pattern.compare("Pattern"), 0);
ASSERT_EQ(substitute_query_pattern->substitution.compare("Substitution"), 0); ASSERT_EQ(substitute_query_pattern->substitution.compare("Substitution"), 0);
} }
...@@ -132,11 +131,11 @@ TEST_F(UrlRequestRewriteRulesManagerTest, ConvertReplaceUrl) { ...@@ -132,11 +131,11 @@ TEST_F(UrlRequestRewriteRulesManagerTest, ConvertReplaceUrl) {
ASSERT_EQ(cached_rules->data.size(), 1u); ASSERT_EQ(cached_rules->data.size(), 1u);
ASSERT_FALSE(cached_rules->data[0]->hosts_filter); ASSERT_FALSE(cached_rules->data[0]->hosts_filter);
ASSERT_FALSE(cached_rules->data[0]->schemes_filter); ASSERT_FALSE(cached_rules->data[0]->schemes_filter);
ASSERT_EQ(cached_rules->data[0]->rewrites.size(), 1u); ASSERT_EQ(cached_rules->data[0]->actions.size(), 1u);
ASSERT_TRUE(cached_rules->data[0]->rewrites[0]->is_replace_url()); ASSERT_TRUE(cached_rules->data[0]->actions[0]->is_replace_url());
const mojom::UrlRequestRewriteReplaceUrlPtr& replace_url = const mojom::UrlRequestRewriteReplaceUrlPtr& replace_url =
cached_rules->data[0]->rewrites[0]->get_replace_url(); cached_rules->data[0]->actions[0]->get_replace_url();
ASSERT_EQ(replace_url->url_ends_with.compare("/something"), 0); ASSERT_EQ(replace_url->url_ends_with.compare("/something"), 0);
ASSERT_EQ(replace_url->new_url.spec().compare(url.spec()), 0); ASSERT_EQ(replace_url->new_url.spec().compare(url.spec()), 0);
} }
...@@ -210,10 +209,10 @@ TEST_F(UrlRequestRewriteRulesManagerTest, RuleRenewal) { ...@@ -210,10 +209,10 @@ TEST_F(UrlRequestRewriteRulesManagerTest, RuleRenewal) {
scoped_refptr<WebEngineURLLoaderThrottle::UrlRequestRewriteRules> scoped_refptr<WebEngineURLLoaderThrottle::UrlRequestRewriteRules>
cached_rules = url_request_rewrite_rules_manager_->GetCachedRules(); cached_rules = url_request_rewrite_rules_manager_->GetCachedRules();
ASSERT_EQ(cached_rules->data.size(), 1u); ASSERT_EQ(cached_rules->data.size(), 1u);
ASSERT_EQ(cached_rules->data[0]->rewrites.size(), 1u); ASSERT_EQ(cached_rules->data[0]->actions.size(), 1u);
ASSERT_TRUE(cached_rules->data[0]->rewrites[0]->is_add_headers()); ASSERT_TRUE(cached_rules->data[0]->actions[0]->is_add_headers());
ASSERT_TRUE( ASSERT_TRUE(
cached_rules->data[0]->rewrites[0]->get_add_headers()->headers.HasHeader( cached_rules->data[0]->actions[0]->get_add_headers()->headers.HasHeader(
"Test1")); "Test1"));
EXPECT_EQ(UpdateRulesFromRewrite( EXPECT_EQ(UpdateRulesFromRewrite(
...@@ -223,10 +222,10 @@ TEST_F(UrlRequestRewriteRulesManagerTest, RuleRenewal) { ...@@ -223,10 +222,10 @@ TEST_F(UrlRequestRewriteRulesManagerTest, RuleRenewal) {
// We should have the new rules. // We should have the new rules.
cached_rules = url_request_rewrite_rules_manager_->GetCachedRules(); cached_rules = url_request_rewrite_rules_manager_->GetCachedRules();
ASSERT_EQ(cached_rules->data.size(), 1u); ASSERT_EQ(cached_rules->data.size(), 1u);
ASSERT_EQ(cached_rules->data[0]->rewrites.size(), 1u); ASSERT_EQ(cached_rules->data[0]->actions.size(), 1u);
ASSERT_TRUE(cached_rules->data[0]->rewrites[0]->is_add_headers()); ASSERT_TRUE(cached_rules->data[0]->actions[0]->is_add_headers());
ASSERT_TRUE( ASSERT_TRUE(
cached_rules->data[0]->rewrites[0]->get_add_headers()->headers.HasHeader( cached_rules->data[0]->actions[0]->get_add_headers()->headers.HasHeader(
"Test2")); "Test2"));
} }
......
...@@ -79,21 +79,23 @@ void ApplyReplaceUrl(network::ResourceRequest* request, ...@@ -79,21 +79,23 @@ void ApplyReplaceUrl(network::ResourceRequest* request,
} }
void ApplyRewrite(network::ResourceRequest* request, void ApplyRewrite(network::ResourceRequest* request,
const mojom::UrlRequestRewritePtr& rewrite) { const mojom::UrlRequestActionPtr& rewrite) {
switch (rewrite->which()) { switch (rewrite->which()) {
case mojom::UrlRequestRewrite::Tag::ADD_HEADERS: case mojom::UrlRequestAction::Tag::ADD_HEADERS:
ApplyAddHeaders(request, rewrite->get_add_headers()); ApplyAddHeaders(request, rewrite->get_add_headers());
break; break;
case mojom::UrlRequestRewrite::Tag::REMOVE_HEADER: case mojom::UrlRequestAction::Tag::REMOVE_HEADER:
ApplyRemoveHeader(request, rewrite->get_remove_header()); ApplyRemoveHeader(request, rewrite->get_remove_header());
break; break;
case mojom::UrlRequestRewrite::Tag::SUBSTITUTE_QUERY_PATTERN: case mojom::UrlRequestAction::Tag::SUBSTITUTE_QUERY_PATTERN:
ApplySubstituteQueryPattern(request, ApplySubstituteQueryPattern(request,
rewrite->get_substitute_query_pattern()); rewrite->get_substitute_query_pattern());
break; break;
case mojom::UrlRequestRewrite::Tag::REPLACE_URL: case mojom::UrlRequestAction::Tag::REPLACE_URL:
ApplyReplaceUrl(request, rewrite->get_replace_url()); ApplyReplaceUrl(request, rewrite->get_replace_url());
break; break;
case mojom::UrlRequestAction::Tag::POLICY:
break;
} }
} }
...@@ -101,9 +103,6 @@ bool HostMatches(const base::StringPiece& url_host, ...@@ -101,9 +103,6 @@ bool HostMatches(const base::StringPiece& url_host,
const base::StringPiece& rule_host) { const base::StringPiece& rule_host) {
const base::StringPiece kWildcard("*."); const base::StringPiece kWildcard("*.");
if (base::StartsWith(rule_host, kWildcard, base::CompareCase::SENSITIVE)) { if (base::StartsWith(rule_host, kWildcard, base::CompareCase::SENSITIVE)) {
// |rule_host| starts with a wildcard (e.g. "*.test.xyz"). Check if
// |url_host| ends with ".test.xyz". The "." character is included here to
// prevent accidentally matching "notatest.xyz".
if (base::EndsWith(url_host, rule_host.substr(1), if (base::EndsWith(url_host, rule_host.substr(1),
base::CompareCase::SENSITIVE)) { base::CompareCase::SENSITIVE)) {
return true; return true;
...@@ -117,8 +116,10 @@ bool HostMatches(const base::StringPiece& url_host, ...@@ -117,8 +116,10 @@ bool HostMatches(const base::StringPiece& url_host,
return base::CompareCaseInsensitiveASCII(url_host, rule_host) == 0; return base::CompareCaseInsensitiveASCII(url_host, rule_host) == 0;
} }
void ApplyRule(network::ResourceRequest* request, // Returns true if the host and scheme filters defined in |rule| match
const mojom::UrlRequestRewriteRulePtr& rule) { // |request|.
bool RuleFiltersMatchRequest(network::ResourceRequest* request,
const mojom::UrlRequestRulePtr& rule) {
const GURL& url = request->url; const GURL& url = request->url;
if (rule->hosts_filter) { if (rule->hosts_filter) {
...@@ -128,7 +129,7 @@ void ApplyRule(network::ResourceRequest* request, ...@@ -128,7 +129,7 @@ void ApplyRule(network::ResourceRequest* request,
break; break;
} }
if (!found) if (!found)
return; return false;
} }
if (rule->schemes_filter) { if (rule->schemes_filter) {
...@@ -140,19 +141,46 @@ void ApplyRule(network::ResourceRequest* request, ...@@ -140,19 +141,46 @@ void ApplyRule(network::ResourceRequest* request,
} }
} }
if (!found) if (!found)
return; return false;
} }
for (const auto& rewrite : rule->rewrites) { return true;
}
// Applies |rule|'s transformations to |request| if it satisfies |rule|'s
// criteria.
void ApplyRule(network::ResourceRequest* request,
const mojom::UrlRequestRulePtr& rule) {
if (!RuleFiltersMatchRequest(request, rule))
return;
for (const auto& rewrite : rule->actions)
ApplyRewrite(request, rewrite); ApplyRewrite(request, rewrite);
}
} }
void ApplyRules(network::ResourceRequest* request, // Returns true if |request| is either allowed or left unblocked by any rules.
const std::vector<mojom::UrlRequestRewriteRulePtr>& rules) { bool IsRequestAllowed(
for (const auto& rule : rules) { network::ResourceRequest* request,
ApplyRule(request, rule); const WebEngineURLLoaderThrottle::UrlRequestRewriteRules& rules) {
for (const auto& rule : rules.data) {
if (rule->actions.size() != 1)
continue;
if (rule->actions[0]->which() != mojom::UrlRequestAction::Tag::POLICY)
continue;
if (!RuleFiltersMatchRequest(request, rule))
continue;
switch (rule->actions[0]->get_policy()) {
case mojom::UrlRequestAccessPolicy::kAllow:
return true;
case mojom::UrlRequestAccessPolicy::kDeny:
return false;
}
} }
return true;
} }
} // namespace } // namespace
...@@ -173,8 +201,16 @@ void WebEngineURLLoaderThrottle::WillStartRequest( ...@@ -173,8 +201,16 @@ void WebEngineURLLoaderThrottle::WillStartRequest(
scoped_refptr<WebEngineURLLoaderThrottle::UrlRequestRewriteRules> scoped_refptr<WebEngineURLLoaderThrottle::UrlRequestRewriteRules>
cached_rules = cached_rules_provider_->GetCachedRules(); cached_rules = cached_rules_provider_->GetCachedRules();
// |cached_rules| may be empty if no rule was ever sent to WebEngine. // |cached_rules| may be empty if no rule was ever sent to WebEngine.
if (cached_rules) if (cached_rules) {
ApplyRules(request, cached_rules->data); if (!IsRequestAllowed(request, *cached_rules)) {
delegate_->CancelWithError(net::ERR_ABORTED,
"Resource load blocked by embedder policy.");
return;
}
for (const auto& rule : cached_rules->data)
ApplyRule(request, rule);
}
*defer = false; *defer = false;
} }
......
...@@ -18,7 +18,7 @@ class WEB_ENGINE_EXPORT WebEngineURLLoaderThrottle ...@@ -18,7 +18,7 @@ class WEB_ENGINE_EXPORT WebEngineURLLoaderThrottle
: public blink::URLLoaderThrottle { : public blink::URLLoaderThrottle {
public: public:
using UrlRequestRewriteRules = using UrlRequestRewriteRules =
base::RefCountedData<std::vector<mojom::UrlRequestRewriteRulePtr>>; base::RefCountedData<std::vector<mojom::UrlRequestRulePtr>>;
// An interface to provide rewrite rules to the throttle. Its // An interface to provide rewrite rules to the throttle. Its
// implementation must outlive the WebEngineURLLoaderThrottle. // implementation must outlive the WebEngineURLLoaderThrottle.
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
#include "base/test/task_environment.h" #include "base/test/task_environment.h"
#include "testing/gtest/include/gtest/gtest.h" #include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/common/loader/url_loader_throttle.h"
namespace { namespace {
...@@ -51,15 +52,15 @@ TEST_F(WebEngineURLLoaderThrottleTest, WildcardHosts) { ...@@ -51,15 +52,15 @@ TEST_F(WebEngineURLLoaderThrottleTest, WildcardHosts) {
mojom::UrlRequestRewriteAddHeadersPtr add_headers = mojom::UrlRequestRewriteAddHeadersPtr add_headers =
mojom::UrlRequestRewriteAddHeaders::New(); mojom::UrlRequestRewriteAddHeaders::New();
add_headers->headers.SetHeader("Header", "Value"); add_headers->headers.SetHeader("Header", "Value");
mojom::UrlRequestRewritePtr rewrite = mojom::UrlRequestActionPtr rewrite =
mojom::UrlRequestRewrite::NewAddHeaders(std::move(add_headers)); mojom::UrlRequestAction::NewAddHeaders(std::move(add_headers));
std::vector<mojom::UrlRequestRewritePtr> rewrites; std::vector<mojom::UrlRequestActionPtr> actions;
rewrites.push_back(std::move(rewrite)); actions.push_back(std::move(rewrite));
mojom::UrlRequestRewriteRulePtr rule = mojom::UrlRequestRewriteRule::New(); mojom::UrlRequestRulePtr rule = mojom::UrlRequestRule::New();
rule->hosts_filter = base::Optional<std::vector<std::string>>({"*.test.net"}); rule->hosts_filter = base::Optional<std::vector<std::string>>({"*.test.net"});
rule->rewrites = std::move(rewrites); rule->actions = std::move(actions);
std::vector<mojom::UrlRequestRewriteRulePtr> rules; std::vector<mojom::UrlRequestRulePtr> rules;
rules.push_back(std::move(rule)); rules.push_back(std::move(rule));
TestCachedRulesProvider provider; TestCachedRulesProvider provider;
...@@ -100,15 +101,15 @@ TEST_F(WebEngineURLLoaderThrottleTest, DataReplacementUrl) { ...@@ -100,15 +101,15 @@ TEST_F(WebEngineURLLoaderThrottleTest, DataReplacementUrl) {
mojom::UrlRequestRewriteReplaceUrl::New(); mojom::UrlRequestRewriteReplaceUrl::New();
replace_url->url_ends_with = ".css"; replace_url->url_ends_with = ".css";
replace_url->new_url = GURL(kCssDataURI); replace_url->new_url = GURL(kCssDataURI);
mojom::UrlRequestRewritePtr rewrite = mojom::UrlRequestActionPtr rewrite =
mojom::UrlRequestRewrite::NewReplaceUrl(std::move(replace_url)); mojom::UrlRequestAction::NewReplaceUrl(std::move(replace_url));
std::vector<mojom::UrlRequestRewritePtr> rewrites; std::vector<mojom::UrlRequestActionPtr> actions;
rewrites.push_back(std::move(rewrite)); actions.push_back(std::move(rewrite));
mojom::UrlRequestRewriteRulePtr rule = mojom::UrlRequestRewriteRule::New(); mojom::UrlRequestRulePtr rule = mojom::UrlRequestRule::New();
rule->hosts_filter = base::Optional<std::vector<std::string>>({"*.test.net"}); rule->hosts_filter = base::Optional<std::vector<std::string>>({"*.test.net"});
rule->rewrites = std::move(rewrites); rule->actions = std::move(actions);
std::vector<mojom::UrlRequestRewriteRulePtr> rules; std::vector<mojom::UrlRequestRulePtr> rules;
rules.push_back(std::move(rule)); rules.push_back(std::move(rule));
TestCachedRulesProvider provider; TestCachedRulesProvider provider;
...@@ -124,3 +125,74 @@ TEST_F(WebEngineURLLoaderThrottleTest, DataReplacementUrl) { ...@@ -124,3 +125,74 @@ TEST_F(WebEngineURLLoaderThrottleTest, DataReplacementUrl) {
throttle.WillStartRequest(&request, &defer); throttle.WillStartRequest(&request, &defer);
EXPECT_EQ(request.url, base::StringPiece(kCssDataURI)); EXPECT_EQ(request.url, base::StringPiece(kCssDataURI));
} }
class TestThrottleDelegate : public blink::URLLoaderThrottle::Delegate {
public:
TestThrottleDelegate() = default;
~TestThrottleDelegate() override = default;
bool canceled() const { return canceled_; }
base::StringPiece cancel_reason() const { return cancel_reason_; }
void Reset() {
canceled_ = false;
cancel_reason_.clear();
}
// URLLoaderThrottle::Delegate implementation.
void CancelWithError(int error_code,
base::StringPiece custom_reason) override {
canceled_ = true;
cancel_reason_ = custom_reason.as_string();
}
void Resume() override {}
private:
bool canceled_ = false;
std::string cancel_reason_;
};
// Tests that resource loads can be allowed or blocked based on the
// UrlRequestAction policy.
TEST_F(WebEngineURLLoaderThrottleTest, AllowAndDeny) {
std::vector<mojom::UrlRequestRulePtr> rules;
{
mojom::UrlRequestRulePtr rule = mojom::UrlRequestRule::New();
rule->hosts_filter = base::Optional<std::vector<std::string>>({"test.net"});
rule->actions.push_back(mojom::UrlRequestAction::NewPolicy(
mojom::UrlRequestAccessPolicy::kAllow));
rules.push_back(std::move(rule));
}
{
mojom::UrlRequestRulePtr rule = mojom::UrlRequestRule::New();
rule->actions.push_back(mojom::UrlRequestAction::NewPolicy(
mojom::UrlRequestAccessPolicy::kDeny));
rules.push_back(std::move(rule));
}
TestCachedRulesProvider provider;
provider.SetCachedRules(
base::MakeRefCounted<WebEngineURLLoaderThrottle::UrlRequestRewriteRules>(
std::move(rules)));
WebEngineURLLoaderThrottle throttle(&provider);
bool defer = false;
TestThrottleDelegate delegate;
throttle.set_delegate(&delegate);
network::ResourceRequest request1;
request1.url = GURL("http://test.net");
throttle.WillStartRequest(&request1, &defer);
EXPECT_FALSE(delegate.canceled());
delegate.Reset();
network::ResourceRequest request2;
request2.url = GURL("http://blocked.net");
throttle.WillStartRequest(&request2, &defer);
EXPECT_TRUE(delegate.canceled());
EXPECT_EQ(delegate.cancel_reason(),
"Resource load blocked by embedder policy.");
}
...@@ -41,7 +41,7 @@ void UrlRequestRulesReceiver::OnUrlRequestRulesReceiverAssociatedReceiver( ...@@ -41,7 +41,7 @@ void UrlRequestRulesReceiver::OnUrlRequestRulesReceiverAssociatedReceiver(
} }
void UrlRequestRulesReceiver::OnRulesUpdated( void UrlRequestRulesReceiver::OnRulesUpdated(
std::vector<mojom::UrlRequestRewriteRulePtr> rules) { std::vector<mojom::UrlRequestRulePtr> rules) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
base::AutoLock auto_lock(lock_); base::AutoLock auto_lock(lock_);
cached_rules_ = cached_rules_ =
......
...@@ -42,8 +42,7 @@ class UrlRequestRulesReceiver ...@@ -42,8 +42,7 @@ class UrlRequestRulesReceiver
mojo::PendingAssociatedReceiver<mojom::UrlRequestRulesReceiver> receiver); mojo::PendingAssociatedReceiver<mojom::UrlRequestRulesReceiver> receiver);
// mojom::UrlRequestRulesReceiver implementation. // mojom::UrlRequestRulesReceiver implementation.
void OnRulesUpdated( void OnRulesUpdated(std::vector<mojom::UrlRequestRulePtr> rules) override;
std::vector<mojom::UrlRequestRewriteRulePtr> rules) override;
// WebEngineURLLoaderThrottle::CachedRulesProvider implementation. // WebEngineURLLoaderThrottle::CachedRulesProvider implementation.
scoped_refptr<WebEngineURLLoaderThrottle::UrlRequestRewriteRules> scoped_refptr<WebEngineURLLoaderThrottle::UrlRequestRewriteRules>
......
...@@ -13,11 +13,11 @@ import "url/mojom/url.mojom"; ...@@ -13,11 +13,11 @@ import "url/mojom/url.mojom";
// TODO(https://crbug.com/976975): Support URL rewriting for service workers. // TODO(https://crbug.com/976975): Support URL rewriting for service workers.
interface UrlRequestRulesReceiver { interface UrlRequestRulesReceiver {
// Receives a set of rules to apply to URL requests. // Receives a set of rules to apply to URL requests.
OnRulesUpdated(array<UrlRequestRewriteRule> rules); OnRulesUpdated(array<UrlRequestRule> rules);
}; };
// A URL request rewrite rule. // A URL request modification rule.
struct UrlRequestRewriteRule { struct UrlRequestRule {
// Set of hosts to apply the rewrites to. If empty, the rule will apply to // Set of hosts to apply the rewrites to. If empty, the rule will apply to
// every request, independent of host. // every request, independent of host.
array<string>? hosts_filter; array<string>? hosts_filter;
...@@ -27,10 +27,10 @@ struct UrlRequestRewriteRule { ...@@ -27,10 +27,10 @@ struct UrlRequestRewriteRule {
array<string>? schemes_filter; array<string>? schemes_filter;
// URL request rewrites to apply. // URL request rewrites to apply.
array<UrlRequestRewrite> rewrites; array<UrlRequestAction> actions;
}; };
union UrlRequestRewrite { union UrlRequestAction {
// Adds a set of headers to a URL request. // Adds a set of headers to a URL request.
UrlRequestRewriteAddHeaders add_headers; UrlRequestRewriteAddHeaders add_headers;
...@@ -42,6 +42,10 @@ union UrlRequestRewrite { ...@@ -42,6 +42,10 @@ union UrlRequestRewrite {
// Replaces a URL if the original URL ends with a pattern. // Replaces a URL if the original URL ends with a pattern.
UrlRequestRewriteReplaceUrl replace_url; UrlRequestRewriteReplaceUrl replace_url;
// Specifies whether the request should be allowed or blocked.
// Cannot be combined with other UrlRequestActions.
UrlRequestAccessPolicy policy;
}; };
// Adds |headers| to the URL request. If a header is already present in the // Adds |headers| to the URL request. If a header is already present in the
...@@ -81,3 +85,8 @@ struct UrlRequestRewriteReplaceUrl { ...@@ -81,3 +85,8 @@ struct UrlRequestRewriteReplaceUrl {
// The replacement URL. // The replacement URL.
url.mojom.Url new_url; url.mojom.Url new_url;
}; };
enum UrlRequestAccessPolicy {
kAllow,
kDeny,
};
...@@ -6,6 +6,8 @@ ...@@ -6,6 +6,8 @@
#include "base/strings/strcat.h" #include "base/strings/strcat.h"
#include "base/strings/string_util.h" #include "base/strings/string_util.h"
#include "fuchsia/base/string_util.h"
#include "net/base/url_util.h"
namespace { namespace {
...@@ -17,96 +19,121 @@ std::string NormalizeHost(base::StringPiece host) { ...@@ -17,96 +19,121 @@ std::string NormalizeHost(base::StringPiece host) {
namespace mojo { namespace mojo {
mojom::UrlRequestRewriteAddHeadersPtr template <>
TypeConverter<mojom::UrlRequestRewriteAddHeadersPtr, struct TypeConverter<mojom::UrlRequestRewriteAddHeadersPtr,
fuchsia::web::UrlRequestRewriteAddHeaders>:: fuchsia::web::UrlRequestRewriteAddHeaders> {
Convert(const fuchsia::web::UrlRequestRewriteAddHeaders& input) { static mojom::UrlRequestRewriteAddHeadersPtr Convert(
mojom::UrlRequestRewriteAddHeadersPtr add_headers = const fuchsia::web::UrlRequestRewriteAddHeaders& input) {
mojom::UrlRequestRewriteAddHeaders::New(); mojom::UrlRequestRewriteAddHeadersPtr add_headers =
if (input.has_headers()) { mojom::UrlRequestRewriteAddHeaders::New();
for (const auto& header : input.headers()) { if (input.has_headers()) {
base::StringPiece header_name = cr_fuchsia::BytesAsString(header.name); for (const auto& header : input.headers()) {
base::StringPiece header_value = cr_fuchsia::BytesAsString(header.value); base::StringPiece header_name = cr_fuchsia::BytesAsString(header.name);
add_headers->headers.SetHeader(header_name, header_value); base::StringPiece header_value =
cr_fuchsia::BytesAsString(header.value);
add_headers->headers.SetHeader(header_name, header_value);
}
} }
return add_headers;
} }
return add_headers; };
}
mojom::UrlRequestRewriteRemoveHeaderPtr template <>
TypeConverter<mojom::UrlRequestRewriteRemoveHeaderPtr, struct TypeConverter<mojom::UrlRequestRewriteRemoveHeaderPtr,
fuchsia::web::UrlRequestRewriteRemoveHeader>:: fuchsia::web::UrlRequestRewriteRemoveHeader> {
Convert(const fuchsia::web::UrlRequestRewriteRemoveHeader& input) { static mojom::UrlRequestRewriteRemoveHeaderPtr Convert(
mojom::UrlRequestRewriteRemoveHeaderPtr remove_header = const fuchsia::web::UrlRequestRewriteRemoveHeader& input) {
mojom::UrlRequestRewriteRemoveHeader::New(); mojom::UrlRequestRewriteRemoveHeaderPtr remove_header =
if (input.has_query_pattern()) mojom::UrlRequestRewriteRemoveHeader::New();
remove_header->query_pattern = base::make_optional(input.query_pattern()); if (input.has_query_pattern())
if (input.has_header_name()) remove_header->query_pattern = base::make_optional(input.query_pattern());
remove_header->header_name = if (input.has_header_name())
cr_fuchsia::BytesAsString(input.header_name()).as_string(); remove_header->header_name =
return remove_header; cr_fuchsia::BytesAsString(input.header_name()).as_string();
} return remove_header;
}
};
mojom::UrlRequestRewriteSubstituteQueryPatternPtr template <>
TypeConverter<mojom::UrlRequestRewriteSubstituteQueryPatternPtr, struct TypeConverter<mojom::UrlRequestRewriteSubstituteQueryPatternPtr,
fuchsia::web::UrlRequestRewriteSubstituteQueryPattern>:: fuchsia::web::UrlRequestRewriteSubstituteQueryPattern> {
Convert( static mojom::UrlRequestRewriteSubstituteQueryPatternPtr Convert(
const fuchsia::web::UrlRequestRewriteSubstituteQueryPattern& input) { const fuchsia::web::UrlRequestRewriteSubstituteQueryPattern& input) {
mojom::UrlRequestRewriteSubstituteQueryPatternPtr substitute_query_pattern = mojom::UrlRequestRewriteSubstituteQueryPatternPtr substitute_query_pattern =
mojom::UrlRequestRewriteSubstituteQueryPattern::New(); mojom::UrlRequestRewriteSubstituteQueryPattern::New();
if (input.has_pattern()) if (input.has_pattern())
substitute_query_pattern->pattern = input.pattern(); substitute_query_pattern->pattern = input.pattern();
if (input.has_substitution()) if (input.has_substitution())
substitute_query_pattern->substitution = input.substitution(); substitute_query_pattern->substitution = input.substitution();
return substitute_query_pattern; return substitute_query_pattern;
} }
};
mojom::UrlRequestRewriteReplaceUrlPtr template <>
TypeConverter<mojom::UrlRequestRewriteReplaceUrlPtr, struct TypeConverter<mojom::UrlRequestRewriteReplaceUrlPtr,
fuchsia::web::UrlRequestRewriteReplaceUrl>:: fuchsia::web::UrlRequestRewriteReplaceUrl> {
Convert(const fuchsia::web::UrlRequestRewriteReplaceUrl& input) { static mojom::UrlRequestRewriteReplaceUrlPtr Convert(
mojom::UrlRequestRewriteReplaceUrlPtr replace_url = const fuchsia::web::UrlRequestRewriteReplaceUrl& input) {
mojom::UrlRequestRewriteReplaceUrl::New(); mojom::UrlRequestRewriteReplaceUrlPtr replace_url =
if (input.has_url_ends_with()) mojom::UrlRequestRewriteReplaceUrl::New();
replace_url->url_ends_with = input.url_ends_with(); if (input.has_url_ends_with())
if (input.has_new_url()) replace_url->url_ends_with = input.url_ends_with();
replace_url->new_url = GURL(input.new_url()); if (input.has_new_url())
return replace_url; replace_url->new_url = GURL(input.new_url());
} return replace_url;
}
};
template <>
struct TypeConverter<mojom::UrlRequestAccessPolicy,
fuchsia::web::UrlRequestAction> {
static mojom::UrlRequestAccessPolicy Convert(
const fuchsia::web::UrlRequestAction& input) {
switch (input) {
case fuchsia::web::UrlRequestAction::ALLOW:
return mojom::UrlRequestAccessPolicy::kAllow;
case fuchsia::web::UrlRequestAction::DENY:
return mojom::UrlRequestAccessPolicy::kDeny;
}
}
};
mojom::UrlRequestRewritePtr template <>
TypeConverter<mojom::UrlRequestRewritePtr, fuchsia::web::UrlRequestRewrite>:: struct TypeConverter<mojom::UrlRequestActionPtr,
Convert(const fuchsia::web::UrlRequestRewrite& input) { fuchsia::web::UrlRequestRewrite> {
switch (input.Which()) { static mojom::UrlRequestActionPtr Convert(
case fuchsia::web::UrlRequestRewrite::Tag::kAddHeaders: const fuchsia::web::UrlRequestRewrite& input) {
return mojom::UrlRequestRewrite::NewAddHeaders( switch (input.Which()) {
mojo::ConvertTo<mojom::UrlRequestRewriteAddHeadersPtr>( case fuchsia::web::UrlRequestRewrite::Tag::kAddHeaders:
input.add_headers())); return mojom::UrlRequestAction::NewAddHeaders(
case fuchsia::web::UrlRequestRewrite::Tag::kRemoveHeader: mojo::ConvertTo<mojom::UrlRequestRewriteAddHeadersPtr>(
return mojom::UrlRequestRewrite::NewRemoveHeader( input.add_headers()));
mojo::ConvertTo<mojom::UrlRequestRewriteRemoveHeaderPtr>( case fuchsia::web::UrlRequestRewrite::Tag::kRemoveHeader:
input.remove_header())); return mojom::UrlRequestAction::NewRemoveHeader(
case fuchsia::web::UrlRequestRewrite::Tag::kSubstituteQueryPattern: mojo::ConvertTo<mojom::UrlRequestRewriteRemoveHeaderPtr>(
return mojom::UrlRequestRewrite::NewSubstituteQueryPattern( input.remove_header()));
mojo::ConvertTo<mojom::UrlRequestRewriteSubstituteQueryPatternPtr>( case fuchsia::web::UrlRequestRewrite::Tag::kSubstituteQueryPattern:
input.substitute_query_pattern())); return mojom::UrlRequestAction::NewSubstituteQueryPattern(
case fuchsia::web::UrlRequestRewrite::Tag::kReplaceUrl: mojo::ConvertTo<mojom::UrlRequestRewriteSubstituteQueryPatternPtr>(
return mojom::UrlRequestRewrite::NewReplaceUrl( input.substitute_query_pattern()));
mojo::ConvertTo<mojom::UrlRequestRewriteReplaceUrlPtr>( case fuchsia::web::UrlRequestRewrite::Tag::kReplaceUrl:
input.replace_url())); return mojom::UrlRequestAction::NewReplaceUrl(
default: mojo::ConvertTo<mojom::UrlRequestRewriteReplaceUrlPtr>(
// This is to prevent build breakage when adding new rewrites to the FIDL input.replace_url()));
// definition. default:
NOTREACHED(); // This is to prevent build breakage when adding new rewrites to the
return nullptr; // FIDL definition.
NOTREACHED();
return nullptr;
}
} }
} };
mojom::UrlRequestRewriteRulePtr mojom::UrlRequestRulePtr
TypeConverter<mojom::UrlRequestRewriteRulePtr, TypeConverter<mojom::UrlRequestRulePtr, fuchsia::web::UrlRequestRewriteRule>::
fuchsia::web::UrlRequestRewriteRule>::
Convert(const fuchsia::web::UrlRequestRewriteRule& input) { Convert(const fuchsia::web::UrlRequestRewriteRule& input) {
mojom::UrlRequestRewriteRulePtr rule = mojom::UrlRequestRewriteRule::New(); mojom::UrlRequestRulePtr rule = mojom::UrlRequestRule::New();
if (input.has_hosts_filter()) { if (input.has_hosts_filter()) {
// Convert host names in case they contain non-ASCII characters. // Convert host names in case they contain non-ASCII characters.
const base::StringPiece kWildcard("*."); const base::StringPiece kWildcard("*.");
...@@ -122,11 +149,19 @@ TypeConverter<mojom::UrlRequestRewriteRulePtr, ...@@ -122,11 +149,19 @@ TypeConverter<mojom::UrlRequestRewriteRulePtr,
} }
rule->hosts_filter = std::move(hosts); rule->hosts_filter = std::move(hosts);
} }
if (input.has_schemes_filter()) if (input.has_schemes_filter())
rule->schemes_filter = base::make_optional(input.schemes_filter()); rule->schemes_filter = base::make_optional(input.schemes_filter());
if (input.has_rewrites())
rule->rewrites = mojo::ConvertTo<std::vector<mojom::UrlRequestRewritePtr>>( if (input.has_rewrites()) {
rule->actions = mojo::ConvertTo<std::vector<mojom::UrlRequestActionPtr>>(
input.rewrites()); input.rewrites());
} else if (input.has_action()) {
rule->actions = std::vector<mojom::UrlRequestActionPtr>();
rule->actions.push_back(mojom::UrlRequestAction::NewPolicy(
mojo::ConvertTo<mojom::UrlRequestAccessPolicy>(input.action())));
}
return rule; return rule;
} }
......
...@@ -7,51 +7,15 @@ ...@@ -7,51 +7,15 @@
#include <fuchsia/web/cpp/fidl.h> #include <fuchsia/web/cpp/fidl.h>
#include "fuchsia/base/string_util.h"
#include "fuchsia/engine/url_request_rewrite.mojom.h" #include "fuchsia/engine/url_request_rewrite.mojom.h"
#include "mojo/public/cpp/bindings/type_converter.h" #include "mojo/public/cpp/bindings/type_converter.h"
namespace mojo { namespace mojo {
template <> template <>
struct TypeConverter<mojom::UrlRequestRewriteAddHeadersPtr, struct TypeConverter<mojom::UrlRequestRulePtr,
fuchsia::web::UrlRequestRewriteAddHeaders> {
static mojom::UrlRequestRewriteAddHeadersPtr Convert(
const fuchsia::web::UrlRequestRewriteAddHeaders& input);
};
template <>
struct TypeConverter<mojom::UrlRequestRewriteRemoveHeaderPtr,
fuchsia::web::UrlRequestRewriteRemoveHeader> {
static mojom::UrlRequestRewriteRemoveHeaderPtr Convert(
const fuchsia::web::UrlRequestRewriteRemoveHeader& input);
};
template <>
struct TypeConverter<mojom::UrlRequestRewriteSubstituteQueryPatternPtr,
fuchsia::web::UrlRequestRewriteSubstituteQueryPattern> {
static mojom::UrlRequestRewriteSubstituteQueryPatternPtr Convert(
const fuchsia::web::UrlRequestRewriteSubstituteQueryPattern& input);
};
template <>
struct TypeConverter<mojom::UrlRequestRewriteReplaceUrlPtr,
fuchsia::web::UrlRequestRewriteReplaceUrl> {
static mojom::UrlRequestRewriteReplaceUrlPtr Convert(
const fuchsia::web::UrlRequestRewriteReplaceUrl& input);
};
template <>
struct TypeConverter<mojom::UrlRequestRewritePtr,
fuchsia::web::UrlRequestRewrite> {
static mojom::UrlRequestRewritePtr Convert(
const fuchsia::web::UrlRequestRewrite& input);
};
template <>
struct TypeConverter<mojom::UrlRequestRewriteRulePtr,
fuchsia::web::UrlRequestRewriteRule> { fuchsia::web::UrlRequestRewriteRule> {
static mojom::UrlRequestRewriteRulePtr Convert( static mojom::UrlRequestRulePtr Convert(
const fuchsia::web::UrlRequestRewriteRule& input); const fuchsia::web::UrlRequestRewriteRule& input);
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment