Commit f904fcc9 authored by Matt Falkenhagen's avatar Matt Falkenhagen Committed by Commit Bot

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

This relands r561423.
Original code review: https://chromium-review.googlesource.com/1069956

The original patch had a problem because the shadow page was created
before UnguessableToken. The fix is to not create the shadow page early,
which was only needed in an earlier patchset to get the task runner
from it.

Bug: 839982, 846545
Change-Id: Id6545d9d86a3a56a04e7f83a840d9acddd55f51b
Cq-Include-Trybots: master.tryserver.chromium.linux:linux_mojo
TBR: kinuko, dcheng
Reviewed-on: https://chromium-review.googlesource.com/1073037
Commit-Queue: Matt Falkenhagen <falken@chromium.org>
Reviewed-by: default avatarHiroki Nakagawa <nhiroki@chromium.org>
Cr-Commit-Position: refs/heads/master@{#561793}
parent 80c7cd99
......@@ -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;
......
......@@ -195,10 +195,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"
......@@ -78,6 +79,8 @@ WebSharedWorkerImpl::WebSharedWorkerImpl(WebSharedWorkerClient* client)
: 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());
}
......@@ -212,6 +215,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,7 +228,11 @@ 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);
// |shadow_page_| must be created after |devtools_worker_token_| because it
// triggers creation of a InspectorNetworkAgent that tries to access the
// token.
shadow_page_ =
std::make_unique<WorkerShadowPage>(this, std::move(loader_factory));
// If we were asked to pause worker context on start and wait for debugger
// then now is a good time to do that.
......@@ -337,16 +345,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 +360,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 +385,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);
......@@ -142,6 +151,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_;
};
......
......@@ -15,17 +15,21 @@
namespace blink {
WorkerShadowPage::WorkerShadowPage(Client* client)
WorkerShadowPage::WorkerShadowPage(
Client* client,
scoped_refptr<network::SharedURLLoaderFactory> loader_factory)
: 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)),
loader_factory_(std::move(loader_factory)) {
DCHECK(IsMainThread());
// TODO(http://crbug.com/363843): This needs to find a better way to
......@@ -87,6 +91,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;
......@@ -48,10 +53,15 @@ class CORE_EXPORT WorkerShadowPage : public WebFrameClient {
virtual const base::UnguessableToken& GetDevToolsWorkerToken() = 0;
};
explicit WorkerShadowPage(Client*);
// If |loader_factory| is non-null, the shadow page will use it when making
// requests.
WorkerShadowPage(
Client* client,
scoped_refptr<network::SharedURLLoaderFactory> loader_factory);
~WorkerShadowPage() override;
// Calls Client::OnShadowPageInitialized() when complete.
// Initializes this instance and calls Client::OnShadowPageInitialized() when
// complete.
void Initialize(const KURL& script_url);
void SetContentSecurityPolicyAndReferrerPolicy(ContentSecurityPolicy*,
......@@ -90,6 +100,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"
......@@ -140,7 +141,13 @@ void WebEmbeddedWorkerImpl::StartWorkerContext(
pause_after_download_state_ = kDoPauseAfterDownload;
devtools_worker_token_ = data.devtools_worker_token;
shadow_page_ = std::make_unique<WorkerShadowPage>(this);
// |loader_factory| is null since all loads for new scripts go through
// ServiceWorkerNetworkProvider::script_loader_factory() rather than the
// shadow page's loader. This is different to shared workers, which use the
// script loader factory for the main script only, and the shadow page loader
// for importScripts().
shadow_page_ =
std::make_unique<WorkerShadowPage>(this, nullptr /* loader_factory */);
WebSettings* settings = shadow_page_->GetSettings();
// Currently we block all mixed-content requests from a ServiceWorker.
......
......@@ -153,6 +153,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