123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347 |
- // Copyright 2018 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_web/webengine/browser/web_engine_content_browser_client.h"
- #include <string>
- #include <utility>
- #include "base/callback.h"
- #include "base/command_line.h"
- #include "base/i18n/rtl.h"
- #include "base/strings/string_split.h"
- #include "components/embedder_support/user_agent_utils.h"
- #include "components/policy/content/safe_sites_navigation_throttle.h"
- #include "components/site_isolation/features.h"
- #include "components/site_isolation/preloaded_isolated_origins.h"
- #include "components/strings/grit/components_locale_settings.h"
- #include "components/url_rewrite/common/url_loader_throttle.h"
- #include "components/url_rewrite/common/url_request_rewrite_rules.h"
- #include "components/version_info/version_info.h"
- #include "content/public/browser/client_certificate_delegate.h"
- #include "content/public/browser/devtools_manager_delegate.h"
- #include "content/public/browser/navigation_handle.h"
- #include "content/public/browser/network_service_instance.h"
- #include "content/public/common/content_switches.h"
- #include "fuchsia_web/common/fuchsia_dir_scheme.h"
- #include "fuchsia_web/common/init_logging.h"
- #include "fuchsia_web/webengine/browser/frame_impl.h"
- #include "fuchsia_web/webengine/browser/navigation_policy_throttle.h"
- #include "fuchsia_web/webengine/browser/web_engine_browser_context.h"
- #include "fuchsia_web/webengine/browser/web_engine_browser_interface_binders.h"
- #include "fuchsia_web/webengine/browser/web_engine_browser_main_parts.h"
- #include "fuchsia_web/webengine/browser/web_engine_devtools_controller.h"
- #include "fuchsia_web/webengine/common/cors_exempt_headers.h"
- #include "fuchsia_web/webengine/common/web_engine_content_client.h"
- #include "fuchsia_web/webengine/switches.h"
- #include "media/base/media_switches.h"
- #include "net/cert/x509_certificate.h"
- #include "net/http/http_util.h"
- #include "net/ssl/ssl_private_key.h"
- #include "services/metrics/public/cpp/ukm_source_id.h"
- #include "services/network/public/cpp/network_switches.h"
- #include "services/network/public/cpp/resource_request.h"
- #include "services/network/public/mojom/network_context.mojom.h"
- #include "services/network/public/mojom/network_service.mojom.h"
- #include "third_party/blink/public/common/switches.h"
- #include "third_party/blink/public/mojom/webpreferences/web_preferences.mojom.h"
- #include "ui/base/l10n/l10n_util.h"
- namespace {
- class DevToolsManagerDelegate final : public content::DevToolsManagerDelegate {
- public:
- explicit DevToolsManagerDelegate(WebEngineBrowserMainParts* main_parts)
- : main_parts_(main_parts) {
- DCHECK(main_parts_);
- }
- ~DevToolsManagerDelegate() override = default;
- DevToolsManagerDelegate(const DevToolsManagerDelegate&) = delete;
- DevToolsManagerDelegate& operator=(const DevToolsManagerDelegate&) = delete;
- // content::DevToolsManagerDelegate implementation.
- std::vector<content::BrowserContext*> GetBrowserContexts() override {
- return main_parts_->browser_contexts();
- }
- content::BrowserContext* GetDefaultBrowserContext() override {
- std::vector<content::BrowserContext*> contexts = GetBrowserContexts();
- return contexts.empty() ? nullptr : contexts.front();
- }
- content::DevToolsAgentHost::List RemoteDebuggingTargets() override {
- return main_parts_->devtools_controller()->RemoteDebuggingTargets();
- }
- private:
- WebEngineBrowserMainParts* const main_parts_;
- };
- std::vector<std::string> GetCorsExemptHeaders() {
- return base::SplitString(
- base::CommandLine::ForCurrentProcess()->GetSwitchValueNative(
- switches::kCorsExemptHeaders),
- ",", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
- }
- static constexpr char const* kRendererSwitchesToCopy[] = {
- blink::switches::kSharedArrayBufferAllowedOrigins,
- switches::kCorsExemptHeaders,
- switches::kEnableCastStreamingReceiver,
- switches::kEnableProtectedVideoBuffers,
- switches::kUseOverlaysForVideo,
- // TODO(crbug/1013412): Delete these two switches when fixed.
- switches::kEnableWidevine,
- switches::kPlayreadyKeySystem,
- // Pass to the renderer process for consistency with Chrome.
- network::switches::kUnsafelyTreatInsecureOriginAsSecure,
- };
- static constexpr char const*
- kUnsafelyTreatInsecureOriginAsSecureSwitchToCopy[] = {
- network::switches::kUnsafelyTreatInsecureOriginAsSecure,
- };
- // These are passed to every child process and should only be used when it is
- // not possible to narrow the scope down to a subset of processes.
- static constexpr char const* kAllProcessSwitchesToCopy[] = {
- // This is used by every child process in WebEngineContentClient.
- switches::kEnableContentDirectories,
- };
- } // namespace
- WebEngineContentBrowserClient::WebEngineContentBrowserClient()
- : cors_exempt_headers_(GetCorsExemptHeaders()),
- allow_insecure_content_(base::CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kAllowRunningInsecureContent)) {
- // Logging in this class ensures this is logged once per web_instance.
- LogComponentStartWithVersion("WebEngine web_instance");
- }
- WebEngineContentBrowserClient::~WebEngineContentBrowserClient() = default;
- std::unique_ptr<content::BrowserMainParts>
- WebEngineContentBrowserClient::CreateBrowserMainParts(
- bool /* is_integration_test */) {
- auto browser_main_parts = std::make_unique<WebEngineBrowserMainParts>(this);
- main_parts_ = browser_main_parts.get();
- return browser_main_parts;
- }
- std::unique_ptr<content::DevToolsManagerDelegate>
- WebEngineContentBrowserClient::CreateDevToolsManagerDelegate() {
- DCHECK(main_parts_);
- return std::make_unique<DevToolsManagerDelegate>(main_parts_);
- }
- std::string WebEngineContentBrowserClient::GetProduct() {
- return version_info::GetProductNameAndVersionForUserAgent();
- }
- std::string WebEngineContentBrowserClient::GetUserAgent() {
- std::string user_agent = embedder_support::GetUserAgent();
- if (base::CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kUserAgentProductAndVersion)) {
- user_agent +=
- " " + base::CommandLine::ForCurrentProcess()->GetSwitchValueNative(
- switches::kUserAgentProductAndVersion);
- }
- return user_agent;
- }
- blink::UserAgentMetadata WebEngineContentBrowserClient::GetUserAgentMetadata() {
- return embedder_support::GetUserAgentMetadata();
- }
- void WebEngineContentBrowserClient::OverrideWebkitPrefs(
- content::WebContents* web_contents,
- blink::web_pref::WebPreferences* web_prefs) {
- // Disable WebSQL support since it's being removed from the web platform.
- web_prefs->databases_enabled = false;
- if (allow_insecure_content_)
- web_prefs->allow_running_insecure_content = true;
- FrameImpl* frame = FrameImpl::FromWebContents(web_contents);
- // This method may be called when a |web_contents| is instantiated but an
- // associated frame has not been created.
- if (frame != nullptr)
- frame->OverrideWebPreferences(web_prefs);
- }
- void WebEngineContentBrowserClient::RegisterBrowserInterfaceBindersForFrame(
- content::RenderFrameHost* render_frame_host,
- mojo::BinderMapWithContext<content::RenderFrameHost*>* map) {
- PopulateFuchsiaFrameBinders(map);
- }
- void WebEngineContentBrowserClient::
- RegisterNonNetworkNavigationURLLoaderFactories(
- int frame_tree_node_id,
- ukm::SourceIdObj ukm_source_id,
- NonNetworkURLLoaderFactoryMap* factories) {
- if (base::CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kEnableContentDirectories)) {
- factories->emplace(kFuchsiaDirScheme,
- ContentDirectoryLoaderFactory::Create());
- }
- }
- void WebEngineContentBrowserClient::
- RegisterNonNetworkSubresourceURLLoaderFactories(
- int render_process_id,
- int render_frame_id,
- const absl::optional<url::Origin>& request_initiator_origin,
- NonNetworkURLLoaderFactoryMap* factories) {
- if (base::CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kEnableContentDirectories)) {
- factories->emplace(kFuchsiaDirScheme,
- ContentDirectoryLoaderFactory::Create());
- }
- }
- bool WebEngineContentBrowserClient::ShouldEnableStrictSiteIsolation() {
- constexpr base::Feature kSitePerProcess{"site-per-process",
- base::FEATURE_ENABLED_BY_DEFAULT};
- static bool enable_strict_isolation =
- base::FeatureList::IsEnabled(kSitePerProcess);
- return enable_strict_isolation;
- }
- void WebEngineContentBrowserClient::AppendExtraCommandLineSwitches(
- base::CommandLine* command_line,
- int child_process_id) {
- const base::CommandLine& browser_command_line =
- *base::CommandLine::ForCurrentProcess();
- command_line->CopySwitchesFrom(browser_command_line,
- kAllProcessSwitchesToCopy,
- std::size(kAllProcessSwitchesToCopy));
- std::string process_type =
- command_line->GetSwitchValueASCII(switches::kProcessType);
- if (process_type == switches::kRendererProcess) {
- command_line->CopySwitchesFrom(browser_command_line,
- kRendererSwitchesToCopy,
- std::size(kRendererSwitchesToCopy));
- } else if (process_type == switches::kUtilityProcess) {
- // Although only the Network process needs
- // kUnsafelyTreatInsecureOriginAsSecureSwitchToCopy, differentiating utility
- // process sub-types is non-trivial. ChromeContentBrowserClient appends this
- // switch to all Utility processes so do the same here.
- // Do not add other switches here.
- command_line->CopySwitchesFrom(
- browser_command_line, kUnsafelyTreatInsecureOriginAsSecureSwitchToCopy,
- std::size(kUnsafelyTreatInsecureOriginAsSecureSwitchToCopy));
- }
- }
- std::string WebEngineContentBrowserClient::GetApplicationLocale() {
- // ICU is configured with the system locale by WebEngineBrowserMainParts.
- return base::i18n::GetConfiguredLocale();
- }
- std::string WebEngineContentBrowserClient::GetAcceptLangs(
- content::BrowserContext* context) {
- // Returns a comma-separated list of language codes, in preference order.
- // This is passed to net::HttpUtil::GenerateAcceptLanguageHeader() to
- // generate a legacy "accept-language" header value.
- return l10n_util::GetStringUTF8(IDS_ACCEPT_LANGUAGES);
- }
- base::OnceClosure WebEngineContentBrowserClient::SelectClientCertificate(
- content::WebContents* web_contents,
- net::SSLCertRequestInfo* cert_request_info,
- net::ClientCertIdentityList client_certs,
- std::unique_ptr<content::ClientCertificateDelegate> delegate) {
- // Continue without a certificate.
- delegate->ContinueWithCertificate(nullptr, nullptr);
- return base::OnceClosure();
- }
- std::vector<std::unique_ptr<content::NavigationThrottle>>
- WebEngineContentBrowserClient::CreateThrottlesForNavigation(
- content::NavigationHandle* navigation_handle) {
- std::vector<std::unique_ptr<content::NavigationThrottle>> throttles;
- auto* frame_impl =
- FrameImpl::FromWebContents(navigation_handle->GetWebContents());
- DCHECK(frame_impl);
- // Only create throttle if FrameImpl has a NavigationPolicyProvider,
- // indicating an interest in navigations.
- if (frame_impl->navigation_policy_handler()) {
- throttles.push_back(std::make_unique<NavigationPolicyThrottle>(
- navigation_handle, frame_impl->navigation_policy_handler()));
- }
- const absl::optional<std::string>& explicit_sites_filter_error_page =
- frame_impl->explicit_sites_filter_error_page();
- if (explicit_sites_filter_error_page) {
- throttles.push_back(std::make_unique<SafeSitesNavigationThrottle>(
- navigation_handle,
- navigation_handle->GetWebContents()->GetBrowserContext(),
- *explicit_sites_filter_error_page));
- }
- return throttles;
- }
- 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 {};
- }
- std::vector<std::unique_ptr<blink::URLLoaderThrottle>> throttles;
- auto* frame_impl = FrameImpl::FromWebContents(wc_getter.Run());
- DCHECK(frame_impl);
- const auto& rules =
- frame_impl->url_request_rewrite_rules_manager()->GetCachedRules();
- if (rules) {
- throttles.emplace_back(std::make_unique<url_rewrite::URLLoaderThrottle>(
- rules, base::BindRepeating(&IsHeaderCorsExempt)));
- }
- return throttles;
- }
- void WebEngineContentBrowserClient::ConfigureNetworkContextParams(
- content::BrowserContext* context,
- bool in_memory,
- const base::FilePath& relative_partition_path,
- network::mojom::NetworkContextParams* network_context_params,
- cert_verifier::mojom::CertVerifierCreationParams*
- cert_verifier_creation_params) {
- network_context_params->user_agent = GetUserAgent();
- network_context_params->accept_language =
- net::HttpUtil::GenerateAcceptLanguageHeader(GetAcceptLangs(context));
- // Set the list of cors_exempt_headers which may be specified in a URLRequest,
- // starting with the headers passed in via
- // |CreateContextParams.cors_exempt_headers|.
- network_context_params->cors_exempt_header_list = cors_exempt_headers_;
- }
- std::vector<url::Origin>
- WebEngineContentBrowserClient::GetOriginsRequiringDedicatedProcess() {
- std::vector<url::Origin> isolated_origin_list;
- // Include additional origins preloaded with specific browser configurations,
- // if any.
- auto built_in_origins =
- site_isolation::GetBrowserSpecificBuiltInIsolatedOrigins();
- std::move(std::begin(built_in_origins), std::end(built_in_origins),
- std::back_inserter(isolated_origin_list));
- return isolated_origin_list;
- }
|