Commit 96887d52 authored by Matt Falkenhagen's avatar Matt Falkenhagen Committed by Commit Bot

shared worker: Allow chrome-extension:// workers under NetworkService.

This allows SharedWorkerScriptLoaderFactory to use non-NetworkService
factories like for chrome-extension://. It allows loading such URLs
for the main shared worker script. Remaining work is to add plumbing
to Blink so that importScripts() also works.

Bug: 839982
Cq-Include-Trybots: master.tryserver.chromium.linux:linux_mojo
Change-Id: I332ca96c8eef46771ca0ea7f290208642b2f82d0
Reviewed-on: https://chromium-review.googlesource.com/1068900Reviewed-by: default avatarHiroki Nakagawa <nhiroki@chromium.org>
Reviewed-by: default avatarKinuko Yasuda <kinuko@chromium.org>
Commit-Queue: Matt Falkenhagen <falken@chromium.org>
Cr-Commit-Position: refs/heads/master@{#561022}
parent 5d675f77
......@@ -21,7 +21,7 @@ SharedWorkerScriptLoader::SharedWorkerScriptLoader(
network::mojom::URLLoaderClientPtr client,
base::WeakPtr<ServiceWorkerProviderHost> service_worker_provider_host,
ResourceContext* resource_context,
scoped_refptr<network::SharedURLLoaderFactory> network_factory,
scoped_refptr<network::SharedURLLoaderFactory> default_loader_factory,
const net::MutableNetworkTrafficAnnotationTag& traffic_annotation)
: routing_id_(routing_id),
request_id_(request_id),
......@@ -30,7 +30,7 @@ SharedWorkerScriptLoader::SharedWorkerScriptLoader(
client_(std::move(client)),
service_worker_provider_host_(service_worker_provider_host),
resource_context_(resource_context),
network_factory_(std::move(network_factory)),
default_loader_factory_(std::move(default_loader_factory)),
traffic_annotation_(traffic_annotation),
url_loader_client_binding_(this),
weak_factory_(this) {
......@@ -84,7 +84,7 @@ void SharedWorkerScriptLoader::MaybeStartLoader(
void SharedWorkerScriptLoader::LoadFromNetwork() {
network::mojom::URLLoaderClientPtr client;
url_loader_client_binding_.Bind(mojo::MakeRequest(&client));
url_loader_factory_ = network_factory_;
url_loader_factory_ = default_loader_factory_;
url_loader_factory_->CreateLoaderAndStart(
mojo::MakeRequest(&url_loader_), routing_id_, request_id_, options_,
resource_request_, std::move(client), traffic_annotation_);
......
......@@ -26,15 +26,20 @@ class ServiceWorkerProviderHost;
//
// This acts much like NavigationURLLoaderImpl. It allows a
// NavigationLoaderInterceptor to intercept the request with its own loader, and
// goes to the network loader otherwise. Once a loader is started, this class
// acts as the URLLoaderClient for it, forwarding messages to the outer client.
// On redirects, it starts over with the new request URL, possibly starting a
// new loader and becoming the client of that.
// goes to |default_loader_factory| otherwise. Once a loader is started, this
// class acts as the URLLoaderClient for it, forwarding messages to the outer
// client. On redirects, it starts over with the new request URL, possibly
// starting a new loader and becoming the client of that.
//
// Lives on the IO thread.
class SharedWorkerScriptLoader : public network::mojom::URLLoader,
public network::mojom::URLLoaderClient {
public:
// |default_loader_factory| is used to load the script if the load is not
// intercepted by a feature like service worker. Typically it will load the
// script from the NetworkService. However, it may internally contain
// non-NetworkService factories used for non-http(s) URLs, e.g., a
// chrome-extension:// URL.
SharedWorkerScriptLoader(
int32_t routing_id,
int32_t request_id,
......@@ -43,7 +48,7 @@ class SharedWorkerScriptLoader : public network::mojom::URLLoader,
network::mojom::URLLoaderClientPtr client,
base::WeakPtr<ServiceWorkerProviderHost> service_worker_provider_host,
ResourceContext* resource_context,
scoped_refptr<network::SharedURLLoaderFactory> network_factory,
scoped_refptr<network::SharedURLLoaderFactory> default_loader_factory,
const net::MutableNetworkTrafficAnnotationTag& traffic_annotation);
~SharedWorkerScriptLoader() override;
......@@ -90,7 +95,7 @@ class SharedWorkerScriptLoader : public network::mojom::URLLoader,
network::mojom::URLLoaderClientPtr client_;
base::WeakPtr<ServiceWorkerProviderHost> service_worker_provider_host_;
ResourceContext* resource_context_;
scoped_refptr<network::SharedURLLoaderFactory> network_factory_;
scoped_refptr<network::SharedURLLoaderFactory> default_loader_factory_;
net::MutableNetworkTrafficAnnotationTag traffic_annotation_;
base::Optional<net::RedirectInfo> redirect_info_;
......@@ -98,6 +103,9 @@ class SharedWorkerScriptLoader : public network::mojom::URLLoader,
network::mojom::URLLoaderPtr url_loader_;
mojo::Binding<network::mojom::URLLoaderClient> url_loader_client_binding_;
// The factory used to request the script. This is the same as
// |default_loader_factory_| if a service worker or other interceptor didn't
// elect to handle the request.
scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory_;
base::WeakPtrFactory<SharedWorkerScriptLoader> weak_factory_;
......
......@@ -22,10 +22,10 @@ SharedWorkerScriptLoaderFactory::SharedWorkerScriptLoaderFactory(
ServiceWorkerContextWrapper* context,
base::WeakPtr<ServiceWorkerProviderHost> service_worker_provider_host,
ResourceContext* resource_context,
scoped_refptr<network::SharedURLLoaderFactory> network_factory)
scoped_refptr<network::SharedURLLoaderFactory> loader_factory)
: service_worker_provider_host_(service_worker_provider_host),
resource_context_(resource_context),
network_factory_(std::move(network_factory)) {
loader_factory_(std::move(loader_factory)) {
DCHECK(ServiceWorkerUtils::IsServicificationEnabled());
DCHECK_EQ(service_worker_provider_host_->provider_type(),
blink::mojom::ServiceWorkerProviderType::kForSharedWorker);
......@@ -54,7 +54,7 @@ void SharedWorkerScriptLoaderFactory::CreateLoaderAndStart(
mojo::MakeStrongBinding(
std::make_unique<SharedWorkerScriptLoader>(
routing_id, request_id, options, resource_request, std::move(client),
service_worker_provider_host_, resource_context_, network_factory_,
service_worker_provider_host_, resource_context_, loader_factory_,
traffic_annotation),
std::move(request));
}
......
......@@ -31,11 +31,15 @@ class ResourceContext;
class SharedWorkerScriptLoaderFactory
: public network::mojom::URLLoaderFactory {
public:
// |loader_factory| is used to load the script if the load is not intercepted
// by a feature like service worker. Typically it will load the script from
// the NetworkService. However, it may internally contain non-NetworkService
// factories used for non-http(s) URLs, e.g., a chrome-extension:// URL.
SharedWorkerScriptLoaderFactory(
ServiceWorkerContextWrapper* context,
base::WeakPtr<ServiceWorkerProviderHost> provider_host,
ResourceContext* resource_context,
scoped_refptr<network::SharedURLLoaderFactory> network_factory);
scoped_refptr<network::SharedURLLoaderFactory> loader_factory);
~SharedWorkerScriptLoaderFactory() override;
// network::mojom::URLLoaderFactory:
......@@ -52,7 +56,7 @@ class SharedWorkerScriptLoaderFactory
private:
base::WeakPtr<ServiceWorkerProviderHost> service_worker_provider_host_;
ResourceContext* resource_context_ = nullptr;
scoped_refptr<network::SharedURLLoaderFactory> network_factory_;
scoped_refptr<network::SharedURLLoaderFactory> loader_factory_;
DISALLOW_COPY_AND_ASSIGN(SharedWorkerScriptLoaderFactory);
};
......
......@@ -27,6 +27,7 @@
#include "content/public/browser/render_view_host.h"
#include "content/public/common/bind_interface_helpers.h"
#include "mojo/public/cpp/bindings/strong_associated_binding.h"
#include "mojo/public/cpp/bindings/strong_binding.h"
#include "third_party/blink/public/common/message_port/message_port_channel.h"
#include "url/origin.h"
......@@ -40,6 +41,7 @@ bool IsShuttingDown(RenderProcessHost* host) {
void CreateScriptLoaderOnIO(
scoped_refptr<URLLoaderFactoryGetter> loader_factory_getter,
std::unique_ptr<URLLoaderFactoryBundleInfo> factory_bundle_info,
scoped_refptr<ServiceWorkerContextWrapper> context,
int process_id,
base::OnceCallback<void(mojom::ServiceWorkerProviderInfoForSharedWorkerPtr,
......@@ -52,14 +54,35 @@ void CreateScriptLoaderOnIO(
base::WeakPtr<ServiceWorkerProviderHost> host =
context->PreCreateHostForSharedWorker(process_id, &provider_info);
// Create the factory bundle for loading the script.
scoped_refptr<URLLoaderFactoryBundle> factory_bundle =
base::MakeRefCounted<URLLoaderFactoryBundle>(
std::move(factory_bundle_info));
// Add the network factory to the bundle. The factory from
// CloneNetworkFactory() doesn't support reconnection to the network service
// after a crash, but it's OK since it's used for a single shared worker
// startup.
network::mojom::URLLoaderFactoryPtr network_factory_ptr;
loader_factory_getter->CloneNetworkFactory(
mojo::MakeRequest(&network_factory_ptr));
factory_bundle->SetDefaultFactory(std::move(network_factory_ptr));
// Create the SharedWorkerScriptLoaderFactory.
network::mojom::URLLoaderFactoryAssociatedPtrInfo script_loader_factory;
mojo::MakeStrongAssociatedBinding(
std::make_unique<SharedWorkerScriptLoaderFactory>(
context.get(), host->AsWeakPtr(), context->resource_context(),
loader_factory_getter->GetNetworkFactory()),
std::move(factory_bundle)),
mojo::MakeRequest(&script_loader_factory));
// TODO(falken): Also send the factory bundle to the renderer like
// CommitNavigation does, to be used for subresource requests from the shared
// worker (SharedWorkerScriptLoaderFactory is only used for the main resource
// request). However, the restartable network factory should be used in this
// case.
// We continue in StartWorker.
BrowserThread::PostTask(
BrowserThread::UI, FROM_HERE,
base::BindOnce(std::move(callback), std::move(provider_info),
......@@ -202,13 +225,37 @@ void SharedWorkerServiceImpl::CreateWorker(
// Bounce to the IO thread to setup service worker support in case the request
// for the worker script will need to be intercepted by service workers.
if (ServiceWorkerUtils::IsServicificationEnabled()) {
// Set up the factory bundle for non-NetworkService URLs, e.g.,
// chrome-extension:// URLs.
ContentBrowserClient::NonNetworkURLLoaderFactoryMap factories;
GetContentClient()
->browser()
->RegisterNonNetworkSubresourceURLLoaderFactories(
process_id, MSG_ROUTING_NONE, &factories);
// TODO(falken): Add FileURLLoaderFactory if the requesting frame is a file
// resource.
auto factory_bundle = std::make_unique<URLLoaderFactoryBundleInfo>();
for (auto& pair : factories) {
const std::string& scheme = pair.first;
std::unique_ptr<network::mojom::URLLoaderFactory> factory =
std::move(pair.second);
network::mojom::URLLoaderFactoryPtr factory_ptr;
mojo::MakeStrongBinding(std::move(factory),
mojo::MakeRequest(&factory_ptr));
factory_bundle->factories_info().emplace(scheme,
factory_ptr.PassInterface());
}
BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
base::BindOnce(
&CreateScriptLoaderOnIO,
service_worker_context_->storage_partition()
->url_loader_factory_getter(),
service_worker_context_, process_id,
std::move(factory_bundle), service_worker_context_, process_id,
base::BindOnce(&SharedWorkerServiceImpl::StartWorker,
weak_factory_.GetWeakPtr(), std::move(instance),
weak_host, std::move(client), process_id, frame_id,
......
......@@ -202,7 +202,6 @@
# Support URLLoaderFactories from embedder in shared workers.
# https://crbug.com/839982
-ExtensionApiTest.Debugger
-ExtensionApiTestWithSwitch.ExtensionDebugger
# https://crbug.com/832749
......
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