PlzWorker: Create an AppCache interceptor for shared workers
This is one of CLs for PlzWorker for shared workers. In this CL, responses
served by the interceptor are actually not used yet and tests are still failing.
The subsequent CLs will wire up the interceptor up to resource loaders.
DesignDoc:
https://docs.google.com/document/d/1Jtn33bvqkqWxq6K7HIA4uU6HLWPTmOD7vFviacfTmhM/edit?usp=sharing
Bug: 715632
Change-Id: Iba11b4c0bd598d8ca3c445196f21855c46b1069e
Cq-Include-Trybots: luci.chromium.try:linux_mojo
Reviewed-on: https://chromium-review.googlesource.com/1146417
Commit-Queue: Hiroki Nakagawa <[email protected]>
Reviewed-by: Matt Falkenhagen <[email protected]>
Reviewed-by: Kinuko Yasuda <[email protected]>
Cr-Commit-Position: refs/heads/master@{#578225}
diff --git a/content/browser/appcache/appcache_request_handler.cc b/content/browser/appcache/appcache_request_handler.cc
index 7f291f9..65cc571 100644
--- a/content/browser/appcache/appcache_request_handler.cc
+++ b/content/browser/appcache/appcache_request_handler.cc
@@ -222,17 +222,17 @@
// static
std::unique_ptr<AppCacheRequestHandler>
-AppCacheRequestHandler::InitializeForNavigationNetworkService(
+AppCacheRequestHandler::InitializeForMainResourceNetworkService(
const network::ResourceRequest& request,
- AppCacheNavigationHandleCore* appcache_handle_core,
+ base::WeakPtr<AppCacheHost> appcache_host,
scoped_refptr<network::SharedURLLoaderFactory> network_loader_factory) {
std::unique_ptr<AppCacheRequestHandler> handler =
- appcache_handle_core->host()->CreateRequestHandler(
+ appcache_host->CreateRequestHandler(
AppCacheURLLoaderRequest::Create(request),
static_cast<ResourceType>(request.resource_type),
request.should_reset_appcache);
handler->network_loader_factory_ = std::move(network_loader_factory);
- handler->appcache_host_ = appcache_handle_core->host()->GetWeakPtr();
+ handler->appcache_host_ = std::move(appcache_host);
return handler;
}
diff --git a/content/browser/appcache/appcache_request_handler.h b/content/browser/appcache/appcache_request_handler.h
index b8b8266..3b369c7 100644
--- a/content/browser/appcache/appcache_request_handler.h
+++ b/content/browser/appcache/appcache_request_handler.h
@@ -33,7 +33,6 @@
namespace content {
class AppCacheJob;
-class AppCacheNavigationHandleCore;
class AppCacheSubresourceURLFactory;
class AppCacheRequest;
class AppCacheRequestHandlerTest;
@@ -106,9 +105,9 @@
LoaderCallback callback);
static std::unique_ptr<AppCacheRequestHandler>
- InitializeForNavigationNetworkService(
+ InitializeForMainResourceNetworkService(
const network::ResourceRequest& request,
- AppCacheNavigationHandleCore* appcache_handle_core,
+ base::WeakPtr<AppCacheHost> appcache_host,
scoped_refptr<network::SharedURLLoaderFactory> network_loader_factory);
static bool IsMainResourceType(ResourceType type) {
diff --git a/content/browser/loader/navigation_url_loader_impl.cc b/content/browser/loader/navigation_url_loader_impl.cc
index dbb1b89..6c5184fb 100644
--- a/content/browser/loader/navigation_url_loader_impl.cc
+++ b/content/browser/loader/navigation_url_loader_impl.cc
@@ -15,6 +15,7 @@
#include "base/trace_event/trace_event.h"
#include "components/download/public/common/download_stats.h"
#include "content/browser/appcache/appcache_navigation_handle.h"
+#include "content/browser/appcache/appcache_navigation_handle_core.h"
#include "content/browser/appcache/appcache_request_handler.h"
#include "content/browser/blob_storage/chrome_blob_storage_context.h"
#include "content/browser/devtools/render_frame_devtools_agent_host.h"
@@ -615,8 +616,8 @@
if (appcache_handle_core) {
std::unique_ptr<NavigationLoaderInterceptor> appcache_interceptor =
- AppCacheRequestHandler::InitializeForNavigationNetworkService(
- *resource_request_, appcache_handle_core,
+ AppCacheRequestHandler::InitializeForMainResourceNetworkService(
+ *resource_request_, appcache_handle_core->host()->GetWeakPtr(),
network_loader_factory_);
if (appcache_interceptor)
interceptors_.push_back(std::move(appcache_interceptor));
diff --git a/content/browser/shared_worker/shared_worker_host.cc b/content/browser/shared_worker/shared_worker_host.cc
index 407310c..aa29ba3 100644
--- a/content/browser/shared_worker/shared_worker_host.cc
+++ b/content/browser/shared_worker/shared_worker_host.cc
@@ -9,6 +9,7 @@
#include "base/feature_list.h"
#include "base/metrics/histogram_macros.h"
#include "base/unguessable_token.h"
+#include "content/browser/appcache/appcache_navigation_handle.h"
#include "content/browser/devtools/shared_worker_devtools_manager.h"
#include "content/browser/interface_provider_filtering.h"
#include "content/browser/renderer_interface_binders.h"
@@ -416,6 +417,12 @@
worker_->BindDevToolsAgent(std::move(request));
}
+void SharedWorkerHost::SetAppCacheHandle(
+ std::unique_ptr<AppCacheNavigationHandle> appcache_handle) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ appcache_handle_ = std::move(appcache_handle);
+}
+
void SharedWorkerHost::OnClientConnectionLost() {
// We'll get a notification for each dropped connection.
for (auto it = clients_.begin(); it != clients_.end(); ++it) {
diff --git a/content/browser/shared_worker/shared_worker_host.h b/content/browser/shared_worker/shared_worker_host.h
index 95f9f2c2..d8c7382 100644
--- a/content/browser/shared_worker/shared_worker_host.h
+++ b/content/browser/shared_worker/shared_worker_host.h
@@ -33,6 +33,8 @@
}
namespace content {
+
+class AppCacheNavigationHandle;
class SharedWorkerContentSettingsProxyImpl;
class SharedWorkerInstance;
class SharedWorkerServiceImpl;
@@ -86,6 +88,9 @@
void BindDevToolsAgent(blink::mojom::DevToolsAgentAssociatedRequest request);
+ void SetAppCacheHandle(
+ std::unique_ptr<AppCacheNavigationHandle> appcache_handle);
+
SharedWorkerInstance* instance() { return instance_.get(); }
int process_id() const { return process_id_; }
bool IsAvailable() const;
@@ -172,6 +177,11 @@
mojo::Binding<service_manager::mojom::InterfaceProvider>
interface_provider_binding_;
+ // NetworkService:
+ // The handle owns the precreated AppCacheHost until it's claimed by the
+ // renderer after main script loading finishes.
+ std::unique_ptr<AppCacheNavigationHandle> appcache_handle_;
+
Phase phase_ = Phase::kInitial;
base::WeakPtrFactory<SharedWorkerHost> weak_factory_;
diff --git a/content/browser/shared_worker/shared_worker_script_loader.cc b/content/browser/shared_worker/shared_worker_script_loader.cc
index 81fb376..d363f74 100644
--- a/content/browser/shared_worker/shared_worker_script_loader.cc
+++ b/content/browser/shared_worker/shared_worker_script_loader.cc
@@ -4,6 +4,7 @@
#include "content/browser/shared_worker/shared_worker_script_loader.h"
+#include "content/browser/appcache/appcache_request_handler.h"
#include "content/browser/loader/navigation_loader_interceptor.h"
#include "content/browser/service_worker/service_worker_provider_host.h"
#include "content/public/browser/resource_context.h"
@@ -20,6 +21,7 @@
const network::ResourceRequest& resource_request,
network::mojom::URLLoaderClientPtr client,
base::WeakPtr<ServiceWorkerProviderHost> service_worker_provider_host,
+ base::WeakPtr<AppCacheHost> appcache_host,
ResourceContext* resource_context,
scoped_refptr<network::SharedURLLoaderFactory> default_loader_factory,
const net::MutableNetworkTrafficAnnotationTag& traffic_annotation)
@@ -37,9 +39,19 @@
DCHECK(blink::ServiceWorkerUtils::IsServicificationEnabled());
if (service_worker_provider_host_) {
- service_worker_interceptor_ =
+ std::unique_ptr<NavigationLoaderInterceptor> service_worker_interceptor =
ServiceWorkerRequestHandler::InitializeForSharedWorker(
resource_request_, service_worker_provider_host_);
+ if (service_worker_interceptor)
+ interceptors_.push_back(std::move(service_worker_interceptor));
+ }
+
+ if (appcache_host) {
+ std::unique_ptr<NavigationLoaderInterceptor> appcache_interceptor =
+ AppCacheRequestHandler::InitializeForMainResourceNetworkService(
+ resource_request_, appcache_host, default_loader_factory_);
+ if (appcache_interceptor)
+ interceptors_.push_back(std::move(appcache_interceptor));
}
Start();
@@ -48,12 +60,12 @@
SharedWorkerScriptLoader::~SharedWorkerScriptLoader() = default;
void SharedWorkerScriptLoader::Start() {
- if (service_worker_interceptor_) {
- service_worker_interceptor_->MaybeCreateLoader(
+ if (interceptor_index_ < interceptors_.size()) {
+ auto* interceptor = interceptors_[interceptor_index_++].get();
+ interceptor->MaybeCreateLoader(
resource_request_, resource_context_,
base::BindOnce(&SharedWorkerScriptLoader::MaybeStartLoader,
- weak_factory_.GetWeakPtr(),
- service_worker_interceptor_.get()));
+ weak_factory_.GetWeakPtr(), interceptor));
return;
}
@@ -63,6 +75,16 @@
void SharedWorkerScriptLoader::MaybeStartLoader(
NavigationLoaderInterceptor* interceptor,
SingleRequestURLLoaderFactory::RequestHandler single_request_handler) {
+ DCHECK(interceptor);
+
+ // TODO(nhiroki): Create SubresourceLoaderParams for intercepting subresource
+ // requests and populating the "controller" field in ServiceWorkerContainer,
+ // and send the params to the renderer when we create the SharedWorker.
+ // Note that we shouldn't try the next interceptor if this interceptor
+ // provides SubresourceLoaderParams. See comments on
+ // NavigationLoaderInterceptor::MaybeCreateSubresourceLoaderParams() for
+ // details.
+
if (single_request_handler) {
// The interceptor elected to handle the request. Use it.
network::mojom::URLLoaderClientPtr client;
@@ -76,7 +98,8 @@
return;
}
- LoadFromNetwork();
+ // Continue until all the interceptors are tried.
+ Start();
}
void SharedWorkerScriptLoader::LoadFromNetwork() {
@@ -117,6 +140,7 @@
resource_request_.referrer_policy = redirect_info_->new_referrer_policy;
// Restart the request.
+ interceptor_index_ = 0;
url_loader_client_binding_.Unbind();
redirect_info_.reset();
Start();
diff --git a/content/browser/shared_worker/shared_worker_script_loader.h b/content/browser/shared_worker/shared_worker_script_loader.h
index e7eb646..4730433 100644
--- a/content/browser/shared_worker/shared_worker_script_loader.h
+++ b/content/browser/shared_worker/shared_worker_script_loader.h
@@ -17,6 +17,8 @@
} // namespace network
namespace content {
+
+class AppCacheHost;
class NavigationLoaderInterceptor;
class ResourceContext;
class ServiceWorkerProviderHost;
@@ -47,6 +49,7 @@
const network::ResourceRequest& resource_request,
network::mojom::URLLoaderClientPtr client,
base::WeakPtr<ServiceWorkerProviderHost> service_worker_provider_host,
+ base::WeakPtr<AppCacheHost> appcache_host,
ResourceContext* resource_context,
scoped_refptr<network::SharedURLLoaderFactory> default_loader_factory,
const net::MutableNetworkTrafficAnnotationTag& traffic_annotation);
@@ -85,8 +88,10 @@
SingleRequestURLLoaderFactory::RequestHandler single_request_handler);
void LoadFromNetwork();
- // TODO(falken): Add other interceptors like in NavigationURLLoaderImpl.
- std::unique_ptr<NavigationLoaderInterceptor> service_worker_interceptor_;
+ // The order of the interceptors is important. The former interceptor can
+ // preferentially get a chance to intercept a network request.
+ std::vector<std::unique_ptr<NavigationLoaderInterceptor>> interceptors_;
+ size_t interceptor_index_ = 0;
const int32_t routing_id_;
const int32_t request_id_;
diff --git a/content/browser/shared_worker/shared_worker_script_loader_factory.cc b/content/browser/shared_worker/shared_worker_script_loader_factory.cc
index 6a21c378..c4a876b 100644
--- a/content/browser/shared_worker/shared_worker_script_loader_factory.cc
+++ b/content/browser/shared_worker/shared_worker_script_loader_factory.cc
@@ -10,6 +10,7 @@
#include "content/browser/service_worker/service_worker_provider_host.h"
#include "content/browser/service_worker/service_worker_version.h"
#include "content/browser/shared_worker/shared_worker_script_loader.h"
+#include "content/public/browser/browser_thread.h"
#include "mojo/public/cpp/bindings/strong_binding.h"
#include "services/network/public/cpp/resource_response.h"
#include "services/network/public/cpp/shared_url_loader_factory.h"
@@ -21,17 +22,22 @@
SharedWorkerScriptLoaderFactory::SharedWorkerScriptLoaderFactory(
ServiceWorkerContextWrapper* context,
base::WeakPtr<ServiceWorkerProviderHost> service_worker_provider_host,
+ base::WeakPtr<AppCacheHost> appcache_host,
ResourceContext* resource_context,
scoped_refptr<network::SharedURLLoaderFactory> loader_factory)
- : service_worker_provider_host_(service_worker_provider_host),
+ : service_worker_provider_host_(std::move(service_worker_provider_host)),
+ appcache_host_(std::move(appcache_host)),
resource_context_(resource_context),
loader_factory_(std::move(loader_factory)) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
DCHECK(blink::ServiceWorkerUtils::IsServicificationEnabled());
DCHECK_EQ(service_worker_provider_host_->provider_type(),
blink::mojom::ServiceWorkerProviderType::kForSharedWorker);
}
-SharedWorkerScriptLoaderFactory::~SharedWorkerScriptLoaderFactory() {}
+SharedWorkerScriptLoaderFactory::~SharedWorkerScriptLoaderFactory() {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+}
void SharedWorkerScriptLoaderFactory::CreateLoaderAndStart(
network::mojom::URLLoaderRequest request,
@@ -41,6 +47,8 @@
const network::ResourceRequest& resource_request,
network::mojom::URLLoaderClientPtr client,
const net::MutableNetworkTrafficAnnotationTag& traffic_annotation) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+
// Handle only the main script (RESOURCE_TYPE_SHARED_WORKER). Import scripts
// should go to the network loader or controller.
if (resource_request.resource_type != RESOURCE_TYPE_SHARED_WORKER) {
@@ -54,8 +62,8 @@
mojo::MakeStrongBinding(
std::make_unique<SharedWorkerScriptLoader>(
routing_id, request_id, options, resource_request, std::move(client),
- service_worker_provider_host_, resource_context_, loader_factory_,
- traffic_annotation),
+ service_worker_provider_host_, appcache_host_, resource_context_,
+ loader_factory_, traffic_annotation),
std::move(request));
}
diff --git a/content/browser/shared_worker/shared_worker_script_loader_factory.h b/content/browser/shared_worker/shared_worker_script_loader_factory.h
index 2e42cfaa..356baea 100644
--- a/content/browser/shared_worker/shared_worker_script_loader_factory.h
+++ b/content/browser/shared_worker/shared_worker_script_loader_factory.h
@@ -14,6 +14,7 @@
namespace content {
+class AppCacheHost;
class ServiceWorkerContextWrapper;
class ServiceWorkerProviderHost;
class ResourceContext;
@@ -38,6 +39,7 @@
SharedWorkerScriptLoaderFactory(
ServiceWorkerContextWrapper* context,
base::WeakPtr<ServiceWorkerProviderHost> provider_host,
+ base::WeakPtr<AppCacheHost> appcache_host,
ResourceContext* resource_context,
scoped_refptr<network::SharedURLLoaderFactory> loader_factory);
~SharedWorkerScriptLoaderFactory() override;
@@ -55,6 +57,7 @@
private:
base::WeakPtr<ServiceWorkerProviderHost> service_worker_provider_host_;
+ base::WeakPtr<AppCacheHost> appcache_host_;
ResourceContext* resource_context_ = nullptr;
scoped_refptr<network::SharedURLLoaderFactory> loader_factory_;
diff --git a/content/browser/shared_worker/shared_worker_service_impl.cc b/content/browser/shared_worker/shared_worker_service_impl.cc
index d6b462f..165dca9 100644
--- a/content/browser/shared_worker/shared_worker_service_impl.cc
+++ b/content/browser/shared_worker/shared_worker_service_impl.cc
@@ -10,10 +10,12 @@
#include <iterator>
#include "base/callback.h"
+#include "base/feature_list.h"
#include "base/logging.h"
#include "base/macros.h"
#include "base/task_scheduler/post_task.h"
#include "content/browser/appcache/appcache_navigation_handle.h"
+#include "content/browser/appcache/appcache_navigation_handle_core.h"
#include "content/browser/file_url_loader_factory.h"
#include "content/browser/shared_worker/shared_worker_host.h"
#include "content/browser/shared_worker/shared_worker_instance.h"
@@ -31,6 +33,7 @@
#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 "services/network/public/cpp/features.h"
#include "third_party/blink/public/common/message_port/message_port_channel.h"
#include "third_party/blink/public/common/service_worker/service_worker_utils.h"
#include "url/origin.h"
@@ -89,6 +92,7 @@
std::unique_ptr<URLLoaderFactoryBundleInfo>
factory_bundle_for_renderer_info,
scoped_refptr<ServiceWorkerContextWrapper> context,
+ AppCacheNavigationHandleCore* appcache_handle_core,
std::unique_ptr<network::SharedURLLoaderFactoryInfo>
blob_url_loader_factory_info,
int process_id,
@@ -128,12 +132,20 @@
factory_bundle->SetDefaultFactory(std::move(network_factory_ptr));
}
+ // It's safe for |appcache_handle_core| to be a raw pointer. The core is owned
+ // by AppCacheNavigationHandle on the UI thread, which posts a task to delete
+ // the core on the IO thread on destruction, which must happen after this
+ // task.
+ base::WeakPtr<AppCacheHost> appcache_host =
+ appcache_handle_core ? appcache_handle_core->host()->GetWeakPtr()
+ : nullptr;
+
// Create the SharedWorkerScriptLoaderFactory.
network::mojom::URLLoaderFactoryAssociatedPtrInfo script_loader_factory;
mojo::MakeStrongAssociatedBinding(
std::make_unique<SharedWorkerScriptLoaderFactory>(
- context.get(), host->AsWeakPtr(), context->resource_context(),
- std::move(url_loader_factory)),
+ context.get(), host->AsWeakPtr(), std::move(appcache_host),
+ context->resource_context(), std::move(url_loader_factory)),
mojo::MakeRequest(&script_loader_factory));
// We continue in StartWorker.
@@ -294,8 +306,9 @@
StoragePartitionImpl* storage_partition =
service_worker_context_->storage_partition();
- // 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.
+
+ // Bounce to the IO thread to setup service worker and appcache support in
+ // case the request for the worker script will need to be intercepted by them.
if (blink::ServiceWorkerUtils::IsServicificationEnabled()) {
if (!storage_partition) {
// The context is shutting down. Just drop the request.
@@ -312,9 +325,15 @@
CreateFactoryBundle(process_id, storage_partition,
constructor_uses_file_url);
- // TODO(nhiroki): Create an instance of AppCacheNavigationHandle from
- // |appcache_service_| and pass its core() to the IO thread in order to set
- // up an interceptor for AppCache.
+ // An appcache interceptor is available only when the network service is
+ // enabled.
+ AppCacheNavigationHandleCore* appcache_handle_core = nullptr;
+ if (base::FeatureList::IsEnabled(network::features::kNetworkService)) {
+ auto appcache_handle =
+ std::make_unique<AppCacheNavigationHandle>(appcache_service_.get());
+ appcache_handle_core = appcache_handle->core();
+ weak_host->SetAppCacheHandle(std::move(appcache_handle));
+ }
BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
@@ -324,6 +343,7 @@
->url_loader_factory_getter(),
std::move(factory_bundle_for_browser),
std::move(factory_bundle_for_renderer), service_worker_context_,
+ appcache_handle_core,
blob_url_loader_factory ? blob_url_loader_factory->Clone()
: nullptr,
process_id,