|
@@ -49,6 +49,7 @@
|
|
|
#include "extensions/common/constants.h"
|
|
|
#include "net/base/escape.h"
|
|
|
#include "net/ssl/ssl_cert_request_info.h"
|
|
|
+#include "ppapi/buildflags/buildflags.h"
|
|
|
#include "ppapi/host/ppapi_host.h"
|
|
|
#include "printing/buildflags/buildflags.h"
|
|
|
#include "services/device/public/cpp/geolocation/location_provider.h"
|
|
@@ -129,13 +130,29 @@
|
|
|
#endif // BUILDFLAG(ENABLE_PRINTING)
|
|
|
|
|
|
#if BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS)
|
|
|
+#include "chrome/common/webui_url_constants.h"
|
|
|
+#include "content/public/browser/child_process_security_policy.h"
|
|
|
+#include "content/public/browser/file_url_loader.h"
|
|
|
+#include "content/public/browser/web_ui_url_loader_factory.h"
|
|
|
+#include "extensions/browser/api/mime_handler_private/mime_handler_private.h"
|
|
|
+#include "extensions/browser/extension_host.h"
|
|
|
#include "extensions/browser/extension_message_filter.h"
|
|
|
#include "extensions/browser/extension_navigation_throttle.h"
|
|
|
#include "extensions/browser/extension_registry.h"
|
|
|
+#include "extensions/browser/guest_view/extensions_guest_view_message_filter.h"
|
|
|
+#include "extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest.h"
|
|
|
#include "extensions/browser/info_map.h"
|
|
|
+#include "extensions/browser/process_manager.h"
|
|
|
#include "extensions/browser/process_map.h"
|
|
|
+#include "extensions/common/api/mime_handler.mojom.h"
|
|
|
#include "extensions/common/extension.h"
|
|
|
#include "shell/browser/extensions/electron_extension_system.h"
|
|
|
+#include "shell/browser/extensions/electron_extension_web_contents_observer.h"
|
|
|
+#endif
|
|
|
+
|
|
|
+#if BUILDFLAG(ENABLE_PLUGINS)
|
|
|
+#include "chrome/browser/plugins/plugin_response_interceptor_url_loader_throttle.h" // nogncheck
|
|
|
+#include "shell/browser/plugins/plugin_utils.h"
|
|
|
#endif
|
|
|
|
|
|
#if defined(OS_MACOSX)
|
|
@@ -443,6 +460,8 @@ void ElectronBrowserClient::RenderProcessWillLaunch(
|
|
|
#if BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS)
|
|
|
host->AddFilter(
|
|
|
new extensions::ExtensionMessageFilter(process_id, browser_context));
|
|
|
+ host->AddFilter(new extensions::ExtensionsGuestViewMessageFilter(
|
|
|
+ process_id, browser_context));
|
|
|
#endif
|
|
|
|
|
|
ProcessPreferences prefs;
|
|
@@ -785,6 +804,7 @@ void ElectronBrowserClient::GetAdditionalAllowedSchemesForFileSystem(
|
|
|
additional_schemes->insert(additional_schemes->end(), schemes_list.begin(),
|
|
|
schemes_list.end());
|
|
|
additional_schemes->push_back(content::kChromeDevToolsScheme);
|
|
|
+ additional_schemes->push_back(content::kChromeUIScheme);
|
|
|
}
|
|
|
|
|
|
void ElectronBrowserClient::GetAdditionalWebUISchemes(
|
|
@@ -1144,28 +1164,123 @@ void ElectronBrowserClient::RegisterNonNetworkNavigationURLLoaderFactories(
|
|
|
protocol->RegisterURLLoaderFactories(factories);
|
|
|
}
|
|
|
|
|
|
+#if BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS)
|
|
|
+namespace {
|
|
|
+
|
|
|
+// The FileURLLoaderFactory provided to the extension background pages.
|
|
|
+// Checks with the ChildProcessSecurityPolicy to validate the file access.
|
|
|
+class FileURLLoaderFactory : public network::mojom::URLLoaderFactory {
|
|
|
+ public:
|
|
|
+ explicit FileURLLoaderFactory(int child_id) : child_id_(child_id) {}
|
|
|
+
|
|
|
+ private:
|
|
|
+ // network::mojom::URLLoaderFactory:
|
|
|
+ void CreateLoaderAndStart(
|
|
|
+ mojo::PendingReceiver<network::mojom::URLLoader> loader,
|
|
|
+ int32_t routing_id,
|
|
|
+ int32_t request_id,
|
|
|
+ uint32_t options,
|
|
|
+ const network::ResourceRequest& request,
|
|
|
+ mojo::PendingRemote<network::mojom::URLLoaderClient> client,
|
|
|
+ const net::MutableNetworkTrafficAnnotationTag& traffic_annotation)
|
|
|
+ override {
|
|
|
+ if (!content::ChildProcessSecurityPolicy::GetInstance()->CanRequestURL(
|
|
|
+ child_id_, request.url)) {
|
|
|
+ mojo::Remote<network::mojom::URLLoaderClient>(std::move(client))
|
|
|
+ ->OnComplete(
|
|
|
+ network::URLLoaderCompletionStatus(net::ERR_ACCESS_DENIED));
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ content::CreateFileURLLoaderBypassingSecurityChecks(
|
|
|
+ request, std::move(loader), std::move(client),
|
|
|
+ /*observer=*/nullptr,
|
|
|
+ /* allow_directory_listing */ true);
|
|
|
+ }
|
|
|
+
|
|
|
+ void Clone(
|
|
|
+ mojo::PendingReceiver<network::mojom::URLLoaderFactory> loader) override {
|
|
|
+ receivers_.Add(this, std::move(loader));
|
|
|
+ }
|
|
|
+
|
|
|
+ int child_id_;
|
|
|
+ mojo::ReceiverSet<network::mojom::URLLoaderFactory> receivers_;
|
|
|
+ DISALLOW_COPY_AND_ASSIGN(FileURLLoaderFactory);
|
|
|
+};
|
|
|
+
|
|
|
+} // namespace
|
|
|
+#endif // BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS)
|
|
|
+
|
|
|
void ElectronBrowserClient::RegisterNonNetworkSubresourceURLLoaderFactories(
|
|
|
int render_process_id,
|
|
|
int render_frame_id,
|
|
|
NonNetworkURLLoaderFactoryMap* factories) {
|
|
|
-#if BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS)
|
|
|
- auto factory = extensions::CreateExtensionURLLoaderFactory(render_process_id,
|
|
|
- render_frame_id);
|
|
|
- if (factory)
|
|
|
- factories->emplace(extensions::kExtensionScheme, std::move(factory));
|
|
|
-#endif
|
|
|
-
|
|
|
- // Chromium may call this even when NetworkService is not enabled.
|
|
|
content::RenderFrameHost* frame_host =
|
|
|
content::RenderFrameHost::FromID(render_process_id, render_frame_id);
|
|
|
content::WebContents* web_contents =
|
|
|
content::WebContents::FromRenderFrameHost(frame_host);
|
|
|
+
|
|
|
if (web_contents) {
|
|
|
api::Protocol* protocol = api::Protocol::FromWrappedClass(
|
|
|
v8::Isolate::GetCurrent(), web_contents->GetBrowserContext());
|
|
|
if (protocol)
|
|
|
protocol->RegisterURLLoaderFactories(factories);
|
|
|
}
|
|
|
+#if BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS)
|
|
|
+ auto factory = extensions::CreateExtensionURLLoaderFactory(render_process_id,
|
|
|
+ render_frame_id);
|
|
|
+ if (factory)
|
|
|
+ factories->emplace(extensions::kExtensionScheme, std::move(factory));
|
|
|
+
|
|
|
+ if (!web_contents)
|
|
|
+ return;
|
|
|
+
|
|
|
+ extensions::ElectronExtensionWebContentsObserver* web_observer =
|
|
|
+ extensions::ElectronExtensionWebContentsObserver::FromWebContents(
|
|
|
+ web_contents);
|
|
|
+
|
|
|
+ // There is nothing to do if no ElectronExtensionWebContentsObserver is
|
|
|
+ // attached to the |web_contents|.
|
|
|
+ if (!web_observer)
|
|
|
+ return;
|
|
|
+
|
|
|
+ const extensions::Extension* extension =
|
|
|
+ web_observer->GetExtensionFromFrame(frame_host, false);
|
|
|
+ if (!extension)
|
|
|
+ return;
|
|
|
+
|
|
|
+ // Support for chrome:// scheme if appropriate.
|
|
|
+ if (extension->is_extension() &&
|
|
|
+ extensions::Manifest::IsComponentLocation(extension->location())) {
|
|
|
+ // Components of chrome that are implemented as extensions or platform apps
|
|
|
+ // are allowed to use chrome://resources/ and chrome://theme/ URLs.
|
|
|
+ factories->emplace(
|
|
|
+ content::kChromeUIScheme,
|
|
|
+ content::CreateWebUIURLLoader(frame_host, content::kChromeUIScheme,
|
|
|
+ {content::kChromeUIResourcesHost}));
|
|
|
+ }
|
|
|
+
|
|
|
+ // Extension with a background page get file access that gets approval from
|
|
|
+ // ChildProcessSecurityPolicy.
|
|
|
+ extensions::ExtensionHost* host =
|
|
|
+ extensions::ProcessManager::Get(web_contents->GetBrowserContext())
|
|
|
+ ->GetBackgroundHostForExtension(extension->id());
|
|
|
+ if (host) {
|
|
|
+ factories->emplace(url::kFileScheme, std::make_unique<FileURLLoaderFactory>(
|
|
|
+ render_process_id));
|
|
|
+ }
|
|
|
+#endif
|
|
|
+}
|
|
|
+
|
|
|
+bool ElectronBrowserClient::ShouldTreatURLSchemeAsFirstPartyWhenTopLevel(
|
|
|
+ base::StringPiece scheme,
|
|
|
+ bool is_embedded_origin_secure) {
|
|
|
+ if (is_embedded_origin_secure && scheme == content::kChromeUIScheme)
|
|
|
+ return true;
|
|
|
+#if BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS)
|
|
|
+ return scheme == extensions::kExtensionScheme;
|
|
|
+#else
|
|
|
+ return false;
|
|
|
+#endif
|
|
|
}
|
|
|
|
|
|
bool ElectronBrowserClient::WillInterceptWebSocket(
|
|
@@ -1331,11 +1446,31 @@ void ElectronBrowserClient::BindHostReceiverForRenderer(
|
|
|
#endif
|
|
|
}
|
|
|
|
|
|
+#if BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS)
|
|
|
+void BindMimeHandlerService(
|
|
|
+ content::RenderFrameHost* frame_host,
|
|
|
+ mojo::PendingReceiver<extensions::mime_handler::MimeHandlerService>
|
|
|
+ receiver) {
|
|
|
+ content::WebContents* contents =
|
|
|
+ content::WebContents::FromRenderFrameHost(frame_host);
|
|
|
+ auto* guest_view =
|
|
|
+ extensions::MimeHandlerViewGuest::FromWebContents(contents);
|
|
|
+ if (!guest_view)
|
|
|
+ return;
|
|
|
+ extensions::MimeHandlerServiceImpl::Create(guest_view->GetStreamWeakPtr(),
|
|
|
+ std::move(receiver));
|
|
|
+}
|
|
|
+#endif
|
|
|
+
|
|
|
void ElectronBrowserClient::RegisterBrowserInterfaceBindersForFrame(
|
|
|
content::RenderFrameHost* render_frame_host,
|
|
|
service_manager::BinderMapWithContext<content::RenderFrameHost*>* map) {
|
|
|
map->Add<network_hints::mojom::NetworkHintsHandler>(
|
|
|
base::BindRepeating(&BindNetworkHintsHandler));
|
|
|
+#if BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS)
|
|
|
+ map->Add<extensions::mime_handler::MimeHandlerService>(
|
|
|
+ base::BindRepeating(&BindMimeHandlerService));
|
|
|
+#endif
|
|
|
}
|
|
|
|
|
|
std::unique_ptr<content::LoginDelegate>
|
|
@@ -1353,4 +1488,35 @@ ElectronBrowserClient::CreateLoginDelegate(
|
|
|
first_auth_attempt, std::move(auth_required_callback));
|
|
|
}
|
|
|
|
|
|
+std::vector<std::unique_ptr<blink::URLLoaderThrottle>>
|
|
|
+ElectronBrowserClient::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) {
|
|
|
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
|
|
|
+
|
|
|
+ std::vector<std::unique_ptr<blink::URLLoaderThrottle>> result;
|
|
|
+
|
|
|
+#if BUILDFLAG(ENABLE_PLUGINS) && BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS)
|
|
|
+ result.push_back(std::make_unique<PluginResponseInterceptorURLLoaderThrottle>(
|
|
|
+ request.resource_type, frame_tree_node_id));
|
|
|
+#endif
|
|
|
+
|
|
|
+ return result;
|
|
|
+}
|
|
|
+
|
|
|
+base::flat_set<std::string>
|
|
|
+ElectronBrowserClient::GetPluginMimeTypesWithExternalHandlers(
|
|
|
+ content::BrowserContext* browser_context) {
|
|
|
+ base::flat_set<std::string> mime_types;
|
|
|
+#if BUILDFLAG(ENABLE_PLUGINS) && BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS)
|
|
|
+ auto map = PluginUtils::GetMimeTypeToExtensionIdMap(browser_context);
|
|
|
+ for (const auto& pair : map)
|
|
|
+ mime_types.insert(pair.first);
|
|
|
+#endif
|
|
|
+ return mime_types;
|
|
|
+}
|
|
|
+
|
|
|
} // namespace electron
|