Commit 79573b37 authored by Matt Falkenhagen's avatar Matt Falkenhagen Committed by Commit Bot

shared worker: Give the renderer a factory bundle when NetworkService is enabled.

Similar to frames, the shared worker needs a factory bundle in order to
load non-NetworkService URLs like chrome-extension://.

This fixes the remaining test failure but we're still missing test
coverage. I think the factory bundle needs to be propagated to
ServiceWorkerSubresourceLoaderFactory for use with network fallback.

Bug: 839982
Cq-Include-Trybots: master.tryserver.chromium.linux:linux_mojo
Change-Id: I2c489a17fb30364e477d691bc346f7656b07906d
Reviewed-on: https://chromium-review.googlesource.com/1069956
Commit-Queue: Matt Falkenhagen <falken@chromium.org>
Reviewed-by: default avatarHiroki Nakagawa <nhiroki@chromium.org>
Reviewed-by: default avatarDaniel Cheng <dcheng@chromium.org>
Reviewed-by: default avatarKinuko Yasuda <kinuko@chromium.org>
Cr-Commit-Position: refs/heads/master@{#561423}
parent 2c31aa6a
......@@ -4,6 +4,7 @@
#include "content/browser/shared_worker/mock_shared_worker.h"
#include "content/common/url_loader_factory_bundle.h"
#include "mojo/public/cpp/test_support/test_utils.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "url/gurl.h"
......@@ -102,6 +103,7 @@ void MockSharedWorkerFactory::CreateSharedWorker(
service_worker_provider_info,
network::mojom::URLLoaderFactoryAssociatedPtrInfo
script_loader_factory_ptr_info,
std::unique_ptr<URLLoaderFactoryBundleInfo> subresource_loaders,
mojom::SharedWorkerHostPtr host,
mojom::SharedWorkerRequest request,
service_manager::mojom::InterfaceProviderPtr interface_provider) {
......
......@@ -22,6 +22,7 @@
class GURL;
namespace content {
class URLLoaderFactoryBundleInfo;
class MockSharedWorker : public mojom::SharedWorker {
public:
......@@ -71,6 +72,7 @@ class MockSharedWorkerFactory : public mojom::SharedWorkerFactory {
service_worker_provider_info,
network::mojom::URLLoaderFactoryAssociatedPtrInfo
script_loader_factory_ptr_info,
std::unique_ptr<URLLoaderFactoryBundleInfo> subresource_loaders,
mojom::SharedWorkerHostPtr host,
mojom::SharedWorkerRequest request,
service_manager::mojom::InterfaceProviderPtr interface_provider) override;
......
......@@ -14,6 +14,8 @@
#include "content/browser/shared_worker/shared_worker_content_settings_proxy_impl.h"
#include "content/browser/shared_worker/shared_worker_instance.h"
#include "content/browser/shared_worker/shared_worker_service_impl.h"
#include "content/browser/storage_partition_impl.h"
#include "content/common/url_loader_factory_bundle.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/content_browser_client.h"
......@@ -121,7 +123,8 @@ void SharedWorkerHost::Start(
mojom::SharedWorkerFactoryPtr factory,
mojom::ServiceWorkerProviderInfoForSharedWorkerPtr
service_worker_provider_info,
network::mojom::URLLoaderFactoryAssociatedPtrInfo script_loader_factory) {
network::mojom::URLLoaderFactoryAssociatedPtrInfo script_loader_factory,
std::unique_ptr<URLLoaderFactoryBundleInfo> factory_bundle) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
AdvanceTo(Phase::kStarted);
......@@ -151,19 +154,48 @@ void SharedWorkerHost::Start(
mojom::kNavigation_SharedWorkerSpec, process_id_,
mojo::MakeRequest(&interface_provider)));
// NetworkService: Add the network factory to the bundle to pass to the
// renderer. The bundle is only provided (along with |script_loader_factory|)
// if NetworkService/S13nSW is enabled.
DCHECK(!script_loader_factory || factory_bundle);
if (factory_bundle) {
network::mojom::URLLoaderFactoryPtrInfo network_factory_info;
CreateNetworkFactory(mojo::MakeRequest(&network_factory_info));
DCHECK(!factory_bundle->default_factory_info());
factory_bundle->default_factory_info() = std::move(network_factory_info);
}
// Send the CreateSharedWorker message.
factory_ = std::move(factory);
factory_->CreateSharedWorker(
std::move(info), pause_on_start, devtools_worker_token,
std::move(content_settings), std::move(service_worker_provider_info),
std::move(script_loader_factory), std::move(host),
std::move(worker_request_), std::move(interface_provider));
std::move(script_loader_factory), std::move(factory_bundle),
std::move(host), std::move(worker_request_),
std::move(interface_provider));
// Monitor the lifetime of the worker.
worker_.set_connection_error_handler(base::BindOnce(
&SharedWorkerHost::OnWorkerConnectionLost, weak_factory_.GetWeakPtr()));
}
// This is similar to
// RenderFrameHostImpl::CreateNetworkServiceDefaultFactoryAndObserve.
void SharedWorkerHost::CreateNetworkFactory(
network::mojom::URLLoaderFactoryRequest request) {
network::mojom::URLLoaderFactoryParamsPtr params =
network::mojom::URLLoaderFactoryParams::New();
params->process_id = process_id_;
// TODO(lukasza): https://crbug.com/792546: Start using CORB.
params->is_corb_enabled = false;
service_->storage_partition()->GetNetworkContext()->CreateURLLoaderFactory(
std::move(request), std::move(params));
// TODO(falken): Detect connection error and send a IPC with a new network
// factory like UpdateSubresourceLoaderFactories does for frames.
}
void SharedWorkerHost::AllowFileSystem(
const GURL& url,
base::OnceCallback<void(bool)> callback) {
......
......@@ -36,6 +36,7 @@ namespace content {
class SharedWorkerContentSettingsProxyImpl;
class SharedWorkerInstance;
class SharedWorkerServiceImpl;
class URLLoaderFactoryBundleInfo;
// The SharedWorkerHost is the interface that represents the browser side of
// the browser <-> worker communication channel. This is owned by
......@@ -66,7 +67,8 @@ class CONTENT_EXPORT SharedWorkerHost
mojom::SharedWorkerFactoryPtr factory,
mojom::ServiceWorkerProviderInfoForSharedWorkerPtr
service_worker_provider_info,
network::mojom::URLLoaderFactoryAssociatedPtrInfo script_loader_factory);
network::mojom::URLLoaderFactoryAssociatedPtrInfo script_loader_factory,
std::unique_ptr<URLLoaderFactoryBundleInfo> factory_bundle);
void AllowFileSystem(const GURL& url,
base::OnceCallback<void(bool)> callback);
......@@ -137,6 +139,8 @@ class CONTENT_EXPORT SharedWorkerHost
void GetInterface(const std::string& interface_name,
mojo::ScopedMessagePipeHandle interface_pipe) override;
void CreateNetworkFactory(network::mojom::URLLoaderFactoryRequest request);
void AdvanceTo(Phase phase);
mojo::Binding<mojom::SharedWorkerHost> binding_;
......
......@@ -15,9 +15,11 @@
#include "content/browser/shared_worker/shared_worker_instance.h"
#include "content/browser/shared_worker/shared_worker_service_impl.h"
#include "content/public/test/test_browser_thread_bundle.h"
#include "content/public/test/test_storage_partition.h"
#include "content/public/test/test_utils.h"
#include "mojo/public/cpp/bindings/binding.h"
#include "mojo/public/cpp/test_support/test_utils.h"
#include "services/network/test/test_network_context.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/common/message_port/message_port_channel.h"
#include "url/origin.h"
......@@ -28,7 +30,10 @@ namespace content {
class SharedWorkerHostTest : public testing::Test {
public:
SharedWorkerHostTest() : service_(nullptr) {}
SharedWorkerHostTest()
: service_(&storage_partition_, nullptr /* service_worker_context */) {
storage_partition_.set_network_context(&network_context_);
}
base::WeakPtr<SharedWorkerHost> CreateHost() {
GURL url("http://www.example.com/w.js");
......@@ -56,7 +61,8 @@ class SharedWorkerHostTest : public testing::Test {
void StartWorker(SharedWorkerHost* host,
mojom::SharedWorkerFactoryPtr factory) {
host->Start(std::move(factory), nullptr /* service_worker_provider_info */,
{} /* script_loader_factory_info */);
{} /* script_loader_factory_info */,
nullptr /* factory_bundle */);
}
MessagePortChannel AddClient(SharedWorkerHost* host,
......@@ -71,6 +77,9 @@ class SharedWorkerHostTest : public testing::Test {
protected:
TestBrowserThreadBundle test_browser_thread_bundle_;
TestStoragePartition storage_partition_;
network::TestNetworkContext network_context_;
SharedWorkerServiceImpl service_;
DISALLOW_COPY_AND_ASSIGN(SharedWorkerHostTest);
......@@ -181,7 +190,8 @@ TEST_F(SharedWorkerHostTest, TerminateAfterStarting) {
// Start the worker.
host->Start(std::move(factory), nullptr /* service_worker_provider_info */,
{} /* script_loader_factory_info */);
{} /* script_loader_factory_info */,
nullptr /* factory_bundle */);
// Add a client.
MockSharedWorkerClient client;
......
......@@ -16,6 +16,7 @@
#include "content/browser/shared_worker/shared_worker_instance.h"
#include "content/browser/shared_worker/shared_worker_script_loader_factory.h"
#include "content/browser/storage_partition_impl.h"
#include "content/browser/url_loader_factory_getter.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/common/service_worker/service_worker_provider.mojom.h"
#include "content/common/service_worker/service_worker_utils.h"
......@@ -39,13 +40,45 @@ bool IsShuttingDown(RenderProcessHost* host) {
host->IsKeepAliveRefCountDisabled();
}
std::unique_ptr<URLLoaderFactoryBundleInfo> CreateFactoryBundle(
int process_id) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
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());
}
return factory_bundle;
}
void CreateScriptLoaderOnIO(
scoped_refptr<URLLoaderFactoryGetter> loader_factory_getter,
std::unique_ptr<URLLoaderFactoryBundleInfo> factory_bundle_info,
std::unique_ptr<URLLoaderFactoryBundleInfo> factory_bundle_for_browser_info,
std::unique_ptr<URLLoaderFactoryBundleInfo>
factory_bundle_for_renderer_info,
scoped_refptr<ServiceWorkerContextWrapper> context,
int process_id,
base::OnceCallback<void(mojom::ServiceWorkerProviderInfoForSharedWorkerPtr,
network::mojom::URLLoaderFactoryAssociatedPtrInfo)>
network::mojom::URLLoaderFactoryAssociatedPtrInfo,
std::unique_ptr<URLLoaderFactoryBundleInfo>)>
callback) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
......@@ -54,10 +87,11 @@ void CreateScriptLoaderOnIO(
base::WeakPtr<ServiceWorkerProviderHost> host =
context->PreCreateHostForSharedWorker(process_id, &provider_info);
// Create the factory bundle for loading the script.
// Create the factory bundle for SharedWorkerScriptLoaderFactory to use to
// load the script.
scoped_refptr<URLLoaderFactoryBundle> factory_bundle =
base::MakeRefCounted<URLLoaderFactoryBundle>(
std::move(factory_bundle_info));
std::move(factory_bundle_for_browser_info));
// Add the network factory to the bundle. The factory from
// CloneNetworkFactory() doesn't support reconnection to the network service
......@@ -76,24 +110,21 @@ void CreateScriptLoaderOnIO(
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),
std::move(script_loader_factory)));
std::move(script_loader_factory),
std::move(factory_bundle_for_renderer_info)));
}
} // namespace
SharedWorkerServiceImpl::SharedWorkerServiceImpl(
StoragePartition* storage_partition,
scoped_refptr<ServiceWorkerContextWrapper> service_worker_context)
: service_worker_context_(std::move(service_worker_context)),
: storage_partition_(storage_partition),
service_worker_context_(std::move(service_worker_context)),
weak_factory_(this) {}
SharedWorkerServiceImpl::~SharedWorkerServiceImpl() {}
......@@ -225,37 +256,28 @@ 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());
if (!service_worker_context_->storage_partition()) {
// The context is shutting down. Just drop the request.
return;
}
// Set up the factory bundle for non-NetworkService URLs, e.g.,
// chrome-extension:// URLs. One factory bundle is consumed by the browser
// for SharedWorkerScriptLoaderFactory, and one is sent to the renderer.
std::unique_ptr<URLLoaderFactoryBundleInfo> factory_bundle_for_browser =
CreateFactoryBundle(process_id);
std::unique_ptr<URLLoaderFactoryBundleInfo> factory_bundle_for_renderer =
CreateFactoryBundle(process_id);
BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
base::BindOnce(
&CreateScriptLoaderOnIO,
service_worker_context_->storage_partition()
->url_loader_factory_getter(),
std::move(factory_bundle), service_worker_context_, process_id,
std::move(factory_bundle_for_browser),
std::move(factory_bundle_for_renderer), service_worker_context_,
process_id,
base::BindOnce(&SharedWorkerServiceImpl::StartWorker,
weak_factory_.GetWeakPtr(), std::move(instance),
weak_host, std::move(client), process_id, frame_id,
......@@ -264,7 +286,7 @@ void SharedWorkerServiceImpl::CreateWorker(
}
StartWorker(std::move(instance), weak_host, std::move(client), process_id,
frame_id, message_port, nullptr, {});
frame_id, message_port, nullptr, {}, nullptr);
}
void SharedWorkerServiceImpl::StartWorker(
......@@ -277,7 +299,8 @@ void SharedWorkerServiceImpl::StartWorker(
mojom::ServiceWorkerProviderInfoForSharedWorkerPtr
service_worker_provider_info,
network::mojom::URLLoaderFactoryAssociatedPtrInfo
script_loader_factory_info) {
script_loader_factory_info,
std::unique_ptr<URLLoaderFactoryBundleInfo> factory_bundle) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
// The host may already be gone if something forcibly terminated the worker
......@@ -304,7 +327,7 @@ void SharedWorkerServiceImpl::StartWorker(
BindInterface(process_host, &factory);
host->Start(std::move(factory), std::move(service_worker_provider_info),
std::move(script_loader_factory_info));
std::move(script_loader_factory_info), std::move(factory_bundle));
host->AddClient(std::move(client), process_id, frame_id, message_port);
}
......
......@@ -29,10 +29,13 @@ class MessagePortChannel;
namespace content {
class SharedWorkerInstance;
class SharedWorkerHost;
class StoragePartition;
// Created per StoragePartition.
class CONTENT_EXPORT SharedWorkerServiceImpl : public SharedWorkerService {
public:
explicit SharedWorkerServiceImpl(
SharedWorkerServiceImpl(
StoragePartition* storage_partition,
scoped_refptr<ServiceWorkerContextWrapper> service_worker_context);
~SharedWorkerServiceImpl() override;
......@@ -54,6 +57,8 @@ class CONTENT_EXPORT SharedWorkerServiceImpl : public SharedWorkerService {
void DestroyHost(SharedWorkerHost* host);
StoragePartition* storage_partition() { return storage_partition_; }
private:
friend class SharedWorkerServiceImplTest;
friend class SharedWorkerHostTest;
......@@ -72,7 +77,8 @@ class CONTENT_EXPORT SharedWorkerServiceImpl : public SharedWorkerService {
mojom::ServiceWorkerProviderInfoForSharedWorkerPtr
service_worker_provider_info,
network::mojom::URLLoaderFactoryAssociatedPtrInfo
script_loader_factory_info);
script_loader_factory_info,
std::unique_ptr<URLLoaderFactoryBundleInfo> factory_bundle);
// Returns nullptr if there is no such host.
SharedWorkerHost* FindSharedWorkerHost(int process_id, int route_id);
......@@ -83,6 +89,8 @@ class CONTENT_EXPORT SharedWorkerServiceImpl : public SharedWorkerService {
worker_hosts_;
base::OnceClosure terminate_all_workers_callback_;
// |storage_partition_| owns |this|.
StoragePartition* const storage_partition_;
scoped_refptr<ServiceWorkerContextWrapper> service_worker_context_;
base::WeakPtrFactory<SharedWorkerServiceImpl> weak_factory_;
......
......@@ -609,7 +609,7 @@ std::unique_ptr<StoragePartitionImpl> StoragePartitionImpl::Create(
partition->service_worker_context_->set_storage_partition(partition.get());
partition->shared_worker_service_ = std::make_unique<SharedWorkerServiceImpl>(
partition->service_worker_context_);
partition.get(), partition->service_worker_context_);
partition->appcache_service_ =
new ChromeAppCacheService(quota_manager_proxy.get());
......
......@@ -8,6 +8,7 @@ import "content/common/service_worker/service_worker_provider.mojom";
import "content/common/shared_worker/shared_worker.mojom";
import "content/common/shared_worker/shared_worker_host.mojom";
import "content/common/shared_worker/shared_worker_info.mojom";
import "content/common/url_loader_factory_bundle.mojom";
import "mojo/public/mojom/base/unguessable_token.mojom";
import "services/network/public/mojom/url_loader_factory.mojom";
import "services/service_manager/public/mojom/interface_provider.mojom";
......@@ -53,6 +54,14 @@ interface SharedWorkerFactory {
// worker execution contexts.
associated network.mojom.URLLoaderFactory? script_loader_factory_ptr_info,
// NetworkService:
// When the Network Service is enabled, |subresource_loader_factories|
// may also be provided a means for the shared worker to load
// subresources where applicable. For example, this allows the shared
// worker to load chrome-extension:// URLs which the renderer's default
// loader factory can't load.
URLLoaderFactoryBundle? subresource_loader_factories,
SharedWorkerHost host,
SharedWorker& shared_worker,
service_manager.mojom.InterfaceProvider interface_provider);
......
......@@ -88,6 +88,7 @@
#include "ppapi/buildflags/buildflags.h"
#include "services/device/public/cpp/generic_sensor/motion_data.h"
#include "services/network/public/cpp/features.h"
#include "services/network/public/cpp/shared_url_loader_factory.h"
#include "services/network/public/cpp/wrapper_shared_url_loader_factory.h"
#include "services/service_manager/public/cpp/connector.h"
#include "services/service_manager/public/cpp/interface_provider.h"
......@@ -344,6 +345,14 @@ RendererBlinkPlatformImpl::WrapURLLoaderFactory(
network::mojom::URLLoaderFactory::Version_)));
}
std::unique_ptr<blink::WebURLLoaderFactory>
RendererBlinkPlatformImpl::WrapSharedURLLoaderFactory(
scoped_refptr<network::SharedURLLoaderFactory> factory) {
return std::make_unique<WebURLLoaderFactoryImpl>(
RenderThreadImpl::current()->resource_dispatcher()->GetWeakPtr(),
std::move(factory));
}
std::unique_ptr<blink::WebDataConsumerHandle>
RendererBlinkPlatformImpl::CreateDataConsumerHandle(
mojo::ScopedDataPipeConsumerHandle handle) {
......
......@@ -53,6 +53,10 @@ class MotionData;
class OrientationData;
}
namespace network {
class SharedURLLoaderFactory;
}
namespace content {
class BlinkInterfaceProviderImpl;
class ChildURLLoaderFactoryBundle;
......@@ -237,6 +241,8 @@ class CONTENT_EXPORT RendererBlinkPlatformImpl : public BlinkPlatformImpl {
override;
std::unique_ptr<blink::WebURLLoaderFactory> WrapURLLoaderFactory(
mojo::ScopedMessagePipeHandle url_loader_factory_handle) override;
std::unique_ptr<blink::WebURLLoaderFactory> WrapSharedURLLoaderFactory(
scoped_refptr<network::SharedURLLoaderFactory> factory) override;
std::unique_ptr<blink::WebDataConsumerHandle> CreateDataConsumerHandle(
mojo::ScopedDataPipeConsumerHandle handle) override;
void RequestPurgeMemory() override;
......
......@@ -13,6 +13,7 @@
#include "content/child/scoped_child_process_reference.h"
#include "content/common/possibly_associated_wrapper_shared_url_loader_factory.h"
#include "content/common/service_worker/service_worker_utils.h"
#include "content/common/url_loader_factory_bundle.h"
#include "content/public/common/appcache_info.h"
#include "content/public/common/content_client.h"
#include "content/public/common/content_features.h"
......@@ -22,6 +23,7 @@
#include "content/renderer/appcache/web_application_cache_host_impl.h"
#include "content/renderer/loader/child_url_loader_factory_bundle.h"
#include "content/renderer/loader/request_extra_data.h"
#include "content/renderer/loader/tracked_child_url_loader_factory_bundle.h"
#include "content/renderer/render_thread_impl.h"
#include "content/renderer/renderer_blink_platform_impl.h"
#include "content/renderer/service_worker/service_worker_network_provider.h"
......@@ -33,6 +35,7 @@
#include "third_party/blink/public/mojom/service_worker/service_worker_object.mojom.h"
#include "third_party/blink/public/platform/interface_provider.h"
#include "third_party/blink/public/platform/modules/serviceworker/web_service_worker_network_provider.h"
#include "third_party/blink/public/platform/task_type.h"
#include "third_party/blink/public/platform/url_conversion.h"
#include "third_party/blink/public/platform/web_security_origin.h"
#include "third_party/blink/public/web/web_shared_worker.h"
......@@ -142,15 +145,19 @@ class WebServiceWorkerNetworkProviderForSharedWorker
provider_->script_loader_factory()));
}
// Otherwise, it's an importScript. Use the subresource loader factory.
// Otherwise, it's an importScript. Use the subresource loader factory if
// it exists (we are controlled by a service worker).
if (!provider_->context() ||
!provider_->context()->GetSubresourceLoaderFactory()) {
return nullptr;
}
// If it's not for HTTP or HTTPS, no need to intercept the request.
if (!GURL(request.Url()).SchemeIsHTTPOrHTTPS())
// TODO(falken): Allow SubresourceLoaderFactory to handle it in order
// to support chrome-extension://.
if (!GURL(request.Url()).SchemeIsHTTPOrHTTPS()) {
return nullptr;
}
// If GetSkipServiceWorker() returns true, do not intercept the request.
if (request.GetSkipServiceWorker())
......@@ -183,6 +190,7 @@ EmbeddedSharedWorkerStub::EmbeddedSharedWorkerStub(
service_worker_provider_info,
network::mojom::URLLoaderFactoryAssociatedPtrInfo
script_loader_factory_info,
std::unique_ptr<URLLoaderFactoryBundleInfo> subresource_loaders,
mojom::SharedWorkerHostPtr host,
mojom::SharedWorkerRequest request,
service_manager::mojom::InterfaceProviderPtr interface_provider)
......@@ -200,11 +208,29 @@ EmbeddedSharedWorkerStub::EmbeddedSharedWorkerStub(
service_worker_provider_info_ = std::move(service_worker_provider_info);
script_loader_factory_info_ = std::move(script_loader_factory_info);
// Make the factory bundle for the shadow page to use for importScripts().
auto loader_factories = base::MakeRefCounted<HostChildURLLoaderFactoryBundle>(
impl_->GetTaskRunner(blink::TaskType::kInternalLoading));
// In some tests |render_thread| could be null.
RenderThreadImpl* render_thread = RenderThreadImpl::current();
if (render_thread) {
loader_factories->Update(render_thread->blink_platform_impl()
->CreateDefaultURLLoaderFactoryBundle()
->PassInterface(),
base::nullopt /* subresource_overrides */);
}
if (subresource_loaders) {
loader_factories->Update(std::make_unique<ChildURLLoaderFactoryBundleInfo>(
std::move(subresource_loaders)),
base::nullopt /* subresource_overrides */);
}
impl_->StartWorkerContext(
url_, blink::WebString::FromUTF8(name_),
blink::WebString::FromUTF8(info->content_security_policy),
info->content_security_policy_type, info->creation_address_space,
devtools_worker_token, content_settings.PassInterface().PassHandle(),
devtools_worker_token, std::move(loader_factories),
content_settings.PassInterface().PassHandle(),
interface_provider.PassInterface().PassHandle());
// If the host drops its connection, then self-destruct.
......@@ -278,6 +304,9 @@ EmbeddedSharedWorkerStub::CreateServiceWorkerNetworkProvider() {
scoped_refptr<network::SharedURLLoaderFactory> fallback_factory;
// current() may be null in tests.
if (RenderThreadImpl* render_thread = RenderThreadImpl::current()) {
// TODO(crbug.com/839982): Make a bundle using the |factory_bundle| passed
// to the ctor instead, otherwise chrome-extension:// won't work for network
// fallback.
scoped_refptr<ChildURLLoaderFactoryBundle> bundle =
render_thread->blink_platform_impl()
->CreateDefaultURLLoaderFactoryBundle();
......
......@@ -40,6 +40,7 @@ class MessagePortChannel;
}
namespace content {
class URLLoaderFactoryBundleInfo;
class WebApplicationCacheHostImpl;
// A stub class to receive IPC from browser process and talk to
......@@ -63,6 +64,7 @@ class EmbeddedSharedWorkerStub : public blink::WebSharedWorkerClient,
service_worker_provider_info,
network::mojom::URLLoaderFactoryAssociatedPtrInfo
script_loader_factory_info,
std::unique_ptr<URLLoaderFactoryBundleInfo> subresource_loaders,
mojom::SharedWorkerHostPtr host,
mojom::SharedWorkerRequest request,
service_manager::mojom::InterfaceProviderPtr interface_provider);
......
......@@ -5,6 +5,7 @@
#include "content/renderer/shared_worker/shared_worker_factory_impl.h"
#include "base/memory/ptr_util.h"
#include "content/common/url_loader_factory_bundle.h"
#include "content/renderer/shared_worker/embedded_shared_worker_stub.h"
#include "mojo/public/cpp/bindings/strong_binding.h"
......@@ -28,6 +29,7 @@ void SharedWorkerFactoryImpl::CreateSharedWorker(
service_worker_provider_info,
network::mojom::URLLoaderFactoryAssociatedPtrInfo
script_loader_factory_ptr_info,
std::unique_ptr<URLLoaderFactoryBundleInfo> subresource_loaders,
mojom::SharedWorkerHostPtr host,
mojom::SharedWorkerRequest request,
service_manager::mojom::InterfaceProviderPtr interface_provider) {
......@@ -35,8 +37,8 @@ void SharedWorkerFactoryImpl::CreateSharedWorker(
new EmbeddedSharedWorkerStub(
std::move(info), pause_on_start, devtools_worker_token,
std::move(content_settings), std::move(service_worker_provider_info),
std::move(script_loader_factory_ptr_info), std::move(host),
std::move(request), std::move(interface_provider));
std::move(script_loader_factory_ptr_info), std::move(subresource_loaders),
std::move(host), std::move(request), std::move(interface_provider));
}
} // namespace content
......@@ -11,6 +11,7 @@
#include "services/network/public/mojom/url_loader_factory.mojom.h"
namespace content {
class URLLoaderFactoryBundleInfo;
class SharedWorkerFactoryImpl : public mojom::SharedWorkerFactory {
public:
......@@ -29,6 +30,7 @@ class SharedWorkerFactoryImpl : public mojom::SharedWorkerFactory {
service_worker_provider_info,
network::mojom::URLLoaderFactoryAssociatedPtrInfo
script_loader_factory_ptr_info,
std::unique_ptr<URLLoaderFactoryBundleInfo> subresource_loaders,
mojom::SharedWorkerHostPtr host,
mojom::SharedWorkerRequest request,
service_manager::mojom::InterfaceProviderPtr interface_provider) override;
......
......@@ -200,10 +200,6 @@
-PredictorBrowserTest.SubframeInitiatesPreconnects
-PredictorBrowserTest.SubframeLearning
# Support URLLoaderFactories from embedder in shared workers.
# https://crbug.com/839982
-ExtensionApiTestWithSwitch.ExtensionDebugger
# https://crbug.com/832749
# Add DMServer header
-ChromeResourceDispatcherHostDelegateBrowserTest.PolicyHeader
......
......@@ -23,6 +23,7 @@ include_rules = [
"+net/http",
"+services/network/public/cpp/cors/cors_error_status.h",
"+services/network/public/cpp/cors/preflight_result.h",
"+services/network/public/cpp/shared_url_loader_factory.h",
# Enforce to use mojom-shared.h in blink/public so that it can compile
# inside and outside Blink.
......
......@@ -44,6 +44,7 @@
#include "components/viz/common/surfaces/frame_sink_id.h"
#include "mojo/public/cpp/system/data_pipe.h"
#include "mojo/public/cpp/system/message_pipe.h"
#include "services/network/public/cpp/shared_url_loader_factory.h"
#include "third_party/blink/public/common/feature_policy/feature_policy.h"
#include "third_party/blink/public/platform/blame_context.h"
#include "third_party/blink/public/platform/user_metrics_action.h"
......@@ -307,6 +308,14 @@ class BLINK_PLATFORM_EXPORT Platform {
// Returns the platform's default URLLoaderFactory. It is expected that the
// returned value is stored and to be used for all the CreateURLLoader
// requests for the same loading context.
//
// WARNING: This factory understands http(s) and blob URLs, but it does not
// understand URLs like chrome-extension:// and file:// as those are provided
// by the browser process on a per-frame or per-worker basis. If you require
// support for such URLs, you must add that support manually. Typically you
// get a factory bundle from the browser process, and compose a new factory
// using both the bundle and this default.
//
// TODO(kinuko): See if we can deprecate this too.
virtual std::unique_ptr<WebURLLoaderFactory> CreateDefaultURLLoaderFactory() {
return nullptr;
......@@ -319,6 +328,14 @@ class BLINK_PLATFORM_EXPORT Platform {
return nullptr;
}
// Returns a new WebURLLoaderFactory that wraps the given
// network::SharedURLLoaderFactory.
virtual std::unique_ptr<blink::WebURLLoaderFactory>
WrapSharedURLLoaderFactory(
scoped_refptr<network::SharedURLLoaderFactory> factory) {
return nullptr;
}
// Returns a WebDataConsumerHandle for a given mojo data pipe endpoint.
virtual std::unique_ptr<WebDataConsumerHandle> CreateDataConsumerHandle(
mojo::ScopedDataPipeConsumerHandle handle) {
......
......@@ -37,9 +37,18 @@
#include "mojo/public/cpp/bindings/scoped_interface_endpoint_handle.h"
#include "mojo/public/cpp/system/message_pipe.h"
#include "third_party/blink/public/mojom/net/ip_address_space.mojom-shared.h"
#include "third_party/blink/public/platform/task_type.h"
#include "third_party/blink/public/platform/web_common.h"
#include "third_party/blink/public/platform/web_content_security_policy.h"
namespace base {
class SingleThreadTaskRunner;
}
namespace network {
class SharedURLLoaderFactory;
}
namespace blink {
class MessagePortChannel;
......@@ -63,6 +72,7 @@ class BLINK_EXPORT WebSharedWorker {
WebContentSecurityPolicyType,
mojom::IPAddressSpace,
const base::UnguessableToken& devtools_worker_token,
scoped_refptr<network::SharedURLLoaderFactory> loader_factory,
mojo::ScopedMessagePipeHandle content_settings_handle,
mojo::ScopedMessagePipeHandle interface_provider) = 0;
......@@ -76,6 +86,9 @@ class BLINK_EXPORT WebSharedWorker {
virtual void PauseWorkerContextOnStart() = 0;
virtual void BindDevToolsAgent(
mojo::ScopedInterfaceEndpointHandle devtools_agent_request) = 0;
virtual scoped_refptr<base::SingleThreadTaskRunner> GetTaskRunner(
TaskType) = 0;
};
} // namespace blink
......
......@@ -21,6 +21,7 @@ include_rules = [
"+mojo/public/cpp/system",
"+services/metrics/public",
"+services/network/public/cpp/features.h",
"+services/network/public/cpp/shared_url_loader_factory.h",
"+services/network/public/mojom",
"+services/resource_coordinator/public/cpp/resource_coordinator_features.h",
"+services/service_manager/public",
......
......@@ -31,6 +31,7 @@
#include "third_party/blink/renderer/core/exported/web_shared_worker_impl.h"
#include <memory>
#include "services/network/public/cpp/shared_url_loader_factory.h"
#include "services/network/public/mojom/fetch_api.mojom-blink.h"
#include "third_party/blink/public/platform/modules/serviceworker/web_service_worker_network_provider.h"
#include "third_party/blink/public/platform/task_type.h"
......@@ -75,9 +76,12 @@
namespace blink {
WebSharedWorkerImpl::WebSharedWorkerImpl(WebSharedWorkerClient* client)
: worker_inspector_proxy_(WorkerInspectorProxy::Create()),
: shadow_page_(std::make_unique<WorkerShadowPage>(this)),
worker_inspector_proxy_(WorkerInspectorProxy::Create()),
client_(client),
creation_address_space_(mojom::IPAddressSpace::kPublic),
parent_execution_context_task_runners_(
ParentExecutionContextTaskRunners::Create()),
weak_ptr_factory_(this) {
DCHECK(IsMainThread());
}
......@@ -149,7 +153,7 @@ void WebSharedWorkerImpl::ResumeStartup() {
is_paused_on_start_ = false;
if (is_paused_on_start) {
// We'll continue in OnShadowPageInitialized().
shadow_page_->Initialize(url_);
shadow_page_->Initialize(url_, std::move(loader_factory_));
}
}
......@@ -212,6 +216,7 @@ void WebSharedWorkerImpl::StartWorkerContext(
WebContentSecurityPolicyType policy_type,
mojom::IPAddressSpace creation_address_space,
const base::UnguessableToken& devtools_worker_token,
scoped_refptr<network::SharedURLLoaderFactory> loader_factory,
mojo::ScopedMessagePipeHandle content_settings_handle,
mojo::ScopedMessagePipeHandle interface_provider) {
DCHECK(IsMainThread());
......@@ -224,18 +229,18 @@ void WebSharedWorkerImpl::StartWorkerContext(
pending_interface_provider_.set_handle(std::move(interface_provider));
devtools_worker_token_ = devtools_worker_token;
shadow_page_ = std::make_unique<WorkerShadowPage>(this);
// If we were asked to pause worker context on start and wait for debugger
// then now is a good time to do that.
client_->WorkerReadyForInspection();
if (pause_worker_context_on_start_) {
is_paused_on_start_ = true;
loader_factory_ = std::move(loader_factory);
return;
}
// We'll continue in OnShadowPageInitialized().
shadow_page_->Initialize(url_);
shadow_page_->Initialize(url_, std::move(loader_factory));
}
void WebSharedWorkerImpl::DidReceiveScriptLoaderResponse() {
......@@ -337,16 +342,8 @@ void WebSharedWorkerImpl::ContinueOnScriptLoaderFinished() {
std::move(pending_interface_provider_));
String source_code = main_script_loader_->SourceText();
// SharedWorker can sometimes run tasks that are initiated by/associated with
// a document's frame but these documents can be from a different process. So
// we intentionally populate the task runners with default task runners of the
// main thread. Note that |m_document| should not be used as it's a dummy
// document for loading that doesn't represent the frame of any associated
// document.
ParentExecutionContextTaskRunners* task_runners =
ParentExecutionContextTaskRunners::Create();
reporting_proxy_ = new SharedWorkerReportingProxy(this, task_runners);
reporting_proxy_ = new SharedWorkerReportingProxy(
this, parent_execution_context_task_runners_);
worker_thread_ = std::make_unique<SharedWorkerThread>(
name_, ThreadableLoadingContext::Create(*document), *reporting_proxy_);
probe::scriptImported(document, main_script_loader_->Identifier(),
......@@ -360,7 +357,7 @@ void WebSharedWorkerImpl::ContinueOnScriptLoaderFinished() {
GetWorkerThread()->Start(
std::move(global_scope_creation_params), thread_startup_data,
worker_inspector_proxy_->ShouldPauseOnWorkerStart(document),
task_runners);
parent_execution_context_task_runners_);
worker_inspector_proxy_->WorkerThreadCreated(document, GetWorkerThread(),
url_);
// TODO(nhiroki): Support module workers (https://crbug.com/680046).
......@@ -385,6 +382,11 @@ void WebSharedWorkerImpl::BindDevToolsAgent(
std::move(devtools_agent_request)));
}
scoped_refptr<base::SingleThreadTaskRunner> WebSharedWorkerImpl::GetTaskRunner(
TaskType task_type) {
return parent_execution_context_task_runners_->Get(task_type);
}
std::unique_ptr<WebSharedWorker> WebSharedWorker::Create(
WebSharedWorkerClient* client) {
return base::WrapUnique(new WebSharedWorkerImpl(client));
......
......@@ -48,6 +48,14 @@
#include "third_party/blink/renderer/core/workers/worker_clients.h"
#include "third_party/blink/renderer/core/workers/worker_thread.h"
namespace base {
class SingleThreadTaskRunner;
};
namespace network {
class SharedURLLoaderFactory;
};
namespace blink {
class WebApplicationCacheHost;
......@@ -87,14 +95,15 @@ class CORE_EXPORT WebSharedWorkerImpl final : public WebSharedWorker,
WebContentSecurityPolicyType,
mojom::IPAddressSpace,
const base::UnguessableToken& devtools_worker_token,
scoped_refptr<network::SharedURLLoaderFactory> loader_factory,
mojo::ScopedMessagePipeHandle content_settings_handle,
mojo::ScopedMessagePipeHandle interface_provider) override;
void Connect(MessagePortChannel) override;
void TerminateWorkerContext() override;
void PauseWorkerContextOnStart() override;
void BindDevToolsAgent(
mojo::ScopedInterfaceEndpointHandle devtools_agent_request) override;
scoped_refptr<base::SingleThreadTaskRunner> GetTaskRunner(TaskType) override;
// Callback methods for SharedWorkerReportingProxy.
void CountFeature(WebFeature);
......@@ -131,6 +140,7 @@ class CORE_EXPORT WebSharedWorkerImpl final : public WebSharedWorker,
bool asked_to_terminate_ = false;
bool pause_worker_context_on_start_ = false;
bool is_paused_on_start_ = false;
scoped_refptr<network::SharedURLLoaderFactory> loader_factory_;
// Kept around only while main script loading is ongoing.
scoped_refptr<WorkerClassicScriptLoader> main_script_loader_;
......@@ -142,6 +152,15 @@ class CORE_EXPORT WebSharedWorkerImpl final : public WebSharedWorker,
service_manager::mojom::blink::InterfaceProviderPtrInfo
pending_interface_provider_;
// SharedWorker can sometimes run tasks that are initiated by/associated with
// a document's frame but these documents can be from a different process. So
// we intentionally populate the task runners with default task runners of the
// main thread. Note that |shadow_page_| should not be used as it's a dummy
// document for loading that doesn't represent the frame of any associated
// document.
Persistent<ParentExecutionContextTaskRunners>
parent_execution_context_task_runners_;
base::WeakPtrFactory<WebSharedWorkerImpl> weak_ptr_factory_;
};
......
......@@ -20,12 +20,13 @@ WorkerShadowPage::WorkerShadowPage(Client* client)
web_view_(WebViewImpl::Create(nullptr,
mojom::PageVisibilityState::kVisible,
nullptr)),
main_frame_(WebLocalFrameImpl::CreateMainFrame(web_view_,
this,
nullptr,
nullptr,
g_empty_atom,
WebSandboxFlags::kNone)) {
main_frame_(
WebLocalFrameImpl::CreateMainFrame(web_view_,
this,
nullptr /* interface_registry */,
nullptr /* opener */,
g_empty_atom,
WebSandboxFlags::kNone)) {
DCHECK(IsMainThread());
// TODO(http://crbug.com/363843): This needs to find a better way to
......@@ -48,10 +49,14 @@ WorkerShadowPage::~WorkerShadowPage() {
main_frame_->Close();
}
void WorkerShadowPage::Initialize(const KURL& script_url) {
void WorkerShadowPage::Initialize(
const KURL& script_url,
scoped_refptr<network::SharedURLLoaderFactory> loader_factory) {
DCHECK(IsMainThread());
AdvanceState(State::kInitializing);
loader_factory_ = std::move(loader_factory);
// Construct substitute data source. We only need it to have same origin as
// the worker so the loading checks work correctly.
CString content("");
......@@ -87,6 +92,8 @@ WorkerShadowPage::CreateApplicationCacheHost(
std::unique_ptr<blink::WebURLLoaderFactory>
WorkerShadowPage::CreateURLLoaderFactory() {
DCHECK(IsMainThread());
if (loader_factory_)
return Platform::Current()->WrapSharedURLLoaderFactory(loader_factory_);
return Platform::Current()->CreateDefaultURLLoaderFactory();
}
......
......@@ -5,12 +5,17 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_EXPORTED_WORKER_SHADOW_PAGE_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_EXPORTED_WORKER_SHADOW_PAGE_H_
#include "services/network/public/cpp/shared_url_loader_factory.h"
#include "third_party/blink/public/web/web_document_loader.h"
#include "third_party/blink/public/web/web_frame_client.h"
#include "third_party/blink/public/web/web_view.h"
#include "third_party/blink/renderer/core/exported/web_dev_tools_agent_impl.h"
#include "third_party/blink/renderer/core/frame/web_local_frame_impl.h"
namespace network {
class SharedURLLoaderFactory;
}
namespace blink {
class ContentSecurityPolicy;
......@@ -51,8 +56,18 @@ class CORE_EXPORT WorkerShadowPage : public WebFrameClient {
explicit WorkerShadowPage(Client*);
~WorkerShadowPage() override;
// Calls Client::OnShadowPageInitialized() when complete.
void Initialize(const KURL& script_url);
// Initializes this instance and calls Client::OnShadowPageInitialized() when
// complete.
//
// If |loader_factory| is non-null, the shadow page will use it when making
// requests. For service workers, it is null since all loads go through
// ServiceWorkerNetworkProvider::script_loader_factory(). For shared workers,
// it is non-null since only the main script request goes through the script
// loader factory (implemented by SharedWorkerScriptLoaderFactory), and
// importScripts() go through the shadow page loader.
void Initialize(
const KURL& script_url,
scoped_refptr<network::SharedURLLoaderFactory> loader_factory);
void SetContentSecurityPolicyAndReferrerPolicy(ContentSecurityPolicy*,
String referrer_policy);
......@@ -90,6 +105,7 @@ class CORE_EXPORT WorkerShadowPage : public WebFrameClient {
Client* client_;
WebView* web_view_;
Persistent<WebLocalFrameImpl> main_frame_;
scoped_refptr<network::SharedURLLoaderFactory> loader_factory_;
State state_ = State::kUninitialized;
};
......
include_rules = [
"+base/memory/scoped_refptr.h",
"+services/network/public/cpp/shared_url_loader_factory.h",
"+services/service_manager/public/mojom/interface_provider.mojom-blink.h",
"+third_party/blink/public/common",
"+third_party/blink/public/web",
......
......@@ -31,6 +31,7 @@
#include "third_party/blink/renderer/modules/exported/web_embedded_worker_impl.h"
#include <memory>
#include "services/network/public/cpp/shared_url_loader_factory.h"
#include "third_party/blink/public/platform/modules/serviceworker/web_service_worker_network_provider.h"
#include "third_party/blink/public/platform/modules/serviceworker/web_service_worker_provider.h"
#include "third_party/blink/public/platform/task_type.h"
......@@ -155,7 +156,8 @@ void WebEmbeddedWorkerImpl::StartWorkerContext(
return;
}
shadow_page_->Initialize(worker_start_data_.script_url);
shadow_page_->Initialize(worker_start_data_.script_url,
nullptr /* loader_factory */);
}
void WebEmbeddedWorkerImpl::TerminateWorkerContext() {
......@@ -284,8 +286,10 @@ void WebEmbeddedWorkerImpl::OnShadowPageInitialized() {
void WebEmbeddedWorkerImpl::ResumeStartup() {
bool was_waiting = (waiting_for_debugger_state_ == kWaitingForDebugger);
waiting_for_debugger_state_ = kNotWaitingForDebugger;
if (was_waiting)
shadow_page_->Initialize(worker_start_data_.script_url);
if (was_waiting) {
shadow_page_->Initialize(worker_start_data_.script_url,
nullptr /* loader_factory */);
}
}
const base::UnguessableToken& WebEmbeddedWorkerImpl::GetDevToolsWorkerToken() {
......
......@@ -146,6 +146,9 @@ _CONFIG = [
# nested in the blink namespace.
'internal::.+',
# Network service.
'network::.+',
# Some test helpers live in the blink::test namespace.
'test::.+',
......
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