summaryrefslogtreecommitdiffstats
path: root/src/core/content_browser_client_qt.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/content_browser_client_qt.cpp')
-rw-r--r--src/core/content_browser_client_qt.cpp415
1 files changed, 369 insertions, 46 deletions
diff --git a/src/core/content_browser_client_qt.cpp b/src/core/content_browser_client_qt.cpp
index 29b6e09ed..baa08fa7e 100644
--- a/src/core/content_browser_client_qt.cpp
+++ b/src/core/content_browser_client_qt.cpp
@@ -41,14 +41,18 @@
#include "base/memory/ptr_util.h"
#include "base/optional.h"
+#include "base/path_service.h"
#include "base/strings/utf_string_conversions.h"
#include "base/message_loop/message_loop.h"
#include "base/task/post_task.h"
#include "base/threading/thread_restrictions.h"
+#include "chrome/browser/custom_handlers/protocol_handler_registry.h"
#include "chrome/browser/custom_handlers/protocol_handler_registry_factory.h"
#if QT_CONFIG(webengine_spellchecker)
#include "chrome/browser/spellchecker/spell_check_host_chrome_impl.h"
#endif
+#include "components/navigation_interception/intercept_navigation_throttle.h"
+#include "components/navigation_interception/navigation_params.h"
#include "components/guest_view/browser/guest_view_base.h"
#include "components/network_hints/browser/network_hints_message_filter.h"
#include "content/browser/renderer_host/render_view_host_delegate.h"
@@ -58,6 +62,7 @@
#include "content/public/browser/child_process_security_policy.h"
#include "content/public/browser/client_certificate_delegate.h"
#include "content/public/browser/media_observer.h"
+#include "content/public/browser/network_service_instance.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/render_view_host.h"
@@ -66,14 +71,18 @@
#include "content/public/browser/storage_partition.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_contents_user_data.h"
+#include "content/public/browser/web_ui_url_loader_factory.h"
#include "content/public/common/content_switches.h"
#include "content/public/common/main_function_params.h"
#include "content/public/common/service_manager_connection.h"
#include "content/public/common/service_names.mojom.h"
#include "content/public/common/url_constants.h"
+#include "content/public/common/url_loader_throttle.h"
#include "content/public/common/user_agent.h"
#include "media/media_buildflags.h"
#include "extensions/buildflags/buildflags.h"
+#include "extensions/browser/extension_protocols.h"
+#include "extensions/browser/guest_view/web_view/web_view_guest.h"
#include "mojo/public/cpp/bindings/binding.h"
#include "mojo/public/cpp/bindings/binding_set.h"
#include "mojo/public/cpp/bindings/remote.h"
@@ -84,6 +93,8 @@
#include "qtwebengine/browser/qtwebengine_renderer_manifest.h"
#include "net/ssl/client_cert_identity.h"
#include "net/ssl/client_cert_store.h"
+#include "services/network/network_service.h"
+#include "services/network/public/cpp/features.h"
#include "services/service_manager/public/cpp/connector.h"
#include "services/service_manager/public/cpp/service.h"
#include "services/service_manager/sandbox/switches.h"
@@ -109,8 +120,12 @@
#include "devtools_manager_delegate_qt.h"
#include "login_delegate_qt.h"
#include "media_capture_devices_dispatcher.h"
-#include "net/network_delegate_qt.h"
-#include "net/url_request_context_getter_qt.h"
+#include "net/cookie_monster_delegate_qt.h"
+#include "net/custom_url_loader_factory.h"
+#include "net/proxying_restricted_cookie_manager_qt.h"
+#include "net/proxying_url_loader_factory_qt.h"
+#include "net/qrc_url_scheme_handler.h"
+#include "net/system_network_context_manager.h"
#include "platform_notification_service_qt.h"
#if QT_CONFIG(webengine_printing_and_pdf)
#include "printing/printing_message_filter_qt.h"
@@ -121,6 +136,7 @@
#include "renderer_host/user_resource_controller_host.h"
#include "service/service_qt.h"
#include "type_conversion.h"
+#include "web_contents_adapter_client.h"
#include "web_contents_delegate_qt.h"
#include "web_engine_context.h"
#include "web_engine_library_info.h"
@@ -143,13 +159,16 @@
#endif
#if BUILDFLAG(ENABLE_EXTENSIONS)
-#include "extensions/extensions_browser_client_qt.h"
+#include "content/public/browser/file_url_loader.h"
#include "extensions/browser/extension_message_filter.h"
#include "extensions/browser/guest_view/extensions_guest_view_message_filter.h"
#include "extensions/browser/io_thread_extension_message_filter.h"
#include "extensions/common/constants.h"
+
#include "common/extensions/extensions_client_qt.h"
-#include "renderer_host/resource_dispatcher_host_delegate_qt.h"
+#include "extensions/extension_web_contents_observer_qt.h"
+#include "extensions/extensions_browser_client_qt.h"
+#include "net/plugin_response_interceptor_url_loader_throttle.h"
#endif
#if BUILDFLAG(ENABLE_MOJO_MEDIA_IN_BROWSER_PROCESS)
@@ -159,6 +178,7 @@
#include <QGuiApplication>
#include <QLocale>
+#include <QStandardPaths>
#if QT_CONFIG(opengl)
# include <QOpenGLContext>
# include <QOpenGLExtraFunctions>
@@ -276,22 +296,26 @@ void ContentBrowserClientQt::RenderProcessWillLaunch(content::RenderProcessHost*
{
const int id = host->GetID();
Profile *profile = Profile::FromBrowserContext(host->GetBrowserContext());
- base::PostTaskWithTraitsAndReplyWithResult(
- FROM_HERE, {content::BrowserThread::IO},
- base::BindOnce(&net::URLRequestContextGetter::GetURLRequestContext, base::Unretained(profile->GetRequestContext())),
- base::BindOnce(&ContentBrowserClientQt::AddNetworkHintsMessageFilter, base::Unretained(this), id));
+
+ host->AddFilter(new network_hints::NetworkHintsMessageFilter(id));
+
+ // Allow requesting custom schemes.
+ const auto policy = content::ChildProcessSecurityPolicy::GetInstance();
+ const auto profileAdapter = static_cast<ProfileQt *>(profile)->profileAdapter();
+ for (const QByteArray &scheme : profileAdapter->customUrlSchemes())
+ policy->GrantRequestScheme(id, scheme.toStdString());
// FIXME: Add a settings variable to enable/disable the file scheme.
- content::ChildProcessSecurityPolicy::GetInstance()->GrantRequestScheme(id, url::kFileScheme);
- static_cast<ProfileQt*>(host->GetBrowserContext())->m_profileAdapter->userResourceController()->renderProcessStartedWithHost(host);
+ policy->GrantRequestScheme(id, url::kFileScheme);
+ profileAdapter->userResourceController()->renderProcessStartedWithHost(host);
host->AddFilter(new BrowserMessageFilterQt(id, profile));
#if QT_CONFIG(webengine_printing_and_pdf)
- host->AddFilter(new PrintingMessageFilterQt(host->GetID()));
+ host->AddFilter(new PrintingMessageFilterQt(id));
#endif
#if BUILDFLAG(ENABLE_EXTENSIONS)
- host->AddFilter(new extensions::ExtensionMessageFilter(host->GetID(), host->GetBrowserContext()));
- host->AddFilter(new extensions::IOThreadExtensionMessageFilter(host->GetID(), host->GetBrowserContext()));
- host->AddFilter(new extensions::ExtensionsGuestViewMessageFilter(host->GetID(), host->GetBrowserContext()));
+ host->AddFilter(new extensions::ExtensionMessageFilter(id, profile));
+ host->AddFilter(new extensions::IOThreadExtensionMessageFilter(id, profile));
+ host->AddFilter(new extensions::ExtensionsGuestViewMessageFilter(id, profile));
#endif //ENABLE_EXTENSIONS
bool is_incognito_process = profile->IsOffTheRecord();
@@ -313,11 +337,7 @@ void ContentBrowserClientQt::RenderProcessWillLaunch(content::RenderProcessHost*
void ContentBrowserClientQt::ResourceDispatcherHostCreated()
{
-#if BUILDFLAG(ENABLE_EXTENSIONS)
- m_resourceDispatcherHostDelegate.reset(new ResourceDispatcherHostDelegateQt);
-#else
m_resourceDispatcherHostDelegate.reset(new content::ResourceDispatcherHostDelegate);
-#endif
content::ResourceDispatcherHost::Get()->SetDelegate(m_resourceDispatcherHostDelegate.get());
}
@@ -459,12 +479,20 @@ void ContentBrowserClientQt::AppendExtraCommandLineSwitches(base::CommandLine* c
void ContentBrowserClientQt::GetAdditionalWebUISchemes(std::vector<std::string>* additional_schemes)
{
+ ContentBrowserClient::GetAdditionalWebUISchemes(additional_schemes);
additional_schemes->push_back(content::kChromeDevToolsScheme);
}
void ContentBrowserClientQt::GetAdditionalViewSourceSchemes(std::vector<std::string>* additional_schemes)
{
- additional_schemes->push_back(content::kChromeDevToolsScheme);
+ ContentBrowserClient::GetAdditionalViewSourceSchemes(additional_schemes);
+}
+
+void ContentBrowserClientQt::GetAdditionalAllowedSchemesForFileSystem(std::vector<std::string>* additional_schemes)
+{
+ ContentBrowserClient::GetAdditionalAllowedSchemesForFileSystem(additional_schemes);
+ additional_schemes->push_back(content::kChromeDevToolsScheme);
+ additional_schemes->push_back(content::kChromeUIScheme);
}
#if defined(Q_OS_LINUX)
@@ -659,19 +687,6 @@ std::unique_ptr<device::LocationProvider> ContentBrowserClientQt::OverrideSystem
}
#endif
-void ContentBrowserClientQt::AddNetworkHintsMessageFilter(int render_process_id, net::URLRequestContext *context)
-{
- DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
-
- content::RenderProcessHost* host = content::RenderProcessHost::FromID(render_process_id);
- if (!host)
- return;
-
- content::BrowserMessageFilter *network_hints_message_filter =
- new network_hints::NetworkHintsMessageFilter(render_process_id);
- host->AddFilter(network_hints_message_filter);
-}
-
bool ContentBrowserClientQt::ShouldEnableStrictSiteIsolation()
{
// mirroring AwContentBrowserClient, CastContentBrowserClient and
@@ -687,13 +702,17 @@ bool ContentBrowserClientQt::WillCreateRestrictedCookieManager(network::mojom::R
int routing_id,
network::mojom::RestrictedCookieManagerRequest *request)
{
- base::PostTaskWithTraits(
- FROM_HERE, {content::BrowserThread::IO},
- base::BindOnce(&ProfileIODataQt::CreateRestrictedCookieManager,
- ProfileIODataQt::FromBrowserContext(browser_context)->getWeakPtrOnUIThread(),
- std::move(*request),
- role, origin, is_service_worker, process_id, routing_id));
- return true;
+ network::mojom::RestrictedCookieManagerRequest orig_request = std::move(*request);
+ network::mojom::RestrictedCookieManagerPtrInfo target_rcm_info;
+ *request = mojo::MakeRequest(&target_rcm_info);
+
+ ProxyingRestrictedCookieManagerQt::CreateAndBind(
+ ProfileIODataQt::FromBrowserContext(browser_context),
+ std::move(target_rcm_info),
+ is_service_worker, process_id, routing_id,
+ std::move(orig_request));
+
+ return false; // only made a proxy, still need the actual impl to be made.
}
bool ContentBrowserClientQt::AllowAppCacheOnIO(const GURL &manifest_url,
@@ -751,6 +770,14 @@ static void LaunchURL(const GURL& url,
content::WebContents* webContents = web_contents_getter.Run();
if (!webContents)
return;
+
+ ProtocolHandlerRegistry* protocolHandlerRegistry =
+ ProtocolHandlerRegistryFactory::GetForBrowserContext(
+ webContents->GetBrowserContext());
+ if (protocolHandlerRegistry &&
+ protocolHandlerRegistry->IsHandledProtocol(url.scheme()))
+ return;
+
WebContentsDelegateQt *contentsDelegate = static_cast<WebContentsDelegateQt*>(webContents->GetDelegate());
contentsDelegate->launchExternalURL(toQt(url), page_transition, is_main_frame, has_user_gesture);
}
@@ -766,7 +793,7 @@ bool ContentBrowserClientQt::HandleExternalProtocol(
bool has_user_gesture,
network::mojom::URLLoaderFactoryPtr *out_factory)
{
- Q_ASSERT(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
+// Q_ASSERT(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
Q_UNUSED(child_id);
Q_UNUSED(navigation_data);
Q_UNUSED(out_factory);
@@ -822,30 +849,126 @@ private:
std::vector<std::unique_ptr<content::URLLoaderThrottle>>
ContentBrowserClientQt::CreateURLLoaderThrottlesOnIO(
- const network::ResourceRequest & /*request*/, content::ResourceContext *resource_context,
+ const network::ResourceRequest &request, content::ResourceContext *resource_context,
const base::RepeatingCallback<content::WebContents *()> & /*wc_getter*/,
- content::NavigationUIData * /*navigation_ui_data*/, int /*frame_tree_node_id*/)
+ content::NavigationUIData * /*navigation_ui_data*/, int frame_tree_node_id)
{
std::vector<std::unique_ptr<content::URLLoaderThrottle>> result;
ProfileIODataQt *ioData = ProfileIODataQt::FromResourceContext(resource_context);
result.push_back(std::make_unique<ProtocolHandlerThrottle<
scoped_refptr<ProtocolHandlerRegistry::IOThreadDelegate>>>(
- ioData->protocolHandlerRegistryIOThreadDelegate()));
+ ioData->protocolHandlerRegistryIOThreadDelegate()));
+#if BUILDFLAG(ENABLE_EXTENSIONS)
+ result.push_back(std::make_unique<PluginResponseInterceptorURLLoaderThrottle>(
+ resource_context, request.resource_type, frame_tree_node_id));
+#endif
return result;
}
std::vector<std::unique_ptr<content::URLLoaderThrottle>>
ContentBrowserClientQt::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)
+ const base::RepeatingCallback<content::WebContents *()> & /*wc_getter*/,
+ content::NavigationUIData * /*navigation_ui_data*/, int frame_tree_node_id)
{
std::vector<std::unique_ptr<content::URLLoaderThrottle>> result;
result.push_back(std::make_unique<ProtocolHandlerThrottle<ProtocolHandlerRegistry *>>(
- ProtocolHandlerRegistryFactory::GetForBrowserContext(browser_context)));
+ ProtocolHandlerRegistryFactory::GetForBrowserContext(browser_context)));
+#if BUILDFLAG(ENABLE_EXTENSIONS)
+ result.push_back(std::make_unique<PluginResponseInterceptorURLLoaderThrottle>(
+ browser_context, request.resource_type, frame_tree_node_id));
+#endif
return result;
}
+WebContentsAdapterClient::NavigationType pageTransitionToNavigationType(ui::PageTransition transition)
+{
+ if (ui::PageTransitionIsRedirect(transition))
+ return WebContentsAdapterClient::RedirectNavigation;
+
+ int32_t qualifier = ui::PageTransitionGetQualifier(transition);
+
+ if (qualifier & ui::PAGE_TRANSITION_FORWARD_BACK)
+ return WebContentsAdapterClient::BackForwardNavigation;
+
+ ui::PageTransition strippedTransition = ui::PageTransitionStripQualifier(transition);
+
+ switch (strippedTransition) {
+ case ui::PAGE_TRANSITION_LINK:
+ return WebContentsAdapterClient::LinkNavigation;
+ case ui::PAGE_TRANSITION_TYPED:
+ return WebContentsAdapterClient::TypedNavigation;
+ case ui::PAGE_TRANSITION_FORM_SUBMIT:
+ return WebContentsAdapterClient::FormSubmittedNavigation;
+ case ui::PAGE_TRANSITION_RELOAD:
+ return WebContentsAdapterClient::ReloadNavigation;
+ default:
+ return WebContentsAdapterClient::OtherNavigation;
+ }
+}
+
+static bool navigationThrottleCallback(content::WebContents *source,
+ const navigation_interception::NavigationParams &params)
+{
+ // We call navigationRequested later in launchExternalUrl for external protocols.
+ // The is_external_protocol parameter here is not fully accurate though,
+ // and doesn't know about profile specific custom URL schemes.
+ ProfileQt *profile = static_cast<ProfileQt *>(source->GetBrowserContext());
+ if (params.is_external_protocol() && !profile->profileAdapter()->urlSchemeHandler(toQByteArray(params.url().scheme())))
+ return false;
+ int navigationRequestAction = WebContentsAdapterClient::AcceptRequest;
+ WebContentsDelegateQt *delegate = static_cast<WebContentsDelegateQt *>(source->GetDelegate());
+ WebContentsAdapterClient *client = delegate->adapterClient();
+ client->navigationRequested(pageTransitionToNavigationType(params.transition_type()),
+ toQt(params.url()),
+ navigationRequestAction,
+ params.is_main_frame());
+ return navigationRequestAction == static_cast<int>(WebContentsAdapterClient::IgnoreRequest);
+}
+
+std::vector<std::unique_ptr<content::NavigationThrottle>> ContentBrowserClientQt::CreateThrottlesForNavigation(
+ content::NavigationHandle *navigation_handle)
+{
+ std::vector<std::unique_ptr<content::NavigationThrottle>> throttles;
+ throttles.push_back(std::make_unique<navigation_interception::InterceptNavigationThrottle>(
+ navigation_handle,
+ base::BindRepeating(&navigationThrottleCallback),
+ navigation_interception::SynchronyMode::kSync));
+ return throttles;
+}
+
+bool ContentBrowserClientQt::IsHandledURL(const GURL &url)
+{
+ static const char *const kProtocolList[] = {
+ url::kFileScheme,
+ content::kChromeDevToolsScheme,
+#if BUILDFLAG(ENABLE_EXTENSIONS)
+ extensions::kExtensionScheme,
+#endif
+ content::kChromeUIScheme,
+ url::kDataScheme,
+ url::kAboutScheme,
+#if !BUILDFLAG(DISABLE_FTP_SUPPORT)
+ url::kFtpScheme,
+#endif // !BUILDFLAG(DISABLE_FTP_SUPPORT)
+ url::kBlobScheme,
+ url::kFileSystemScheme,
+ url::kQrcScheme,
+ };
+
+ // We don't check url.IsCustom() here because we don't
+ // know if the registered protocol is installed in the
+ // profile that will be used to load the URL.
+
+ const std::string scheme = url.scheme();
+
+ for (const char *protocol : kProtocolList) {
+ if (scheme == protocol)
+ return true;
+ }
+ return net::URLRequest::IsHandledProtocol(scheme);
+}
+
std::unique_ptr<content::LoginDelegate> ContentBrowserClientQt::CreateLoginDelegate(
const net::AuthChallengeInfo &authInfo,
content::WebContents *web_contents,
@@ -875,6 +998,16 @@ bool ContentBrowserClientQt::ShouldUseProcessPerSite(content::BrowserContext* br
return ContentBrowserClient::ShouldUseProcessPerSite(browser_context, effective_url);
}
+bool ContentBrowserClientQt::DoesSiteRequireDedicatedProcess(content::BrowserOrResourceContext browser_or_resource_context,
+ const GURL &effective_site_url)
+{
+#if BUILDFLAG(ENABLE_EXTENSIONS)
+ if (effective_site_url.SchemeIs(extensions::kExtensionScheme))
+ return true;
+#endif
+ return ContentBrowserClient::DoesSiteRequireDedicatedProcess(browser_or_resource_context, effective_site_url);
+}
+
std::string ContentBrowserClientQt::getUserAgent()
{
// Mention the Chromium version we're based on to get passed stupid UA-string-based feature detection (several WebRTC demos need this)
@@ -887,4 +1020,194 @@ std::string ContentBrowserClientQt::GetProduct()
return productName.toStdString();
}
+scoped_refptr<network::SharedURLLoaderFactory> ContentBrowserClientQt::GetSystemSharedURLLoaderFactory()
+{
+ if (!SystemNetworkContextManager::GetInstance())
+ return nullptr;
+ return SystemNetworkContextManager::GetInstance()->GetSharedURLLoaderFactory();
+}
+
+network::mojom::NetworkContext *ContentBrowserClientQt::GetSystemNetworkContext()
+{
+ if (!SystemNetworkContextManager::GetInstance())
+ return nullptr;
+ return SystemNetworkContextManager::GetInstance()->GetContext();
+}
+
+void ContentBrowserClientQt::OnNetworkServiceCreated(network::mojom::NetworkService *network_service)
+{
+ if (!base::FeatureList::IsEnabled(network::features::kNetworkService))
+ return;
+
+ if (!SystemNetworkContextManager::GetInstance())
+ SystemNetworkContextManager::CreateInstance();
+
+ // Need to set up global NetworkService state before anything else uses it.
+ SystemNetworkContextManager::GetInstance()->OnNetworkServiceCreated(network_service);
+}
+
+network::mojom::NetworkContextPtr ContentBrowserClientQt::CreateNetworkContext(content::BrowserContext *context,
+ bool in_memory,
+ const base::FilePath &relative_partition_path)
+{
+ if (!base::FeatureList::IsEnabled(network::features::kNetworkService))
+ return nullptr;
+
+ network::mojom::NetworkContextPtr network_context;
+ // ### do we need to pass in_memory and relative_partition_path to ProfileIODataQt::CreateNetworkContextParams() ?
+ network::mojom::NetworkContextParamsPtr context_params = ProfileIODataQt::FromBrowserContext(context)->CreateNetworkContextParams();
+ content::GetNetworkService()->CreateNetworkContext(mojo::MakeRequest(&network_context), std::move(context_params));
+
+ network::mojom::CookieManagerPtrInfo cookie_manager_info;
+ network_context->GetCookieManager(mojo::MakeRequest(&cookie_manager_info));
+ ProfileIODataQt::FromBrowserContext(context)->cookieDelegate()->setMojoCookieManager(std::move(cookie_manager_info));
+
+ return network_context;
+}
+
+std::vector<base::FilePath> ContentBrowserClientQt::GetNetworkContextsParentDirectory()
+{
+ return {
+ toFilePath(QStandardPaths::writableLocation(QStandardPaths::DataLocation)),
+ toFilePath(QStandardPaths::writableLocation(QStandardPaths::CacheLocation)) };
+}
+
+void ContentBrowserClientQt::RegisterNonNetworkNavigationURLLoaderFactories(int frame_tree_node_id,
+ NonNetworkURLLoaderFactoryMap *factories)
+{
+ DCHECK(base::FeatureList::IsEnabled(network::features::kNetworkService));
+ content::WebContents *web_contents = content::WebContents::FromFrameTreeNodeId(frame_tree_node_id);
+ Profile *profile = Profile::FromBrowserContext(web_contents->GetBrowserContext());
+ ProfileAdapter *profileAdapter = static_cast<ProfileQt *>(profile)->profileAdapter();
+
+ for (const QByteArray &scheme : profileAdapter->customUrlSchemes())
+ factories->emplace(scheme.toStdString(), CreateCustomURLLoaderFactory(profileAdapter));
+
+#if BUILDFLAG(ENABLE_EXTENSIONS)
+ factories->emplace(
+ extensions::kExtensionScheme,
+ extensions::CreateExtensionNavigationURLLoaderFactory(profile,
+ !!extensions::WebViewGuest::FromWebContents(web_contents)));
+#endif
+}
+
+#if BUILDFLAG(ENABLE_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(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
+ {
+ if (!content::ChildProcessSecurityPolicy::GetInstance()->CanRequestURL(child_id_, request.url)) {
+ client->OnComplete(network::URLLoaderCompletionStatus(net::ERR_ACCESS_DENIED));
+ return;
+ }
+ content::CreateFileURLLoader(request, std::move(loader), std::move(client),
+ /* observer */ nullptr,
+ /* allow_directory_listing */ false);
+ }
+
+ void Clone(network::mojom::URLLoaderFactoryRequest loader) override
+ {
+ bindings_.AddBinding(this, std::move(loader));
+ }
+
+ int child_id_;
+ mojo::BindingSet<network::mojom::URLLoaderFactory> bindings_;
+ DISALLOW_COPY_AND_ASSIGN(FileURLLoaderFactory);
+};
+} // namespace
+#endif
+
+void ContentBrowserClientQt::RegisterNonNetworkSubresourceURLLoaderFactories(int render_process_id, int render_frame_id,
+ NonNetworkURLLoaderFactoryMap *factories)
+{
+ if (!base::FeatureList::IsEnabled(network::features::kNetworkService))
+ return;
+ content::RenderProcessHost *process_host = content::RenderProcessHost::FromID(render_process_id);
+ Profile *profile = Profile::FromBrowserContext(process_host->GetBrowserContext());
+ ProfileAdapter *profileAdapter = static_cast<ProfileQt *>(profile)->profileAdapter();
+
+ for (const QByteArray &scheme : profileAdapter->customUrlSchemes())
+ factories->emplace(scheme.toStdString(), CreateCustomURLLoaderFactory(profileAdapter));
+
+#if BUILDFLAG(ENABLE_EXTENSIONS)
+ auto factory = extensions::CreateExtensionURLLoaderFactory(render_process_id, render_frame_id);
+ if (factory)
+ factories->emplace(extensions::kExtensionScheme, std::move(factory));
+
+ 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)
+ return;
+
+ extensions::ExtensionWebContentsObserverQt *web_observer =
+ extensions::ExtensionWebContentsObserverQt::FromWebContents(web_contents);
+ if (!web_observer)
+ return;
+
+ const extensions::Extension *extension = web_observer->GetExtensionFromFrame(frame_host, false);
+ if (!extension)
+ return;
+
+ std::vector<std::string> allowed_webui_hosts;
+ // Support for chrome:// scheme if appropriate.
+ if ((extension->is_extension() || extension->is_platform_app()) &&
+ 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.
+ allowed_webui_hosts.emplace_back(content::kChromeUIResourcesHost);
+ }
+ if (!allowed_webui_hosts.empty()) {
+ factories->emplace(content::kChromeUIScheme,
+ content::CreateWebUIURLLoader(frame_host,
+ content::kChromeUIScheme,
+ std::move(allowed_webui_hosts)));
+ }
+ // Support for file:// scheme when approved by ChildProcessSecurityPolicy.
+ // FIXME: Not needed after switching to using transferable url loaders and guest views.
+ factories->emplace(url::kFileScheme, std::make_unique<FileURLLoaderFactory>(render_process_id));
+#endif
+}
+
+bool ContentBrowserClientQt::WillCreateURLLoaderFactory(
+ content::BrowserContext *browser_context,
+ content::RenderFrameHost *frame,
+ int render_process_id,
+ bool is_navigation,
+ bool is_download,
+ const url::Origin &request_initiator,
+ mojo::PendingReceiver<network::mojom::URLLoaderFactory> *factory_receiver,
+ network::mojom::TrustedURLLoaderHeaderClientPtrInfo *header_client,
+ bool *bypass_redirect_checks)
+{
+ if (!base::FeatureList::IsEnabled(network::features::kNetworkService))
+ return false;
+
+ auto proxied_receiver = std::move(*factory_receiver);
+ network::mojom::URLLoaderFactoryPtrInfo target_factory_info;
+ *factory_receiver = mojo::MakeRequest(&target_factory_info);
+ int process_id = is_navigation ? 0 : render_process_id;
+
+ base::PostTaskWithTraits(
+ FROM_HERE, {content::BrowserThread::IO},
+ base::BindOnce(&ProxyingURLLoaderFactoryQt::CreateProxy, process_id,
+ browser_context->GetResourceContext(),
+ std::move(proxied_receiver),
+ std::move(target_factory_info)));
+ return true;
+}
+
} // namespace QtWebEngineCore