Commit f89dec09 authored by Wez's avatar Wez Committed by Commit Bot

Reland "[fuchsia] Implement fuchsia.web.Frame/SetUrlRequestRewriteRules."

This is a reland of 62e19745 with the component
build fixed.

Original change's description:
> [fuchsia] Implement fuchsia.web.Frame/SetUrlRequestRewriteRules.
>
> * Implement the fuchsia.web.Frame/SetUrlRequestRewriteRules API.
> * Add a mojo interface to provide the renderers with new rules.
>   * This interface is implemented in the browser in
>     UrlRequestRewriteRulesManager, which also takes care of validating
>     and converting the rules from FIDL to Mojo, and providing them to
>     the WebEngineURLLoaderThrottles in the browser.
>   * In the renderer, there is one rules receiver per RenderFrame,
>     implemented in UrlRequestRulesReceiver. They cache the rules and
>     provide them to the WebEngineURLLoaderThrottles in the renderer.
> * Add unit tests and browser tests for the new API.
>
> Bug: 976975
> Change-Id: I446ea4838d50e65c568e7e2cbcd32c23d64af426
> Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1659677
> Commit-Queue: Wez <wez@chromium.org>
> Reviewed-by: Daniel Cheng <dcheng@chromium.org>
> Reviewed-by: Ken Rockot <rockot@google.com>
> Reviewed-by: Wez <wez@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#695298}

Bug: 976975, 1002719
Change-Id: I8ea6fda911b6efb89eff8f33182525ed99a20cc1
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1797338
Auto-Submit: Wez <wez@chromium.org>
Reviewed-by: default avatarDaniel Cheng <dcheng@chromium.org>
Reviewed-by: default avatarScott Violet <sky@chromium.org>
Reviewed-by: default avatarKevin Marshall <kmarshall@chromium.org>
Commit-Queue: Scott Violet <sky@chromium.org>
Cr-Commit-Position: refs/heads/master@{#695745}
parent 28836a5e
...@@ -1122,6 +1122,8 @@ _BANNED_CPP_FUNCTIONS = ( ...@@ -1122,6 +1122,8 @@ _BANNED_CPP_FUNCTIONS = (
), ),
False, False,
( (
r'^fuchsia/engine/browser/url_request_rewrite_rules_manager\.cc$',
r'^fuchsia/engine/url_request_rewrite_type_converters\.cc$',
r'^third_party/blink/.*\.(cc|h)$', r'^third_party/blink/.*\.(cc|h)$',
r'^content/renderer/.*\.(cc|h)$', r'^content/renderer/.*\.(cc|h)$',
), ),
......
...@@ -73,6 +73,8 @@ source_set("test_support") { ...@@ -73,6 +73,8 @@ source_set("test_support") {
"test_devtools_list_fetcher.h", "test_devtools_list_fetcher.h",
"test_navigation_listener.cc", "test_navigation_listener.cc",
"test_navigation_listener.h", "test_navigation_listener.h",
"url_request_rewrite_test_util.cc",
"url_request_rewrite_test_util.h",
] ]
public_deps = [ public_deps = [
":base", ":base",
......
// Copyright 2019 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.
#include "fuchsia/base/url_request_rewrite_test_util.h"
#include "fuchsia/base/string_util.h"
namespace cr_fuchsia {
fuchsia::web::UrlRequestRewrite CreateRewriteAddHeaders(
base::StringPiece header_name,
base::StringPiece header_value) {
fuchsia::net::http::Header header;
header.name = cr_fuchsia::StringToBytes(header_name);
header.value = cr_fuchsia::StringToBytes(header_value);
std::vector<fuchsia::net::http::Header> response_headers;
response_headers.push_back(std::move(header));
fuchsia::web::UrlRequestRewriteAddHeaders add_headers;
add_headers.set_headers(std::move(response_headers));
fuchsia::web::UrlRequestRewrite rewrite;
rewrite.set_add_headers(std::move(add_headers));
return rewrite;
}
fuchsia::web::UrlRequestRewrite CreateRewriteRemoveHeader(
base::Optional<base::StringPiece> query_pattern,
base::StringPiece header_name) {
fuchsia::web::UrlRequestRewriteRemoveHeader remove_header;
if (query_pattern)
remove_header.set_query_pattern(query_pattern.value().as_string());
remove_header.set_header_name(cr_fuchsia::StringToBytes(header_name));
fuchsia::web::UrlRequestRewrite rewrite;
rewrite.set_remove_header(std::move(remove_header));
return rewrite;
}
fuchsia::web::UrlRequestRewrite CreateRewriteSubstituteQueryPattern(
base::StringPiece pattern,
base::StringPiece substitution) {
fuchsia::web::UrlRequestRewriteSubstituteQueryPattern
substitute_query_pattern;
substitute_query_pattern.set_pattern(pattern.as_string());
substitute_query_pattern.set_substitution(substitution.as_string());
fuchsia::web::UrlRequestRewrite rewrite;
rewrite.set_substitute_query_pattern(std::move(substitute_query_pattern));
return rewrite;
}
fuchsia::web::UrlRequestRewrite CreateRewriteReplaceUrl(
base::StringPiece url_ends_with,
base::StringPiece new_url) {
fuchsia::web::UrlRequestRewriteReplaceUrl replace_url;
replace_url.set_url_ends_with(url_ends_with.as_string());
replace_url.set_new_url(new_url.as_string());
fuchsia::web::UrlRequestRewrite rewrite;
rewrite.set_replace_url(std::move(replace_url));
return rewrite;
}
} // namespace cr_fuchsia
// Copyright 2019 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 FUCHSIA_BASE_URL_REQUEST_REWRITE_TEST_UTIL_H_
#define FUCHSIA_BASE_URL_REQUEST_REWRITE_TEST_UTIL_H_
#include <fuchsia/web/cpp/fidl.h>
#include "base/optional.h"
#include "base/strings/string_piece.h"
namespace cr_fuchsia {
// Utility functions to create a fuchsia.web.UrlRequestRewrite in one line.
fuchsia::web::UrlRequestRewrite CreateRewriteAddHeaders(
base::StringPiece header_name,
base::StringPiece header_value);
fuchsia::web::UrlRequestRewrite CreateRewriteRemoveHeader(
base::Optional<base::StringPiece> query_pattern,
base::StringPiece header_name);
fuchsia::web::UrlRequestRewrite CreateRewriteSubstituteQueryPattern(
base::StringPiece pattern,
base::StringPiece substitution);
fuchsia::web::UrlRequestRewrite CreateRewriteReplaceUrl(
base::StringPiece url_ends_with,
base::StringPiece new_url);
} // namespace cr_fuchsia
#endif // FUCHSIA_BASE_URL_REQUEST_REWRITE_TEST_UTIL_H_
...@@ -17,9 +17,11 @@ config("web_engine_implementation") { ...@@ -17,9 +17,11 @@ config("web_engine_implementation") {
mojom("mojom") { mojom("mojom") {
sources = [ sources = [
"on_load_script_injector.mojom", "on_load_script_injector.mojom",
"url_request_rewrite.mojom",
] ]
public_deps = [ public_deps = [
"//mojo/public/mojom/base", "//mojo/public/mojom/base",
"//services/network/public/mojom",
] ]
visibility = [ ":*" ] visibility = [ ":*" ]
} }
...@@ -127,6 +129,8 @@ component("web_engine_core") { ...@@ -127,6 +129,8 @@ component("web_engine_core") {
"browser/frame_impl.h", "browser/frame_impl.h",
"browser/navigation_controller_impl.cc", "browser/navigation_controller_impl.cc",
"browser/navigation_controller_impl.h", "browser/navigation_controller_impl.h",
"browser/url_request_rewrite_rules_manager.cc",
"browser/url_request_rewrite_rules_manager.h",
"browser/web_engine_browser_context.cc", "browser/web_engine_browser_context.cc",
"browser/web_engine_browser_context.h", "browser/web_engine_browser_context.h",
"browser/web_engine_browser_main.cc", "browser/web_engine_browser_main.cc",
...@@ -149,14 +153,22 @@ component("web_engine_core") { ...@@ -149,14 +153,22 @@ component("web_engine_core") {
"browser/web_engine_screen.h", "browser/web_engine_screen.h",
"common.cc", "common.cc",
"common.h", "common.h",
"common/web_engine_url_loader_throttle.cc",
"common/web_engine_url_loader_throttle.h",
"context_provider_impl.cc", "context_provider_impl.cc",
"context_provider_impl.h", "context_provider_impl.h",
"context_provider_main.cc", "context_provider_main.cc",
"context_provider_main.h", "context_provider_main.h",
"renderer/on_load_script_injector.cc", "renderer/on_load_script_injector.cc",
"renderer/on_load_script_injector.h", "renderer/on_load_script_injector.h",
"renderer/url_request_rules_receiver.cc",
"renderer/url_request_rules_receiver.h",
"renderer/web_engine_content_renderer_client.cc", "renderer/web_engine_content_renderer_client.cc",
"renderer/web_engine_content_renderer_client.h", "renderer/web_engine_content_renderer_client.h",
"renderer/web_engine_url_loader_throttle_provider.cc",
"renderer/web_engine_url_loader_throttle_provider.h",
"url_request_rewrite_type_converters.cc",
"url_request_rewrite_type_converters.h",
"web_engine_content_client.cc", "web_engine_content_client.cc",
"web_engine_content_client.h", "web_engine_content_client.h",
"web_engine_export.h", "web_engine_export.h",
...@@ -258,12 +270,14 @@ test("web_engine_unittests") { ...@@ -258,12 +270,14 @@ test("web_engine_unittests") {
"browser/accessibility_bridge_unittest.cc", "browser/accessibility_bridge_unittest.cc",
"browser/cookie_manager_impl_unittest.cc", "browser/cookie_manager_impl_unittest.cc",
"browser/frame_impl_unittest.cc", "browser/frame_impl_unittest.cc",
"browser/url_request_rewrite_rules_manager_unittest.cc",
"context_provider_impl_unittest.cc", "context_provider_impl_unittest.cc",
"fake_context.cc", "fake_context.cc",
"fake_context.h", "fake_context.h",
"test/run_all_unittests.cc", "test/run_all_unittests.cc",
] ]
deps = [ deps = [
":mojom",
":web_engine_core", ":web_engine_core",
"//base/test:test_support", "//base/test:test_support",
"//fuchsia/base:test_support", "//fuchsia/base:test_support",
......
...@@ -3,6 +3,7 @@ include_rules = [ ...@@ -3,6 +3,7 @@ include_rules = [
"+content/public/app", "+content/public/app",
"+gpu/command_buffer/service", "+gpu/command_buffer/service",
"+media/base", "+media/base",
"+mojo/public",
"+services/service_manager", "+services/service_manager",
"+third_party/widevine/cdm/widevine_cdm_common.h", "+third_party/widevine/cdm/widevine_cdm_common.h",
"+ui/base", "+ui/base",
......
per-file *.mojom=set noparent per-file *.mojom=set noparent
per-file *.mojom=file://ipc/SECURITY_OWNERS per-file *.mojom=file://ipc/SECURITY_OWNERS
per-file *_type_converter*.*=set noparent
per-file *_type_converter*.*=file://ipc/SECURITY_OWNERS
...@@ -184,6 +184,7 @@ FrameImpl::FrameImpl(std::unique_ptr<content::WebContents> web_contents, ...@@ -184,6 +184,7 @@ FrameImpl::FrameImpl(std::unique_ptr<content::WebContents> web_contents,
context_(context), context_(context),
navigation_controller_(web_contents_.get()), navigation_controller_(web_contents_.get()),
log_level_(kLogSeverityNone), log_level_(kLogSeverityNone),
url_request_rewrite_rules_manager_(web_contents_.get()),
binding_(this, std::move(frame_request)) { binding_(this, std::move(frame_request)) {
web_contents_->SetDelegate(this); web_contents_->SetDelegate(this);
Observe(web_contents_.get()); Observe(web_contents_.get());
...@@ -344,6 +345,12 @@ void FrameImpl::AddNewContents( ...@@ -344,6 +345,12 @@ void FrameImpl::AddNewContents(
case WindowOpenDisposition::NEW_BACKGROUND_TAB: case WindowOpenDisposition::NEW_BACKGROUND_TAB:
case WindowOpenDisposition::NEW_POPUP: case WindowOpenDisposition::NEW_POPUP:
case WindowOpenDisposition::NEW_WINDOW: { case WindowOpenDisposition::NEW_WINDOW: {
if (url_request_rewrite_rules_manager_.GetCachedRules()) {
// There is no support for URL request rules rewriting with popups.
*was_blocked = true;
return;
}
PopupFrameCreationInfoUserData* popup_creation_info = PopupFrameCreationInfoUserData* popup_creation_info =
reinterpret_cast<PopupFrameCreationInfoUserData*>( reinterpret_cast<PopupFrameCreationInfoUserData*>(
new_contents->GetUserData(kPopupCreationInfo)); new_contents->GetUserData(kPopupCreationInfo));
...@@ -620,6 +627,15 @@ void FrameImpl::SetPopupFrameCreationListener( ...@@ -620,6 +627,15 @@ void FrameImpl::SetPopupFrameCreationListener(
fit::bind_member(this, &FrameImpl::OnPopupListenerDisconnected)); fit::bind_member(this, &FrameImpl::OnPopupListenerDisconnected));
} }
void FrameImpl::SetUrlRequestRewriteRules(
std::vector<fuchsia::web::UrlRequestRewriteRule> rules,
SetUrlRequestRewriteRulesCallback callback) {
zx_status_t error = url_request_rewrite_rules_manager_.OnRulesUpdated(
std::move(rules), std::move(callback));
if (error != ZX_OK)
binding_.Close(error);
}
void FrameImpl::CloseContents(content::WebContents* source) { void FrameImpl::CloseContents(content::WebContents* source) {
DCHECK_EQ(source, web_contents_.get()); DCHECK_EQ(source, web_contents_.get());
context_->DestroyFrame(this); context_->DestroyFrame(this);
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#include <fuchsia/web/cpp/fidl.h> #include <fuchsia/web/cpp/fidl.h>
#include <lib/fidl/cpp/binding_set.h> #include <lib/fidl/cpp/binding_set.h>
#include <lib/zx/channel.h> #include <lib/zx/channel.h>
#include <list> #include <list>
#include <map> #include <map>
#include <memory> #include <memory>
...@@ -21,6 +22,7 @@ ...@@ -21,6 +22,7 @@
#include "content/public/browser/web_contents_observer.h" #include "content/public/browser/web_contents_observer.h"
#include "fuchsia/engine/browser/discarding_event_filter.h" #include "fuchsia/engine/browser/discarding_event_filter.h"
#include "fuchsia/engine/browser/navigation_controller_impl.h" #include "fuchsia/engine/browser/navigation_controller_impl.h"
#include "fuchsia/engine/browser/url_request_rewrite_rules_manager.h"
#include "fuchsia/engine/on_load_script_injector.mojom.h" #include "fuchsia/engine/on_load_script_injector.mojom.h"
#include "ui/aura/window_tree_host.h" #include "ui/aura/window_tree_host.h"
#include "ui/wm/core/focus_controller.h" #include "ui/wm/core/focus_controller.h"
...@@ -126,6 +128,9 @@ class FrameImpl : public fuchsia::web::Frame, ...@@ -126,6 +128,9 @@ class FrameImpl : public fuchsia::web::Frame,
void SetPopupFrameCreationListener( void SetPopupFrameCreationListener(
fidl::InterfaceHandle<fuchsia::web::PopupFrameCreationListener> listener) fidl::InterfaceHandle<fuchsia::web::PopupFrameCreationListener> listener)
override; override;
void SetUrlRequestRewriteRules(
std::vector<fuchsia::web::UrlRequestRewriteRule> rules,
SetUrlRequestRewriteRulesCallback callback) override;
// content::WebContentsDelegate implementation. // content::WebContentsDelegate implementation.
void CloseContents(content::WebContents* source) override; void CloseContents(content::WebContents* source) override;
...@@ -177,6 +182,7 @@ class FrameImpl : public fuchsia::web::Frame, ...@@ -177,6 +182,7 @@ class FrameImpl : public fuchsia::web::Frame,
std::map<uint64_t, OriginScopedScript> before_load_scripts_; std::map<uint64_t, OriginScopedScript> before_load_scripts_;
std::vector<uint64_t> before_load_scripts_order_; std::vector<uint64_t> before_load_scripts_order_;
base::RepeatingCallback<void(base::StringPiece)> console_log_message_hook_; base::RepeatingCallback<void(base::StringPiece)> console_log_message_hook_;
UrlRequestRewriteRulesManager url_request_rewrite_rules_manager_;
// Used for receiving and dispatching popup created by this Frame. // Used for receiving and dispatching popup created by this Frame.
fuchsia::web::PopupFrameCreationListenerPtr popup_listener_; fuchsia::web::PopupFrameCreationListenerPtr popup_listener_;
...@@ -188,5 +194,4 @@ class FrameImpl : public fuchsia::web::Frame, ...@@ -188,5 +194,4 @@ class FrameImpl : public fuchsia::web::Frame,
DISALLOW_COPY_AND_ASSIGN(FrameImpl); DISALLOW_COPY_AND_ASSIGN(FrameImpl);
}; };
#endif // FUCHSIA_ENGINE_BROWSER_FRAME_IMPL_H_ #endif // FUCHSIA_ENGINE_BROWSER_FRAME_IMPL_H_
// Copyright 2019 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.
#include "fuchsia/engine/browser/url_request_rewrite_rules_manager.h"
#include "fuchsia/base/string_util.h"
#include "fuchsia/engine/url_request_rewrite_type_converters.h"
#include "net/http/http_util.h"
#include "third_party/blink/public/common/associated_interfaces/associated_interface_provider.h"
namespace {
using RoutingIdRewriterMap =
std::unordered_map<int, UrlRequestRewriteRulesManager*>;
RoutingIdRewriterMap& GetRewriterMap() {
static base::NoDestructor<RoutingIdRewriterMap> rewriter_map;
return *rewriter_map;
}
bool ValidateAddHeaders(
const fuchsia::web::UrlRequestRewriteAddHeaders& add_headers) {
if (!add_headers.has_headers())
return false;
for (const auto& header : add_headers.headers()) {
base::StringPiece header_name = cr_fuchsia::BytesAsString(header.name);
base::StringPiece header_value = cr_fuchsia::BytesAsString(header.value);
if (!net::HttpUtil::IsValidHeaderName(header_name) ||
!net::HttpUtil::IsValidHeaderValue(header_value))
return false;
}
return true;
}
bool ValidateRemoveHeader(
const fuchsia::web::UrlRequestRewriteRemoveHeader& remove_header) {
if (!remove_header.has_header_name())
return false;
if (!net::HttpUtil::IsValidHeaderName(
cr_fuchsia::BytesAsString(remove_header.header_name())))
return false;
return true;
}
bool ValidateSubstituteQueryPattern(
const fuchsia::web::UrlRequestRewriteSubstituteQueryPattern&
substitute_query_pattern) {
if (!substitute_query_pattern.has_pattern() ||
!substitute_query_pattern.has_substitution())
return false;
return true;
}
bool ValidateReplaceUrl(
const fuchsia::web::UrlRequestRewriteReplaceUrl& replace_url) {
if (!replace_url.has_url_ends_with() || !replace_url.has_new_url())
return false;
if (!GURL("http://site.com/" + replace_url.url_ends_with()).is_valid())
return false;
if (!GURL(replace_url.new_url()).is_valid())
return false;
return true;
}
bool ValidateRewrite(const fuchsia::web::UrlRequestRewrite& rewrite) {
switch (rewrite.Which()) {
case fuchsia::web::UrlRequestRewrite::Tag::kAddHeaders:
return ValidateAddHeaders(rewrite.add_headers());
case fuchsia::web::UrlRequestRewrite::Tag::kRemoveHeader:
return ValidateRemoveHeader(rewrite.remove_header());
case fuchsia::web::UrlRequestRewrite::Tag::kSubstituteQueryPattern:
return ValidateSubstituteQueryPattern(rewrite.substitute_query_pattern());
case fuchsia::web::UrlRequestRewrite::Tag::kReplaceUrl:
return ValidateReplaceUrl(rewrite.replace_url());
default:
// This is to prevent build breakage when adding new rewrites to the FIDL
// definition. This can also happen if the client sends an empty rewrite,
// which is invalid.
return false;
}
}
bool ValidateRules(
const std::vector<fuchsia::web::UrlRequestRewriteRule>& rules) {
for (const auto& rule : rules) {
if (rule.has_hosts_filter() && rule.hosts_filter().empty())
return false;
if (rule.has_schemes_filter() && rule.schemes_filter().empty())
return false;
if (!rule.has_rewrites())
return false;
for (const auto& rewrite : rule.rewrites()) {
if (!ValidateRewrite(rewrite))
return false;
}
}
return true;
}
} // namespace
// static
UrlRequestRewriteRulesManager*
UrlRequestRewriteRulesManager::ForFrameTreeNodeId(int frame_tree_node_id) {
auto iter = GetRewriterMap().find(frame_tree_node_id);
if (iter == GetRewriterMap().end())
return nullptr;
return iter->second;
}
// static
std::unique_ptr<UrlRequestRewriteRulesManager>
UrlRequestRewriteRulesManager::CreateForTesting() {
return base::WrapUnique(new UrlRequestRewriteRulesManager());
}
UrlRequestRewriteRulesManager::UrlRequestRewriteRulesManager(
content::WebContents* web_contents)
: content::WebContentsObserver(web_contents) {}
UrlRequestRewriteRulesManager::~UrlRequestRewriteRulesManager() = default;
zx_status_t UrlRequestRewriteRulesManager::OnRulesUpdated(
std::vector<fuchsia::web::UrlRequestRewriteRule> rules,
fuchsia::web::Frame::SetUrlRequestRewriteRulesCallback callback) {
if (!ValidateRules(rules)) {
base::AutoLock auto_lock(lock_);
cached_rules_ = nullptr;
return ZX_ERR_INVALID_ARGS;
}
base::AutoLock auto_lock(lock_);
cached_rules_ =
base::MakeRefCounted<WebEngineURLLoaderThrottle::UrlRequestRewriteRules>(
mojo::ConvertTo<std::vector<mojom::UrlRequestRewriteRulePtr>>(
std::move(rules)));
// Send the updated rules to the receivers.
for (const auto& receiver_pair : rules_receivers_per_frame_id_) {
receiver_pair.second->OnRulesUpdated(mojo::Clone(cached_rules_->data));
}
// TODO(crbug.com/976975): Only call the callback when there are pending
// throttles.
std::move(callback)();
return ZX_OK;
}
scoped_refptr<WebEngineURLLoaderThrottle::UrlRequestRewriteRules>
UrlRequestRewriteRulesManager::GetCachedRules() {
base::AutoLock auto_lock(lock_);
return cached_rules_;
}
UrlRequestRewriteRulesManager::UrlRequestRewriteRulesManager() {}
void UrlRequestRewriteRulesManager::RenderFrameCreated(
content::RenderFrameHost* render_frame_host) {
int frame_tree_node_id = render_frame_host->GetFrameTreeNodeId();
if (rules_receivers_per_frame_id_.find(frame_tree_node_id) !=
rules_receivers_per_frame_id_.end()) {
// This happens on cross-process navigations. It is not necessary to refresh
// the global map in this case as RenderFrameDeleted will not have been
// called for this RenderFrameHost.
size_t deleted = rules_receivers_per_frame_id_.erase(frame_tree_node_id);
DCHECK(deleted == 1);
} else {
// Register this instance of UrlRequestRewriteRulesManager as the URL
// request rewriter handler for this RenderFrameHost ID.
auto iter =
GetRewriterMap().emplace(std::make_pair(frame_tree_node_id, this));
DCHECK(iter.second);
}
// Register the frame rules receiver.
mojom::UrlRequestRulesReceiverAssociatedPtr rules_receiver;
render_frame_host->GetRemoteAssociatedInterfaces()->GetInterface(
&rules_receiver);
auto iter = rules_receivers_per_frame_id_.emplace(frame_tree_node_id,
std::move(rules_receiver));
DCHECK(iter.second);
base::AutoLock auto_lock(lock_);
if (cached_rules_) {
// Send an initial set of rules.
iter.first->second->OnRulesUpdated(mojo::Clone(cached_rules_->data));
}
}
void UrlRequestRewriteRulesManager::RenderFrameDeleted(
content::RenderFrameHost* render_frame_host) {
int frame_tree_node_id = render_frame_host->GetFrameTreeNodeId();
size_t deleted = GetRewriterMap().erase(frame_tree_node_id);
DCHECK(deleted == 1);
deleted = rules_receivers_per_frame_id_.erase(frame_tree_node_id);
DCHECK(deleted == 1);
}
// Copyright 2019 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 FUCHSIA_ENGINE_BROWSER_URL_REQUEST_REWRITE_RULES_MANAGER_H_
#define FUCHSIA_ENGINE_BROWSER_URL_REQUEST_REWRITE_RULES_MANAGER_H_
#include <fuchsia/web/cpp/fidl.h>
#include "base/synchronization/lock.h"
#include "content/public/browser/web_contents_binding_set.h"
#include "fuchsia/engine/common/web_engine_url_loader_throttle.h"
#include "fuchsia/engine/url_request_rewrite.mojom.h"
#include "fuchsia/engine/web_engine_export.h"
namespace content {
class RenderFrameHost;
class WebContents;
} // namespace content
// Adapts the UrlRequestRewrite FIDL API to be sent to the renderers over the
// over the UrlRequestRewrite Mojo API.
class WEB_ENGINE_EXPORT UrlRequestRewriteRulesManager
: public content::WebContentsObserver,
public WebEngineURLLoaderThrottle::CachedRulesProvider {
public:
static UrlRequestRewriteRulesManager* ForFrameTreeNodeId(
int frame_tree_node_id);
static std::unique_ptr<UrlRequestRewriteRulesManager> CreateForTesting();
explicit UrlRequestRewriteRulesManager(content::WebContents* web_contents);
~UrlRequestRewriteRulesManager() final;
// Signals |rules| have been updated. Actual implementation for
// fuchsia.web.Frame/SetUrlRequestRewriteRules.
// Return ZX_OK on success and an error code otherwise.
zx_status_t OnRulesUpdated(
std::vector<fuchsia::web::UrlRequestRewriteRule> rules,
fuchsia::web::Frame::SetUrlRequestRewriteRulesCallback callback);
// WebEngineURLLoaderThrottle::CachedRulesProvider implementation.
scoped_refptr<WebEngineURLLoaderThrottle::UrlRequestRewriteRules>
GetCachedRules() override;
private:
// Test-only constructor.
explicit UrlRequestRewriteRulesManager();
// content::WebContentsObserver implementation.
void RenderFrameCreated(content::RenderFrameHost* render_frame_host) override;
void RenderFrameDeleted(content::RenderFrameHost* render_frame_host) override;
base::Lock lock_;
scoped_refptr<WebEngineURLLoaderThrottle::UrlRequestRewriteRules>
cached_rules_ GUARDED_BY(lock_);
// Map of frames rules receivers per FrameTreeNode ID.
std::map<int, mojom::UrlRequestRulesReceiverAssociatedPtr>
rules_receivers_per_frame_id_;
DISALLOW_COPY_AND_ASSIGN(UrlRequestRewriteRulesManager);
};
#endif // FUCHSIA_ENGINE_BROWSER_URL_REQUEST_REWRITE_RULES_MANAGER_H_
// Copyright 2019 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.
#include "fuchsia/engine/browser/url_request_rewrite_rules_manager.h"
#include <lib/fidl/cpp/binding.h>
#include "base/run_loop.h"
#include "base/test/task_environment.h"
#include "fuchsia/base/url_request_rewrite_test_util.h"
#include "testing/gtest/include/gtest/gtest.h"
class UrlRequestRewriteRulesManagerTest : public testing::Test {
public:
UrlRequestRewriteRulesManagerTest()
: task_environment_(base::test::TaskEnvironment::MainThreadType::IO),
url_request_rewrite_rules_manager_(
UrlRequestRewriteRulesManager::CreateForTesting()) {}
~UrlRequestRewriteRulesManagerTest() override = default;
protected:
zx_status_t UpdateRulesFromRewrite(fuchsia::web::UrlRequestRewrite rewrite) {
std::vector<fuchsia::web::UrlRequestRewrite> rewrites;
rewrites.push_back(std::move(rewrite));
fuchsia::web::UrlRequestRewriteRule rule;
rule.set_rewrites(std::move(rewrites));
std::vector<fuchsia::web::UrlRequestRewriteRule> rules;
rules.push_back(std::move(rule));
return url_request_rewrite_rules_manager_->OnRulesUpdated(std::move(rules),
[]() {});
}
base::test::SingleThreadTaskEnvironment task_environment_;
std::unique_ptr<UrlRequestRewriteRulesManager>
url_request_rewrite_rules_manager_;
DISALLOW_COPY_AND_ASSIGN(UrlRequestRewriteRulesManagerTest);
};
// Tests AddHeaders rewrites are properly converted to their Mojo equivalent.
TEST_F(UrlRequestRewriteRulesManagerTest, ConvertAddHeader) {
EXPECT_EQ(UpdateRulesFromRewrite(
cr_fuchsia::CreateRewriteAddHeaders("Test", "Value")),
ZX_OK);
scoped_refptr<WebEngineURLLoaderThrottle::UrlRequestRewriteRules>
cached_rules = url_request_rewrite_rules_manager_->GetCachedRules();
ASSERT_EQ(cached_rules->data.size(), 1u);
ASSERT_FALSE(cached_rules->data[0]->hosts_filter);
ASSERT_FALSE(cached_rules->data[0]->schemes_filter);
ASSERT_EQ(cached_rules->data[0]->rewrites.size(), 1u);
ASSERT_TRUE(cached_rules->data[0]->rewrites[0]->is_add_headers());
const net::HttpRequestHeaders& headers =
cached_rules->data[0]->rewrites[0]->get_add_headers()->headers;
ASSERT_EQ(headers.GetHeaderVector().size(), 1u);
std::string value;
ASSERT_TRUE(headers.GetHeader("Test", &value));
ASSERT_EQ(value.compare("Value"), 0);
}
// Tests RemoveHeader rewrites are properly converted to their Mojo equivalent.
TEST_F(UrlRequestRewriteRulesManagerTest, ConvertRemoveHeader) {
EXPECT_EQ(UpdateRulesFromRewrite(cr_fuchsia::CreateRewriteRemoveHeader(
base::make_optional("Test"), "Header")),
ZX_OK);
scoped_refptr<WebEngineURLLoaderThrottle::UrlRequestRewriteRules>
cached_rules = url_request_rewrite_rules_manager_->GetCachedRules();
ASSERT_EQ(cached_rules->data.size(), 1u);
ASSERT_FALSE(cached_rules->data[0]->hosts_filter);
ASSERT_FALSE(cached_rules->data[0]->schemes_filter);
ASSERT_EQ(cached_rules->data[0]->rewrites.size(), 1u);
ASSERT_TRUE(cached_rules->data[0]->rewrites[0]->is_remove_header());
const mojom::UrlRequestRewriteRemoveHeaderPtr& remove_header1 =
cached_rules->data[0]->rewrites[0]->get_remove_header();
ASSERT_TRUE(remove_header1->query_pattern);
ASSERT_EQ(remove_header1->query_pattern.value().compare("Test"), 0);
ASSERT_EQ(remove_header1->header_name.compare("Header"), 0);
// Create a RemoveHeader rewrite with no pattern.
EXPECT_EQ(UpdateRulesFromRewrite(
cr_fuchsia::CreateRewriteRemoveHeader(base::nullopt, "Header")),
ZX_OK);
cached_rules = url_request_rewrite_rules_manager_->GetCachedRules();
ASSERT_EQ(cached_rules->data.size(), 1u);
ASSERT_FALSE(cached_rules->data[0]->hosts_filter);
ASSERT_FALSE(cached_rules->data[0]->schemes_filter);
ASSERT_EQ(cached_rules->data[0]->rewrites.size(), 1u);
ASSERT_TRUE(cached_rules->data[0]->rewrites[0]->is_remove_header());
const mojom::UrlRequestRewriteRemoveHeaderPtr& remove_header2 =
cached_rules->data[0]->rewrites[0]->get_remove_header();
ASSERT_FALSE(remove_header2->query_pattern);
ASSERT_EQ(remove_header2->header_name.compare("Header"), 0);
}
// Tests SubstituteQueryPattern rewrites are properly converted to their Mojo
// equivalent.
TEST_F(UrlRequestRewriteRulesManagerTest, ConvertSubstituteQueryPattern) {
EXPECT_EQ(
UpdateRulesFromRewrite(cr_fuchsia::CreateRewriteSubstituteQueryPattern(
"Pattern", "Substitution")),
ZX_OK);
scoped_refptr<WebEngineURLLoaderThrottle::UrlRequestRewriteRules>
cached_rules = url_request_rewrite_rules_manager_->GetCachedRules();
ASSERT_EQ(cached_rules->data.size(), 1u);
ASSERT_FALSE(cached_rules->data[0]->hosts_filter);
ASSERT_FALSE(cached_rules->data[0]->schemes_filter);
ASSERT_EQ(cached_rules->data[0]->rewrites.size(), 1u);
ASSERT_TRUE(
cached_rules->data[0]->rewrites[0]->is_substitute_query_pattern());
const mojom::UrlRequestRewriteSubstituteQueryPatternPtr&
substitute_query_pattern =
cached_rules->data[0]->rewrites[0]->get_substitute_query_pattern();
ASSERT_EQ(substitute_query_pattern->pattern.compare("Pattern"), 0);
ASSERT_EQ(substitute_query_pattern->substitution.compare("Substitution"), 0);
}
// Tests ReplaceUrl rewrites are properly converted to their Mojo equivalent.
TEST_F(UrlRequestRewriteRulesManagerTest, ConvertReplaceUrl) {
GURL url("http://site.xyz");
EXPECT_EQ(UpdateRulesFromRewrite(
cr_fuchsia::CreateRewriteReplaceUrl("/something", url.spec())),
ZX_OK);
scoped_refptr<WebEngineURLLoaderThrottle::UrlRequestRewriteRules>
cached_rules = url_request_rewrite_rules_manager_->GetCachedRules();
ASSERT_EQ(cached_rules->data.size(), 1u);
ASSERT_FALSE(cached_rules->data[0]->hosts_filter);
ASSERT_FALSE(cached_rules->data[0]->schemes_filter);
ASSERT_EQ(cached_rules->data[0]->rewrites.size(), 1u);
ASSERT_TRUE(cached_rules->data[0]->rewrites[0]->is_replace_url());
const mojom::UrlRequestRewriteReplaceUrlPtr& replace_url =
cached_rules->data[0]->rewrites[0]->get_replace_url();
ASSERT_EQ(replace_url->url_ends_with.compare("/something"), 0);
ASSERT_EQ(replace_url->new_url.spec().compare(url.spec()), 0);
}
// Tests validation is working as expected.
TEST_F(UrlRequestRewriteRulesManagerTest, Validation) {
// Empty rewrite.
EXPECT_EQ(UpdateRulesFromRewrite(fuchsia::web::UrlRequestRewrite()),
ZX_ERR_INVALID_ARGS);
// Invalid AddHeaders header name.
EXPECT_EQ(UpdateRulesFromRewrite(
cr_fuchsia::CreateRewriteAddHeaders("Te\nst1", "Value")),
ZX_ERR_INVALID_ARGS);
// Invalid AddHeaders header value.
EXPECT_EQ(UpdateRulesFromRewrite(
cr_fuchsia::CreateRewriteAddHeaders("Test1", "Val\nue")),
ZX_ERR_INVALID_ARGS);
// Empty AddHeaders.
{
fuchsia::web::UrlRequestRewrite rewrite;
rewrite.set_add_headers(fuchsia::web::UrlRequestRewriteAddHeaders());
EXPECT_EQ(UpdateRulesFromRewrite(std::move(rewrite)), ZX_ERR_INVALID_ARGS);
}
// Invalid RemoveHeader header name.
EXPECT_EQ(UpdateRulesFromRewrite(
cr_fuchsia::CreateRewriteRemoveHeader("Query", "Head\ner")),
ZX_ERR_INVALID_ARGS);
// Empty RemoveHeader.
{
fuchsia::web::UrlRequestRewrite rewrite;
rewrite.set_add_headers(fuchsia::web::UrlRequestRewriteAddHeaders());
EXPECT_EQ(UpdateRulesFromRewrite(std::move(rewrite)), ZX_ERR_INVALID_ARGS);
}
// Empty SubstituteQueryPattern.
{
fuchsia::web::UrlRequestRewrite rewrite;
rewrite.set_substitute_query_pattern(
fuchsia::web::UrlRequestRewriteSubstituteQueryPattern());
EXPECT_EQ(UpdateRulesFromRewrite(std::move(rewrite)), ZX_ERR_INVALID_ARGS);
}
// Invalid ReplaceUrl url_ends_with.
EXPECT_EQ(UpdateRulesFromRewrite(cr_fuchsia::CreateRewriteReplaceUrl(
"some%00thing", GURL("http://site.xyz").spec())),
ZX_ERR_INVALID_ARGS);
// Invalid ReplaceUrl new_url.
EXPECT_EQ(UpdateRulesFromRewrite(cr_fuchsia::CreateRewriteReplaceUrl(
"/something", "http:site:xyz")),
ZX_ERR_INVALID_ARGS);
// Empty ReplaceUrl.
{
fuchsia::web::UrlRequestRewrite rewrite;
rewrite.set_replace_url(fuchsia::web::UrlRequestRewriteReplaceUrl());
EXPECT_EQ(UpdateRulesFromRewrite(std::move(rewrite)), ZX_ERR_INVALID_ARGS);
}
}
// Tests rules are properly renewed after new rules are sent.
TEST_F(UrlRequestRewriteRulesManagerTest, RuleRenewal) {
EXPECT_EQ(UpdateRulesFromRewrite(
cr_fuchsia::CreateRewriteAddHeaders("Test1", "Value")),
ZX_OK);
scoped_refptr<WebEngineURLLoaderThrottle::UrlRequestRewriteRules>
cached_rules = url_request_rewrite_rules_manager_->GetCachedRules();
ASSERT_EQ(cached_rules->data.size(), 1u);
ASSERT_EQ(cached_rules->data[0]->rewrites.size(), 1u);
ASSERT_TRUE(cached_rules->data[0]->rewrites[0]->is_add_headers());
ASSERT_TRUE(
cached_rules->data[0]->rewrites[0]->get_add_headers()->headers.HasHeader(
"Test1"));
EXPECT_EQ(UpdateRulesFromRewrite(
cr_fuchsia::CreateRewriteAddHeaders("Test2", "Value")),
ZX_OK);
// We should have the new rules.
cached_rules = url_request_rewrite_rules_manager_->GetCachedRules();
ASSERT_EQ(cached_rules->data.size(), 1u);
ASSERT_EQ(cached_rules->data[0]->rewrites.size(), 1u);
ASSERT_TRUE(cached_rules->data[0]->rewrites[0]->is_add_headers());
ASSERT_TRUE(
cached_rules->data[0]->rewrites[0]->get_add_headers()->headers.HasHeader(
"Test2"));
}
...@@ -11,10 +11,12 @@ ...@@ -11,10 +11,12 @@
#include "components/version_info/version_info.h" #include "components/version_info/version_info.h"
#include "content/public/common/user_agent.h" #include "content/public/common/user_agent.h"
#include "content/public/common/web_preferences.h" #include "content/public/common/web_preferences.h"
#include "fuchsia/engine/browser/url_request_rewrite_rules_manager.h"
#include "fuchsia/engine/browser/web_engine_browser_context.h" #include "fuchsia/engine/browser/web_engine_browser_context.h"
#include "fuchsia/engine/browser/web_engine_browser_main_parts.h" #include "fuchsia/engine/browser/web_engine_browser_main_parts.h"
#include "fuchsia/engine/browser/web_engine_devtools_manager_delegate.h" #include "fuchsia/engine/browser/web_engine_devtools_manager_delegate.h"
#include "fuchsia/engine/common.h" #include "fuchsia/engine/common.h"
#include "fuchsia/engine/common/web_engine_url_loader_throttle.h"
#include "fuchsia/engine/switches.h" #include "fuchsia/engine/switches.h"
WebEngineContentBrowserClient::WebEngineContentBrowserClient( WebEngineContentBrowserClient::WebEngineContentBrowserClient(
...@@ -104,3 +106,28 @@ void WebEngineContentBrowserClient::AppendExtraCommandLineSwitches( ...@@ -104,3 +106,28 @@ void WebEngineContentBrowserClient::AppendExtraCommandLineSwitches(
command_line->AppendSwitch(switches::kDisableSoftwareVideoDecoders); command_line->AppendSwitch(switches::kDisableSoftwareVideoDecoders);
} }
} }
std::vector<std::unique_ptr<blink::URLLoaderThrottle>>
WebEngineContentBrowserClient::CreateURLLoaderThrottles(
const network::ResourceRequest& request,
content::BrowserContext* browser_context,
const base::RepeatingCallback<content::WebContents*()>& wc_getter,
content::NavigationUIData* navigation_ui_data,
int frame_tree_node_id) {
if (frame_tree_node_id == content::RenderFrameHost::kNoFrameTreeNodeId) {
// TODO(crbug.com/976975): Add support for service workers.
return {};
}
UrlRequestRewriteRulesManager* adapter =
UrlRequestRewriteRulesManager::ForFrameTreeNodeId(frame_tree_node_id);
if (!adapter) {
// No popup support for rules rewriter.
return {};
}
std::vector<std::unique_ptr<blink::URLLoaderThrottle>> throttles;
throttles.emplace_back(std::make_unique<WebEngineURLLoaderThrottle>(
UrlRequestRewriteRulesManager::ForFrameTreeNodeId(frame_tree_node_id)));
return throttles;
}
...@@ -48,6 +48,13 @@ class WebEngineContentBrowserClient : public content::ContentBrowserClient { ...@@ -48,6 +48,13 @@ class WebEngineContentBrowserClient : public content::ContentBrowserClient {
NonNetworkURLLoaderFactoryMap* factories) final; NonNetworkURLLoaderFactoryMap* factories) final;
void AppendExtraCommandLineSwitches(base::CommandLine* command_line, void AppendExtraCommandLineSwitches(base::CommandLine* command_line,
int child_process_id) final; int child_process_id) final;
std::vector<std::unique_ptr<blink::URLLoaderThrottle>>
CreateURLLoaderThrottles(
const network::ResourceRequest& request,
content::BrowserContext* browser_context,
const base::RepeatingCallback<content::WebContents*()>& wc_getter,
content::NavigationUIData* navigation_ui_data,
int frame_tree_node_id) final;
private: private:
fidl::InterfaceRequest<fuchsia::web::Context> request_; fidl::InterfaceRequest<fuchsia::web::Context> request_;
......
include_rules = [
"+third_party/blink/public/common/loader",
]
// Copyright 2019 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.
#include "fuchsia/engine/common/web_engine_url_loader_throttle.h"
#include "base/strings/string_util.h"
namespace {
// Returnns a string representing the URL stripped of query and ref.
std::string ClearUrlQueryRef(const GURL& url) {
GURL::Replacements replacements;
replacements.ClearQuery();
replacements.ClearRef();
return url.ReplaceComponents(replacements).spec();
}
void ApplyAddHeaders(network::ResourceRequest* request,
const mojom::UrlRequestRewriteAddHeadersPtr& add_headers) {
request->headers.MergeFrom(add_headers->headers);
}
void ApplyRemoveHeader(
network::ResourceRequest* request,
const mojom::UrlRequestRewriteRemoveHeaderPtr& remove_header) {
base::Optional<std::string> query_pattern = remove_header->query_pattern;
if (query_pattern &&
request->url.query().find(query_pattern.value()) == std::string::npos) {
return;
}
request->headers.RemoveHeader(remove_header->header_name);
}
void ApplySubstituteQueryPattern(
network::ResourceRequest* request,
const mojom::UrlRequestRewriteSubstituteQueryPatternPtr&
substitute_query_pattern) {
std::string url_query = request->url.query();
base::ReplaceSubstringsAfterOffset(&url_query, 0,
substitute_query_pattern->pattern,
substitute_query_pattern->substitution);
GURL::Replacements replacements;
replacements.SetQueryStr(url_query);
request->url = request->url.ReplaceComponents(replacements);
}
void ApplyReplaceUrl(network::ResourceRequest* request,
const mojom::UrlRequestRewriteReplaceUrlPtr& replace_url) {
if (!base::EndsWith(ClearUrlQueryRef(request->url),
replace_url->url_ends_with, base::CompareCase::SENSITIVE))
return;
GURL new_url = replace_url->new_url;
if (new_url.has_scheme() &&
new_url.scheme().compare(request->url.scheme()) != 0) {
// No cross-scheme redirect allowed.
return;
}
GURL::Replacements replacements;
std::string host = new_url.host();
replacements.SetHostStr(host);
std::string port = new_url.port();
replacements.SetPortStr(port);
std::string path = new_url.path();
replacements.SetPathStr(path);
request->url = request->url.ReplaceComponents(replacements);
}
void ApplyRewrite(network::ResourceRequest* request,
const mojom::UrlRequestRewritePtr& rewrite) {
switch (rewrite->which()) {
case mojom::UrlRequestRewrite::Tag::ADD_HEADERS:
ApplyAddHeaders(request, rewrite->get_add_headers());
break;
case mojom::UrlRequestRewrite::Tag::REMOVE_HEADER:
ApplyRemoveHeader(request, rewrite->get_remove_header());
break;
case mojom::UrlRequestRewrite::Tag::SUBSTITUTE_QUERY_PATTERN:
ApplySubstituteQueryPattern(request,
rewrite->get_substitute_query_pattern());
break;
case mojom::UrlRequestRewrite::Tag::REPLACE_URL:
ApplyReplaceUrl(request, rewrite->get_replace_url());
break;
}
}
void ApplyRule(network::ResourceRequest* request,
const mojom::UrlRequestRewriteRulePtr& rule) {
const GURL& url = request->url;
if (rule->hosts_filter) {
bool found = false;
for (const auto& host : rule->hosts_filter.value()) {
if (url.host().compare(host) == 0) {
found = true;
break;
}
}
if (!found)
return;
}
if (rule->schemes_filter) {
bool found = false;
for (const auto& scheme : rule->schemes_filter.value()) {
if (url.scheme().compare(scheme) == 0) {
found = true;
break;
}
}
if (!found)
return;
}
for (const auto& rewrite : rule->rewrites) {
ApplyRewrite(request, rewrite);
}
}
void ApplyRules(network::ResourceRequest* request,
const std::vector<mojom::UrlRequestRewriteRulePtr>& rules) {
for (const auto& rule : rules) {
ApplyRule(request, rule);
}
}
} // namespace
WebEngineURLLoaderThrottle::WebEngineURLLoaderThrottle(
CachedRulesProvider* cached_rules_provider)
: cached_rules_provider_(cached_rules_provider) {
DCHECK(cached_rules_provider);
}
WebEngineURLLoaderThrottle::~WebEngineURLLoaderThrottle() = default;
void WebEngineURLLoaderThrottle::DetachFromCurrentSequence() {}
void WebEngineURLLoaderThrottle::WillStartRequest(
network::ResourceRequest* request,
bool* defer) {
scoped_refptr<WebEngineURLLoaderThrottle::UrlRequestRewriteRules>
cached_rules = cached_rules_provider_->GetCachedRules();
// |cached_rules| may be empty if no rule was ever sent to WebEngine.
if (cached_rules)
ApplyRules(request, cached_rules->data);
*defer = false;
}
bool WebEngineURLLoaderThrottle::makes_unsafe_redirect() {
// WillStartRequest() does not make cross-scheme redirects.
return false;
}
// Copyright 2019 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 FUCHSIA_ENGINE_COMMON_WEB_ENGINE_URL_LOADER_THROTTLE_H_
#define FUCHSIA_ENGINE_COMMON_WEB_ENGINE_URL_LOADER_THROTTLE_H_
#include <vector>
#include "base/memory/ref_counted.h"
#include "fuchsia/engine/url_request_rewrite.mojom.h"
#include "third_party/blink/public/common/loader/url_loader_throttle.h"
// Implements a URLLoaderThrottle for the WebEngine. Applies network request
// rewrites provided through the fuchsia.web.SetUrlRequestRewriteRules FIDL API.
class WebEngineURLLoaderThrottle : public blink::URLLoaderThrottle {
public:
using UrlRequestRewriteRules =
base::RefCountedData<std::vector<mojom::UrlRequestRewriteRulePtr>>;
// An interface to provide rewrite rules to the throttle. Its
// implementation must outlive the WebEngineURLLoaderThrottle.
class CachedRulesProvider {
public:
virtual ~CachedRulesProvider() = default;
// Gets cached rules. This call can be made on any sequence, as
// URLLoaderThrottles are not guaranteed to stay on the same sequence.
virtual scoped_refptr<UrlRequestRewriteRules> GetCachedRules() = 0;
};
explicit WebEngineURLLoaderThrottle(
CachedRulesProvider* cached_rules_provider);
~WebEngineURLLoaderThrottle() override;
private:
// blink::URLLoaderThrottle implementation.
void DetachFromCurrentSequence() override;
void WillStartRequest(network::ResourceRequest* request,
bool* defer) override;
bool makes_unsafe_redirect() override;
CachedRulesProvider* const cached_rules_provider_;
DISALLOW_COPY_AND_ASSIGN(WebEngineURLLoaderThrottle);
};
#endif // FUCHSIA_ENGINE_COMMON_WEB_ENGINE_URL_LOADER_THROTTLE_H_
// Copyright 2019 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.
#include "fuchsia/engine/renderer/url_request_rules_receiver.h"
#include "content/public/renderer/render_frame.h"
#include "fuchsia/engine/renderer/web_engine_content_renderer_client.h"
#include "fuchsia/engine/url_request_rewrite.mojom.h"
#include "third_party/blink/public/common/associated_interfaces/associated_interface_provider.h"
#include "third_party/blink/public/common/associated_interfaces/associated_interface_registry.h"
UrlRequestRulesReceiver::UrlRequestRulesReceiver(
content::RenderFrame* render_frame,
base::OnceCallback<void(int)> on_render_frame_deleted_callback)
: content::RenderFrameObserver(render_frame),
associated_binding_(this),
on_render_frame_deleted_callback_(
std::move(on_render_frame_deleted_callback)) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
DCHECK(on_render_frame_deleted_callback_);
DCHECK(render_frame);
// It is fine to use an unretained pointer to |this| here as the
// AssociatedInterfaceRegistry, owned by |render_frame| will be torn-down at
// the same time as |this|.
render_frame->GetAssociatedInterfaceRegistry()->AddInterface(
base::BindRepeating(
&UrlRequestRulesReceiver::OnUrlRequestRulesReceiverAssociatedRequest,
base::Unretained(this)));
}
UrlRequestRulesReceiver::~UrlRequestRulesReceiver() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
}
void UrlRequestRulesReceiver::OnUrlRequestRulesReceiverAssociatedRequest(
mojom::UrlRequestRulesReceiverAssociatedRequest request) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
DCHECK(!associated_binding_.is_bound());
associated_binding_.Bind(std::move(request));
}
void UrlRequestRulesReceiver::OnRulesUpdated(
std::vector<mojom::UrlRequestRewriteRulePtr> rules) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
base::AutoLock auto_lock(lock_);
cached_rules_ =
base::MakeRefCounted<WebEngineURLLoaderThrottle::UrlRequestRewriteRules>(
std::move(rules));
}
scoped_refptr<WebEngineURLLoaderThrottle::UrlRequestRewriteRules>
UrlRequestRulesReceiver::GetCachedRules() {
base::AutoLock auto_lock(lock_);
return cached_rules_;
}
void UrlRequestRulesReceiver::OnDestruct() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
// The RenderFrame corresponding to this object was destroyed, which means
// the AssociatedInterfaceRegsitry is also gone. It is expected that
// |on_render_frame_deleted_callback_| will delete |this|.
std::move(on_render_frame_deleted_callback_).Run(routing_id());
}
// Copyright 2019 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 FUCHSIA_ENGINE_RENDERER_URL_REQUEST_RULES_RECEIVER_H_
#define FUCHSIA_ENGINE_RENDERER_URL_REQUEST_RULES_RECEIVER_H_
#include "base/sequence_checker.h"
#include "base/synchronization/lock.h"
#include "base/thread_annotations.h"
#include "content/public/renderer/render_frame_observer.h"
#include "fuchsia/engine/common/web_engine_url_loader_throttle.h"
#include "fuchsia/engine/url_request_rewrite.mojom.h"
#include "mojo/public/cpp/bindings/associated_binding.h"
#include "services/service_manager/public/cpp/binder_registry.h"
namespace content {
class RenderFrame;
} // namespace content
// Provides rewriting rules for network requests. UrlRequestRulesReceiver
// objects are owned by their respective WebEngineContentRendererClient and they
// will be destroyed on RenderFrame destruction. This is guaranteed to outlive
// any WebEngineURLLoaderThrottle that uses it as the RenderFrame destruction
// will have triggered the destruction of all pending
// WebEngineURLLoaderThrottles.
// This class should only be used on the IO thread, with the exception of the
// GetCachedRules() implementation, which can be called from any sequence.
class UrlRequestRulesReceiver
: public mojom::UrlRequestRulesReceiver,
public WebEngineURLLoaderThrottle::CachedRulesProvider,
public content::RenderFrameObserver {
public:
UrlRequestRulesReceiver(
content::RenderFrame* render_frame,
base::OnceCallback<void(int)> on_render_frame_deleted_callback);
~UrlRequestRulesReceiver() override;
private:
void OnUrlRequestRulesReceiverAssociatedRequest(
mojom::UrlRequestRulesReceiverAssociatedRequest request);
// mojom::UrlRequestRulesReceiver implementation.
void OnRulesUpdated(
std::vector<mojom::UrlRequestRewriteRulePtr> rules) override;
// WebEngineURLLoaderThrottle::CachedRulesProvider implementation.
scoped_refptr<WebEngineURLLoaderThrottle::UrlRequestRewriteRules>
GetCachedRules() override;
// content::RenderFrameObserver implementation.
void OnDestruct() override;
base::Lock lock_;
// This is accessed by WebEngineURLLoaderThrottles, which can be off-sequence
// in the case of synchronous network requests.
scoped_refptr<WebEngineURLLoaderThrottle::UrlRequestRewriteRules>
cached_rules_ GUARDED_BY(lock_);
mojo::AssociatedBinding<mojom::UrlRequestRulesReceiver> associated_binding_;
base::OnceCallback<void(int)> on_render_frame_deleted_callback_;
SEQUENCE_CHECKER(sequence_checker_);
DISALLOW_COPY_AND_ASSIGN(UrlRequestRulesReceiver);
};
#endif // FUCHSIA_ENGINE_RENDERER_URL_REQUEST_RULES_RECEIVER_H_
...@@ -4,13 +4,16 @@ ...@@ -4,13 +4,16 @@
#include "fuchsia/engine/renderer/web_engine_content_renderer_client.h" #include "fuchsia/engine/renderer/web_engine_content_renderer_client.h"
#include "base/feature_list.h"
#include "base/macros.h" #include "base/macros.h"
#include "components/cdm/renderer/widevine_key_system_properties.h" #include "components/cdm/renderer/widevine_key_system_properties.h"
#include "content/public/renderer/render_frame.h" #include "content/public/renderer/render_frame.h"
#include "fuchsia/engine/renderer/on_load_script_injector.h" #include "fuchsia/engine/renderer/on_load_script_injector.h"
#include "fuchsia/engine/renderer/web_engine_url_loader_throttle_provider.h"
#include "fuchsia/engine/switches.h" #include "fuchsia/engine/switches.h"
#include "media/base/eme_constants.h" #include "media/base/eme_constants.h"
#include "media/base/video_codecs.h" #include "media/base/video_codecs.h"
#include "services/network/public/cpp/features.h"
#include "services/service_manager/public/cpp/binder_registry.h" #include "services/service_manager/public/cpp/binder_registry.h"
#include "third_party/blink/public/common/associated_interfaces/associated_interface_registry.h" #include "third_party/blink/public/common/associated_interfaces/associated_interface_registry.h"
#include "third_party/widevine/cdm/widevine_cdm_common.h" #include "third_party/widevine/cdm/widevine_cdm_common.h"
...@@ -19,11 +22,45 @@ WebEngineContentRendererClient::WebEngineContentRendererClient() = default; ...@@ -19,11 +22,45 @@ WebEngineContentRendererClient::WebEngineContentRendererClient() = default;
WebEngineContentRendererClient::~WebEngineContentRendererClient() = default; WebEngineContentRendererClient::~WebEngineContentRendererClient() = default;
UrlRequestRulesReceiver*
WebEngineContentRendererClient::GetUrlRequestRulesReceiverForRenderFrameId(
int render_frame_id) const {
auto iter = url_request_receivers_by_id_.find(render_frame_id);
DCHECK(iter != url_request_receivers_by_id_.end());
return iter->second.get();
}
void WebEngineContentRendererClient::OnRenderFrameDeleted(int render_frame_id) {
size_t count = url_request_receivers_by_id_.erase(render_frame_id);
DCHECK_EQ(count, 1u);
}
void WebEngineContentRendererClient::RenderFrameCreated( void WebEngineContentRendererClient::RenderFrameCreated(
content::RenderFrame* render_frame) { content::RenderFrame* render_frame) {
// Add WebEngine services to the new RenderFrame. // Add WebEngine services to the new RenderFrame.
// The objects' lifetimes are bound to the RenderFrame's lifetime. // The objects' lifetimes are bound to the RenderFrame's lifetime.
new OnLoadScriptInjector(render_frame); new OnLoadScriptInjector(render_frame);
int render_frame_id = render_frame->GetRoutingID();
auto rules_receiver = std::make_unique<UrlRequestRulesReceiver>(
content::RenderFrame::FromRoutingID(render_frame_id),
base::BindOnce(&WebEngineContentRendererClient::OnRenderFrameDeleted,
base::Unretained(this)));
auto iter = url_request_receivers_by_id_.emplace(render_frame_id,
std::move(rules_receiver));
DCHECK(iter.second);
}
std::unique_ptr<content::URLLoaderThrottleProvider>
WebEngineContentRendererClient::CreateURLLoaderThrottleProvider(
content::URLLoaderThrottleProviderType type) {
DCHECK(base::FeatureList::IsEnabled(network::features::kNetworkService));
// TODO(crbug.com/976975): Add support for service workers.
if (type == content::URLLoaderThrottleProviderType::kWorker)
return nullptr;
return std::make_unique<WebEngineURLLoaderThrottleProvider>(this);
} }
void WebEngineContentRendererClient::AddSupportedKeySystems( void WebEngineContentRendererClient::AddSupportedKeySystems(
......
...@@ -7,20 +7,36 @@ ...@@ -7,20 +7,36 @@
#include "base/macros.h" #include "base/macros.h"
#include "content/public/renderer/content_renderer_client.h" #include "content/public/renderer/content_renderer_client.h"
#include "fuchsia/engine/renderer/url_request_rules_receiver.h"
class WebEngineContentRendererClient : public content::ContentRendererClient { class WebEngineContentRendererClient : public content::ContentRendererClient {
public: public:
WebEngineContentRendererClient(); WebEngineContentRendererClient();
~WebEngineContentRendererClient() override; ~WebEngineContentRendererClient() override;
// Returns the UrlRequestRulesReceiver corresponding to |render_frame_id|.
UrlRequestRulesReceiver* GetUrlRequestRulesReceiverForRenderFrameId(
int render_frame_id) const;
private:
// Called by UrlRequestRulesReceivers when their corresponding RenderFrame is
// in the process of being deleted.
void OnRenderFrameDeleted(int render_frame_id);
// content::ContentRendererClient overrides. // content::ContentRendererClient overrides.
void RenderFrameCreated(content::RenderFrame* render_frame) override; void RenderFrameCreated(content::RenderFrame* render_frame) override;
void AddSupportedKeySystems( void AddSupportedKeySystems(
std::vector<std::unique_ptr<media::KeySystemProperties>>* key_systems) std::vector<std::unique_ptr<media::KeySystemProperties>>* key_systems)
override; override;
bool IsSupportedVideoType(const media::VideoType& type) override; bool IsSupportedVideoType(const media::VideoType& type) override;
std::unique_ptr<content::URLLoaderThrottleProvider>
CreateURLLoaderThrottleProvider(
content::URLLoaderThrottleProviderType type) override;
// Map of rules receivers per RenderFrame ID.
std::map<int, std::unique_ptr<UrlRequestRulesReceiver>>
url_request_receivers_by_id_;
private:
DISALLOW_COPY_AND_ASSIGN(WebEngineContentRendererClient); DISALLOW_COPY_AND_ASSIGN(WebEngineContentRendererClient);
}; };
......
// Copyright 2019 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.
#include "fuchsia/engine/renderer/web_engine_url_loader_throttle_provider.h"
#include "content/public/renderer/render_frame.h"
#include "fuchsia/engine/common/web_engine_url_loader_throttle.h"
#include "fuchsia/engine/renderer/web_engine_content_renderer_client.h"
WebEngineURLLoaderThrottleProvider::WebEngineURLLoaderThrottleProvider(
WebEngineContentRendererClient* content_renderer_client)
: content_renderer_client_(content_renderer_client) {
DETACH_FROM_SEQUENCE(sequence_checker_);
}
WebEngineURLLoaderThrottleProvider::~WebEngineURLLoaderThrottleProvider() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
}
std::unique_ptr<content::URLLoaderThrottleProvider>
WebEngineURLLoaderThrottleProvider::Clone() {
// This should only happen for service workers, which we do not support here.
NOTREACHED();
return nullptr;
}
std::vector<std::unique_ptr<blink::URLLoaderThrottle>>
WebEngineURLLoaderThrottleProvider::CreateThrottles(
int render_frame_id,
const blink::WebURLRequest& request,
content::ResourceType resource_type) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
std::vector<std::unique_ptr<blink::URLLoaderThrottle>> throttles;
throttles.emplace_back(std::make_unique<WebEngineURLLoaderThrottle>(
content_renderer_client_->GetUrlRequestRulesReceiverForRenderFrameId(
render_frame_id)));
return throttles;
}
void WebEngineURLLoaderThrottleProvider::SetOnline(bool is_online) {}
// Copyright 2019 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 FUCHSIA_ENGINE_RENDERER_WEB_ENGINE_URL_LOADER_THROTTLE_PROVIDER_H_
#define FUCHSIA_ENGINE_RENDERER_WEB_ENGINE_URL_LOADER_THROTTLE_PROVIDER_H_
#include "base/macros.h"
#include "base/sequence_checker.h"
#include "content/public/renderer/url_loader_throttle_provider.h"
class WebEngineContentRendererClient;
// Implements a URLLoaderThrottleProvider for the WebEngine. Creates
// URLLoaderThrottles, implemented as WebEngineURLLoaderThrottles for network
// requests.
class WebEngineURLLoaderThrottleProvider
: public content::URLLoaderThrottleProvider {
public:
explicit WebEngineURLLoaderThrottleProvider(
WebEngineContentRendererClient* content_renderer_client);
~WebEngineURLLoaderThrottleProvider() override;
// content::URLLoaderThrottleProvider implementation.
std::unique_ptr<content::URLLoaderThrottleProvider> Clone() override;
std::vector<std::unique_ptr<blink::URLLoaderThrottle>> CreateThrottles(
int render_frame_id,
const blink::WebURLRequest& request,
content::ResourceType resource_type) override;
void SetOnline(bool is_online) override;
private:
const WebEngineContentRendererClient* const content_renderer_client_;
SEQUENCE_CHECKER(sequence_checker_);
DISALLOW_COPY_AND_ASSIGN(WebEngineURLLoaderThrottleProvider);
};
#endif // FUCHSIA_ENGINE_RENDERER_WEB_ENGINE_URL_LOADER_THROTTLE_PROVIDER_H_
<html>
<head><title>Image</title></head>
<body><img src="/img.png"></body>
</html>
// Copyright 2019 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.
module mojom;
import "mojo/public/mojom/base/time.mojom";
import "services/network/public/mojom/http_request_headers.mojom";
import "url/mojom/url.mojom";
// Used by the browser to push URL rewrite rules to renderers. There will be
// one receiver per web frame.
// TODO(https://crbug.com/976975): Support URL rewriting for service workers.
interface UrlRequestRulesReceiver {
// Receives a set of rules to apply to URL requests.
OnRulesUpdated(array<UrlRequestRewriteRule> rules);
};
// A URL request rewrite rule.
struct UrlRequestRewriteRule {
// Set of hosts to apply the rewrites to. If empty, the rule will apply to
// every request, independent of host.
array<string>? hosts_filter;
// Set of schemes to apply the rewrites to. If empty, the rule will apply to
// every request, independent of scheme.
array<string>? schemes_filter;
// URL request rewrites to apply.
array<UrlRequestRewrite> rewrites;
};
union UrlRequestRewrite {
// Adds a set of headers to a URL request.
UrlRequestRewriteAddHeaders add_headers;
// Removes a header based on the presence of a pattern in the URL query.
UrlRequestRewriteRemoveHeader remove_header;
// Substitutes a pattern in the URL query.
UrlRequestRewriteSubstituteQueryPattern substitute_query_pattern;
// Replaces a URL if the original URL ends with a pattern.
UrlRequestRewriteReplaceUrl replace_url;
};
// Adds |headers| to the URL request. If a header is already present in the
// original URL request, it will be overwritten.
struct UrlRequestRewriteAddHeaders {
// The headers to add.
network.mojom.HttpRequestHeaders headers;
};
// If |query_pattern| in the URL query, removes |header_name| from the list of
// headers. If |query_pattern| is empty, removes |header_name| from the list
// of headers unconditionally
struct UrlRequestRewriteRemoveHeader {
// The pattern to look for in the URL request.
string? query_pattern;
// The header to remove.
string header_name;
};
// If |pattern| is found in the URL request query, replaces it with
// |substitution|.
struct UrlRequestRewriteSubstituteQueryPattern {
// The pattern to look for in the URL request.
string pattern;
// The string to repalce |pattern| with.
string substitution;
};
// If the URL in the URL request ends with |url_ends_with|, rewrites the URL to
// |new_url|.
struct UrlRequestRewriteReplaceUrl {
// The pattern to look for in the URL.
string url_ends_with;
// The replacement URL.
url.mojom.Url new_url;
};
// Copyright 2019 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.
#include "fuchsia/engine/url_request_rewrite_type_converters.h"
namespace mojo {
mojom::UrlRequestRewriteAddHeadersPtr
TypeConverter<mojom::UrlRequestRewriteAddHeadersPtr,
fuchsia::web::UrlRequestRewriteAddHeaders>::
Convert(const fuchsia::web::UrlRequestRewriteAddHeaders& input) {
mojom::UrlRequestRewriteAddHeadersPtr add_headers =
mojom::UrlRequestRewriteAddHeaders::New();
if (input.has_headers()) {
for (const auto& header : input.headers()) {
base::StringPiece header_name = cr_fuchsia::BytesAsString(header.name);
base::StringPiece header_value = cr_fuchsia::BytesAsString(header.value);
add_headers->headers.SetHeader(header_name, header_value);
}
}
return add_headers;
}
mojom::UrlRequestRewriteRemoveHeaderPtr
TypeConverter<mojom::UrlRequestRewriteRemoveHeaderPtr,
fuchsia::web::UrlRequestRewriteRemoveHeader>::
Convert(const fuchsia::web::UrlRequestRewriteRemoveHeader& input) {
mojom::UrlRequestRewriteRemoveHeaderPtr remove_header =
mojom::UrlRequestRewriteRemoveHeader::New();
if (input.has_query_pattern())
remove_header->query_pattern = base::make_optional(input.query_pattern());
if (input.has_header_name())
remove_header->header_name =
cr_fuchsia::BytesAsString(input.header_name()).as_string();
return remove_header;
}
mojom::UrlRequestRewriteSubstituteQueryPatternPtr
TypeConverter<mojom::UrlRequestRewriteSubstituteQueryPatternPtr,
fuchsia::web::UrlRequestRewriteSubstituteQueryPattern>::
Convert(
const fuchsia::web::UrlRequestRewriteSubstituteQueryPattern& input) {
mojom::UrlRequestRewriteSubstituteQueryPatternPtr substitute_query_pattern =
mojom::UrlRequestRewriteSubstituteQueryPattern::New();
if (input.has_pattern())
substitute_query_pattern->pattern = input.pattern();
if (input.has_substitution())
substitute_query_pattern->substitution = input.substitution();
return substitute_query_pattern;
}
mojom::UrlRequestRewriteReplaceUrlPtr
TypeConverter<mojom::UrlRequestRewriteReplaceUrlPtr,
fuchsia::web::UrlRequestRewriteReplaceUrl>::
Convert(const fuchsia::web::UrlRequestRewriteReplaceUrl& input) {
mojom::UrlRequestRewriteReplaceUrlPtr replace_url =
mojom::UrlRequestRewriteReplaceUrl::New();
if (input.has_url_ends_with())
replace_url->url_ends_with = input.url_ends_with();
if (input.has_new_url())
replace_url->new_url = GURL(input.new_url());
return replace_url;
}
mojom::UrlRequestRewritePtr
TypeConverter<mojom::UrlRequestRewritePtr, fuchsia::web::UrlRequestRewrite>::
Convert(const fuchsia::web::UrlRequestRewrite& input) {
switch (input.Which()) {
case fuchsia::web::UrlRequestRewrite::Tag::kAddHeaders:
return mojom::UrlRequestRewrite::NewAddHeaders(
mojo::ConvertTo<mojom::UrlRequestRewriteAddHeadersPtr>(
input.add_headers()));
case fuchsia::web::UrlRequestRewrite::Tag::kRemoveHeader:
return mojom::UrlRequestRewrite::NewRemoveHeader(
mojo::ConvertTo<mojom::UrlRequestRewriteRemoveHeaderPtr>(
input.remove_header()));
case fuchsia::web::UrlRequestRewrite::Tag::kSubstituteQueryPattern:
return mojom::UrlRequestRewrite::NewSubstituteQueryPattern(
mojo::ConvertTo<mojom::UrlRequestRewriteSubstituteQueryPatternPtr>(
input.substitute_query_pattern()));
case fuchsia::web::UrlRequestRewrite::Tag::kReplaceUrl:
return mojom::UrlRequestRewrite::NewReplaceUrl(
mojo::ConvertTo<mojom::UrlRequestRewriteReplaceUrlPtr>(
input.replace_url()));
default:
// This is to prevent build breakage when adding new rewrites to the FIDL
// definition.
NOTREACHED();
return nullptr;
}
}
mojom::UrlRequestRewriteRulePtr
TypeConverter<mojom::UrlRequestRewriteRulePtr,
fuchsia::web::UrlRequestRewriteRule>::
Convert(const fuchsia::web::UrlRequestRewriteRule& input) {
mojom::UrlRequestRewriteRulePtr rule = mojom::UrlRequestRewriteRule::New();
if (input.has_hosts_filter())
rule->hosts_filter = base::make_optional(input.hosts_filter());
if (input.has_schemes_filter())
rule->schemes_filter = base::make_optional(input.schemes_filter());
if (input.has_rewrites())
rule->rewrites = mojo::ConvertTo<std::vector<mojom::UrlRequestRewritePtr>>(
input.rewrites());
return rule;
}
} // namespace mojo
// Copyright 2019 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 FUCHSIA_ENGINE_URL_REQUEST_REWRITE_TYPE_CONVERTERS_H_
#define FUCHSIA_ENGINE_URL_REQUEST_REWRITE_TYPE_CONVERTERS_H_
#include <fuchsia/web/cpp/fidl.h>
#include "fuchsia/base/string_util.h"
#include "fuchsia/engine/url_request_rewrite.mojom.h"
#include "mojo/public/cpp/bindings/type_converter.h"
namespace mojo {
template <>
struct TypeConverter<mojom::UrlRequestRewriteAddHeadersPtr,
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> {
static mojom::UrlRequestRewriteRulePtr Convert(
const fuchsia::web::UrlRequestRewriteRule& input);
};
} // namespace mojo
#endif // FUCHSIA_ENGINE_URL_REQUEST_REWRITE_TYPE_CONVERTERS_H_
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