From e1a2cc7f366a19693c0b1f2bee6c31c6b3b11e63 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Wed, 22 May 2019 10:43:37 +0900 Subject: [PATCH] feat: migrate protocol module to NetworkService (Part 8) (#18361) * Add ProxyingURLLoaderFactory * Intercept file:// protocol to support asar archives --- atom/browser/atom_browser_client.cc | 24 +++++++ atom/browser/atom_browser_client.h | 10 +++ .../net/proxying_url_loader_factory.cc | 62 +++++++++++++++++++ .../browser/net/proxying_url_loader_factory.h | 47 ++++++++++++++ filenames.gni | 2 + 5 files changed, 145 insertions(+) create mode 100644 atom/browser/net/proxying_url_loader_factory.cc create mode 100644 atom/browser/net/proxying_url_loader_factory.h diff --git a/atom/browser/atom_browser_client.cc b/atom/browser/atom_browser_client.cc index 0f606bd6dc2..3fc7ef06b86 100644 --- a/atom/browser/atom_browser_client.cc +++ b/atom/browser/atom_browser_client.cc @@ -30,6 +30,7 @@ #include "atom/browser/native_window.h" #include "atom/browser/net/network_context_service.h" #include "atom/browser/net/network_context_service_factory.h" +#include "atom/browser/net/proxying_url_loader_factory.h" #include "atom/browser/notifications/notification_presenter.h" #include "atom/browser/notifications/platform_notification_service.h" #include "atom/browser/session_preferences.h" @@ -958,6 +959,29 @@ void AtomBrowserClient::RegisterNonNetworkSubresourceURLLoaderFactories( protocol->RegisterURLLoaderFactories(factories); } +bool AtomBrowserClient::WillCreateURLLoaderFactory( + content::BrowserContext* browser_context, + content::RenderFrameHost* frame_host, + int render_process_id, + bool is_navigation, + bool is_download, + const url::Origin& request_initiator, + network::mojom::URLLoaderFactoryRequest* factory_request, + network::mojom::TrustedURLLoaderHeaderClientPtrInfo* header_client, + bool* bypass_redirect_checks) { + content::WebContents* web_contents = + content::WebContents::FromRenderFrameHost(frame_host); + if (!web_contents) + return false; + + auto proxied_request = std::move(*factory_request); + network::mojom::URLLoaderFactoryPtrInfo target_factory_info; + *factory_request = mojo::MakeRequest(&target_factory_info); + new ProxyingURLLoaderFactory(std::move(proxied_request), + std::move(target_factory_info)); + return true; +} + std::string AtomBrowserClient::GetApplicationLocale() { if (BrowserThread::CurrentlyOn(BrowserThread::IO)) return g_io_thread_application_locale.Get(); diff --git a/atom/browser/atom_browser_client.h b/atom/browser/atom_browser_client.h index 403102d4813..7ad9ef4a19f 100644 --- a/atom/browser/atom_browser_client.h +++ b/atom/browser/atom_browser_client.h @@ -167,6 +167,16 @@ class AtomBrowserClient : public content::ContentBrowserClient, int render_process_id, int render_frame_id, NonNetworkURLLoaderFactoryMap* factories) override; + bool WillCreateURLLoaderFactory( + content::BrowserContext* browser_context, + content::RenderFrameHost* frame, + int render_process_id, + bool is_navigation, + bool is_download, + const url::Origin& request_initiator, + network::mojom::URLLoaderFactoryRequest* factory_request, + network::mojom::TrustedURLLoaderHeaderClientPtrInfo* header_client, + bool* bypass_redirect_checks) override; // content::RenderProcessHostObserver: void RenderProcessHostDestroyed(content::RenderProcessHost* host) override; diff --git a/atom/browser/net/proxying_url_loader_factory.cc b/atom/browser/net/proxying_url_loader_factory.cc new file mode 100644 index 00000000000..85c96cecc1e --- /dev/null +++ b/atom/browser/net/proxying_url_loader_factory.cc @@ -0,0 +1,62 @@ +// Copyright (c) 2019 GitHub, Inc. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +#include "atom/browser/net/proxying_url_loader_factory.h" + +#include + +#include "atom/browser/net/asar/asar_url_loader.h" + +namespace atom { + +ProxyingURLLoaderFactory::ProxyingURLLoaderFactory( + network::mojom::URLLoaderFactoryRequest loader_request, + network::mojom::URLLoaderFactoryPtrInfo target_factory_info) + : weak_factory_(this) { + target_factory_.Bind(std::move(target_factory_info)); + target_factory_.set_connection_error_handler(base::BindOnce( + &ProxyingURLLoaderFactory::OnTargetFactoryError, base::Unretained(this))); + proxy_bindings_.AddBinding(this, std::move(loader_request)); + proxy_bindings_.set_connection_error_handler(base::BindRepeating( + &ProxyingURLLoaderFactory::OnProxyBindingError, base::Unretained(this))); +} + +ProxyingURLLoaderFactory::~ProxyingURLLoaderFactory() = default; + +void ProxyingURLLoaderFactory::CreateLoaderAndStart( + network::mojom::URLLoaderRequest loader, + int32_t routing_id, + int32_t request_id, + uint32_t options, + const network::ResourceRequest& request, + network::mojom::URLLoaderClientPtr client, + const net::MutableNetworkTrafficAnnotationTag& traffic_annotation) { + // Intercept file:// protocol to support asar archives. + if (request.url.SchemeIsFile()) { + asar::CreateAsarURLLoader(request, std::move(loader), std::move(client), + nullptr); + return; + } + + // Pass-through to the original factory. + target_factory_->CreateLoaderAndStart(std::move(loader), routing_id, + request_id, options, request, + std::move(client), traffic_annotation); +} + +void ProxyingURLLoaderFactory::Clone( + network::mojom::URLLoaderFactoryRequest loader_request) { + proxy_bindings_.AddBinding(this, std::move(loader_request)); +} + +void ProxyingURLLoaderFactory::OnTargetFactoryError() { + delete this; +} + +void ProxyingURLLoaderFactory::OnProxyBindingError() { + if (proxy_bindings_.empty()) + delete this; +} + +} // namespace atom diff --git a/atom/browser/net/proxying_url_loader_factory.h b/atom/browser/net/proxying_url_loader_factory.h new file mode 100644 index 00000000000..1ae13bf7009 --- /dev/null +++ b/atom/browser/net/proxying_url_loader_factory.h @@ -0,0 +1,47 @@ +// Copyright (c) 2019 GitHub, Inc. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +#ifndef ATOM_BROWSER_NET_PROXYING_URL_LOADER_FACTORY_H_ +#define ATOM_BROWSER_NET_PROXYING_URL_LOADER_FACTORY_H_ + +#include "mojo/public/cpp/bindings/binding.h" +#include "mojo/public/cpp/bindings/binding_set.h" +#include "services/network/public/mojom/url_loader.mojom.h" +#include "services/network/public/mojom/url_loader_factory.mojom.h" + +namespace atom { + +class ProxyingURLLoaderFactory : public network::mojom::URLLoaderFactory { + public: + ProxyingURLLoaderFactory( + network::mojom::URLLoaderFactoryRequest loader_request, + network::mojom::URLLoaderFactoryPtrInfo target_factory_info); + ~ProxyingURLLoaderFactory() override; + + // network::mojom::URLLoaderFactory: + void CreateLoaderAndStart(network::mojom::URLLoaderRequest loader, + int32_t routing_id, + int32_t request_id, + uint32_t options, + const network::ResourceRequest& request, + network::mojom::URLLoaderClientPtr client, + const net::MutableNetworkTrafficAnnotationTag& + traffic_annotation) override; + void Clone(network::mojom::URLLoaderFactoryRequest request) override; + + private: + void OnTargetFactoryError(); + void OnProxyBindingError(); + + mojo::BindingSet proxy_bindings_; + network::mojom::URLLoaderFactoryPtr target_factory_; + + base::WeakPtrFactory weak_factory_; + + DISALLOW_COPY_AND_ASSIGN(ProxyingURLLoaderFactory); +}; + +} // namespace atom + +#endif // ATOM_BROWSER_NET_PROXYING_URL_LOADER_FACTORY_H_ diff --git a/filenames.gni b/filenames.gni index 6ab3bf5d1f8..e8e92529269 100644 --- a/filenames.gni +++ b/filenames.gni @@ -335,6 +335,8 @@ filenames = { "atom/browser/net/atom_url_request_job_factory.h", "atom/browser/net/http_protocol_handler.cc", "atom/browser/net/http_protocol_handler.h", + "atom/browser/net/proxying_url_loader_factory.cc", + "atom/browser/net/proxying_url_loader_factory.h", "atom/browser/net/js_asker.cc", "atom/browser/net/js_asker.h", "atom/browser/net/network_context_service_factory.cc",