Commit 9d247e47 authored by Kinuko Yasuda's avatar Kinuko Yasuda Committed by Commit Bot

Re-land: SW Servicification: Hook ScriptURLLoader only for script installation

Add some more code from ServiceWorkerContextRequestHandler to
ScriptURLLoaderFactory.  Also added small cleanup around IsInstalled.

Re-land of:
https://chromium-review.googlesource.com/544720 and
https://chromium-review.googlesource.com/547160

Bug: 715640
Change-Id: Iae432fb2619d1a3b05ba26cbce7563b93e86339d
Reviewed-on: https://chromium-review.googlesource.com/579030
Commit-Queue: Kinuko Yasuda <kinuko@chromium.org>
Reviewed-by: default avatarMatt Falkenhagen <falken@chromium.org>
Cr-Commit-Position: refs/heads/master@{#488702}
parent 97504bed
...@@ -21,26 +21,6 @@ ...@@ -21,26 +21,6 @@
namespace content { namespace content {
namespace {
bool IsInstalled(const ServiceWorkerVersion* version) {
switch (version->status()) {
case ServiceWorkerVersion::NEW:
case ServiceWorkerVersion::INSTALLING:
return false;
case ServiceWorkerVersion::INSTALLED:
case ServiceWorkerVersion::ACTIVATING:
case ServiceWorkerVersion::ACTIVATED:
return true;
case ServiceWorkerVersion::REDUNDANT:
return false;
}
NOTREACHED();
return false;
}
} // namespace
ServiceWorkerContextRequestHandler::ServiceWorkerContextRequestHandler( ServiceWorkerContextRequestHandler::ServiceWorkerContextRequestHandler(
base::WeakPtr<ServiceWorkerContextCore> context, base::WeakPtr<ServiceWorkerContextCore> context,
base::WeakPtr<ServiceWorkerProviderHost> provider_host, base::WeakPtr<ServiceWorkerProviderHost> provider_host,
...@@ -110,7 +90,8 @@ net::URLRequestJob* ServiceWorkerContextRequestHandler::MaybeCreateJob( ...@@ -110,7 +90,8 @@ net::URLRequestJob* ServiceWorkerContextRequestHandler::MaybeCreateJob(
MaybeCreateJobImpl(request, network_delegate, &status); MaybeCreateJobImpl(request, network_delegate, &status);
const bool is_main_script = resource_type_ == RESOURCE_TYPE_SERVICE_WORKER; const bool is_main_script = resource_type_ == RESOURCE_TYPE_SERVICE_WORKER;
ServiceWorkerMetrics::RecordContextRequestHandlerStatus( ServiceWorkerMetrics::RecordContextRequestHandlerStatus(
status, IsInstalled(version_.get()), is_main_script); status, ServiceWorkerVersion::IsInstalled(version_->status()),
is_main_script);
if (job) if (job)
return job; return job;
...@@ -171,7 +152,7 @@ net::URLRequestJob* ServiceWorkerContextRequestHandler::MaybeCreateJobImpl( ...@@ -171,7 +152,7 @@ net::URLRequestJob* ServiceWorkerContextRequestHandler::MaybeCreateJobImpl(
int resource_id = int resource_id =
version_->script_cache_map()->LookupResourceId(request->url()); version_->script_cache_map()->LookupResourceId(request->url());
if (resource_id != kInvalidServiceWorkerResourceId) { if (resource_id != kInvalidServiceWorkerResourceId) {
if (IsInstalled(version_.get())) { if (ServiceWorkerVersion::IsInstalled(version_->status())) {
// An installed worker is loading a stored script. // An installed worker is loading a stored script.
if (is_main_script) if (is_main_script)
version_->embedded_worker()->OnURLJobCreatedForMainScript(); version_->embedded_worker()->OnURLJobCreatedForMainScript();
...@@ -187,7 +168,7 @@ net::URLRequestJob* ServiceWorkerContextRequestHandler::MaybeCreateJobImpl( ...@@ -187,7 +168,7 @@ net::URLRequestJob* ServiceWorkerContextRequestHandler::MaybeCreateJobImpl(
} }
// An installed worker is importing a non-stored script. // An installed worker is importing a non-stored script.
if (IsInstalled(version_.get())) { if (ServiceWorkerVersion::IsInstalled(version_->status())) {
DCHECK(!is_main_script); DCHECK(!is_main_script);
*out_status = CreateJobStatus::ERROR_UNINSTALLED_SCRIPT_IMPORT; *out_status = CreateJobStatus::ERROR_UNINSTALLED_SCRIPT_IMPORT;
return nullptr; return nullptr;
......
...@@ -98,13 +98,51 @@ void RemoveProviderHost(base::WeakPtr<ServiceWorkerContextCore> context, ...@@ -98,13 +98,51 @@ void RemoveProviderHost(base::WeakPtr<ServiceWorkerContextCore> context,
context->RemoveProviderHost(process_id, provider_id); context->RemoveProviderHost(process_id, provider_id);
} }
// Used by a Service Worker for script loading (for all script loading for now, // Wraps associated request for another associated request.
// but to be used only during installation once script streaming lands). // TODO(kinuko): This should be able to go away once URLLoader becomes
// For now this is just a proxy loader for the network loader. // independent.
class AssociatedURLLoaderRelay final : public mojom::URLLoader {
public:
static void CreateLoaderAndStart(
mojom::URLLoaderFactory* factory,
mojom::URLLoaderAssociatedRequest request,
int routing_id,
int request_id,
uint32_t options,
const ResourceRequest& resource_request,
mojom::URLLoaderClientPtr client,
const net::MutableNetworkTrafficAnnotationTag& traffic_annotation) {
mojom::URLLoaderAssociatedPtr associated_ptr;
mojom::URLLoaderAssociatedRequest associated_request =
mojo::MakeRequest(&associated_ptr);
factory->CreateLoaderAndStart(std::move(associated_request), routing_id,
request_id, options, resource_request,
std::move(client), traffic_annotation);
mojo::MakeStrongAssociatedBinding(
base::MakeUnique<AssociatedURLLoaderRelay>(std::move(associated_ptr)),
std::move(request));
}
explicit AssociatedURLLoaderRelay(
mojom::URLLoaderAssociatedPtr associated_ptr)
: associated_ptr_(std::move(associated_ptr)) {}
~AssociatedURLLoaderRelay() override {}
void FollowRedirect() override { associated_ptr_->FollowRedirect(); }
void SetPriority(net::RequestPriority priority,
int intra_priority_value) override {
associated_ptr_->SetPriority(priority, intra_priority_value);
}
private:
mojom::URLLoaderAssociatedPtr associated_ptr_;
DISALLOW_COPY_AND_ASSIGN(AssociatedURLLoaderRelay);
};
// Used by a Service Worker for script loading only during the installation
// time. For now this is just a proxy loader for the network loader.
// Eventually this should replace the existing URLRequestJob-based request // Eventually this should replace the existing URLRequestJob-based request
// interception for script loading, namely ServiceWorkerWriteToCacheJob. // interception for script loading, namely ServiceWorkerWriteToCacheJob.
// TODO(kinuko): Implement this. Hook up the existing code in // TODO(kinuko): Implement this.
// ServiceWorkerContextRequestHandler.
class ScriptURLLoader : public mojom::URLLoader, public mojom::URLLoaderClient { class ScriptURLLoader : public mojom::URLLoader, public mojom::URLLoaderClient {
public: public:
ScriptURLLoader( ScriptURLLoader(
...@@ -224,6 +262,18 @@ class ScriptURLLoaderFactory : public mojom::URLLoaderFactory { ...@@ -224,6 +262,18 @@ class ScriptURLLoaderFactory : public mojom::URLLoaderFactory {
mojom::URLLoaderClientPtr client, mojom::URLLoaderClientPtr client,
const net::MutableNetworkTrafficAnnotationTag& const net::MutableNetworkTrafficAnnotationTag&
traffic_annotation) override { traffic_annotation) override {
if (!ShouldHandleScriptRequest(resource_request)) {
// If the request should not be handled by ScriptURLLoader, just
// fallback to the network. This needs a relaying as we use different
// associated message pipes.
// TODO(kinuko): Record the reason like what we do with netlog in
// ServiceWorkerContextRequestHandler.
AssociatedURLLoaderRelay::CreateLoaderAndStart(
loader_factory_getter_->GetNetworkFactory()->get(),
std::move(request), routing_id, request_id, options, resource_request,
std::move(client), traffic_annotation);
return;
}
mojo::MakeStrongAssociatedBinding( mojo::MakeStrongAssociatedBinding(
base::MakeUnique<ScriptURLLoader>( base::MakeUnique<ScriptURLLoader>(
routing_id, request_id, options, resource_request, routing_id, request_id, options, resource_request,
...@@ -240,6 +290,53 @@ class ScriptURLLoaderFactory : public mojom::URLLoaderFactory { ...@@ -240,6 +290,53 @@ class ScriptURLLoaderFactory : public mojom::URLLoaderFactory {
} }
private: private:
bool ShouldHandleScriptRequest(const ResourceRequest& resource_request) {
if (!context_ || !provider_host_)
return false;
// We only use the script cache for main script loading and
// importScripts(), even if a cached script is xhr'd, we don't
// retrieve it from the script cache.
if (resource_request.resource_type != RESOURCE_TYPE_SERVICE_WORKER &&
resource_request.resource_type != RESOURCE_TYPE_SCRIPT) {
// TODO: Record bad message, we shouldn't come here for other
// request types.
return false;
}
scoped_refptr<ServiceWorkerVersion> version =
provider_host_->running_hosted_version();
// This could happen if browser-side has set the status to redundant but
// the worker has not yet stopped. The worker is already doomed so just
// reject the request. Handle it specially here because otherwise it'd be
// unclear whether "REDUNDANT" should count as installed or not installed
// when making decisions about how to handle the request and logging UMA.
if (!version || version->status() == ServiceWorkerVersion::REDUNDANT)
return false;
// TODO: Make sure we don't handle the redirected request.
// For installed worker we fallback to the network for now.
if (ServiceWorkerVersion::IsInstalled(version->status())) {
DCHECK(ServiceWorkerUtils::IsScriptStreamingEnabled());
return false;
}
// TODO: Make sure we come here only for new / unknown scripts
// once script streaming manager in the renderer side stops sending
// resource requests for the known script URLs, i.e. add DCHECK for
// version->script_cache_map()->LookupResourceId(url) ==
// kInvalidServiceWorkerResourceId.
//
// Currently this could be false for the installing worker that imports
// the same script twice (e.g. importScripts('dupe.js');
// importScripts('dupe.js');).
// Request should be served by ScriptURLLoader.
return true;
}
base::WeakPtr<ServiceWorkerContextCore> context_; base::WeakPtr<ServiceWorkerContextCore> context_;
base::WeakPtr<ServiceWorkerProviderHost> provider_host_; base::WeakPtr<ServiceWorkerProviderHost> provider_host_;
base::WeakPtr<storage::BlobStorageContext> blob_storage_context_; base::WeakPtr<storage::BlobStorageContext> blob_storage_context_;
......
...@@ -136,21 +136,6 @@ void ClearTick(base::TimeTicks* time) { ...@@ -136,21 +136,6 @@ void ClearTick(base::TimeTicks* time) {
*time = base::TimeTicks(); *time = base::TimeTicks();
} }
bool IsInstalled(ServiceWorkerVersion::Status status) {
switch (status) {
case ServiceWorkerVersion::NEW:
case ServiceWorkerVersion::INSTALLING:
case ServiceWorkerVersion::REDUNDANT:
return false;
case ServiceWorkerVersion::INSTALLED:
case ServiceWorkerVersion::ACTIVATING:
case ServiceWorkerVersion::ACTIVATED:
return true;
}
NOTREACHED() << "Unexpected status: " << status;
return false;
}
std::string VersionStatusToString(ServiceWorkerVersion::Status status) { std::string VersionStatusToString(ServiceWorkerVersion::Status status) {
switch (status) { switch (status) {
case ServiceWorkerVersion::NEW: case ServiceWorkerVersion::NEW:
...@@ -1066,6 +1051,21 @@ void ServiceWorkerVersion::CountFeature(uint32_t feature) { ...@@ -1066,6 +1051,21 @@ void ServiceWorkerVersion::CountFeature(uint32_t feature) {
provider_host_by_uuid.second->CountFeature(feature); provider_host_by_uuid.second->CountFeature(feature);
} }
bool ServiceWorkerVersion::IsInstalled(ServiceWorkerVersion::Status status) {
switch (status) {
case ServiceWorkerVersion::NEW:
case ServiceWorkerVersion::INSTALLING:
case ServiceWorkerVersion::REDUNDANT:
return false;
case ServiceWorkerVersion::INSTALLED:
case ServiceWorkerVersion::ACTIVATING:
case ServiceWorkerVersion::ACTIVATED:
return true;
}
NOTREACHED() << "Unexpected status: " << status;
return false;
}
void ServiceWorkerVersion::OnOpenNewTab(int request_id, const GURL& url) { void ServiceWorkerVersion::OnOpenNewTab(int request_id, const GURL& url) {
OnOpenWindow(request_id, url, WindowOpenDisposition::NEW_FOREGROUND_TAB); OnOpenWindow(request_id, url, WindowOpenDisposition::NEW_FOREGROUND_TAB);
} }
......
...@@ -406,6 +406,8 @@ class CONTENT_EXPORT ServiceWorkerVersion ...@@ -406,6 +406,8 @@ class CONTENT_EXPORT ServiceWorkerVersion
} }
const std::set<uint32_t>& used_features() const { return used_features_; } const std::set<uint32_t>& used_features() const { return used_features_; }
static bool IsInstalled(ServiceWorkerVersion::Status status);
private: private:
friend class base::RefCounted<ServiceWorkerVersion>; friend class base::RefCounted<ServiceWorkerVersion>;
friend class ServiceWorkerReadFromCacheJobTest; friend class ServiceWorkerReadFromCacheJobTest;
......
...@@ -76,6 +76,8 @@ ...@@ -76,6 +76,8 @@
#include "third_party/WebKit/public/web/modules/serviceworker/WebServiceWorkerContextClient.h" #include "third_party/WebKit/public/web/modules/serviceworker/WebServiceWorkerContextClient.h"
#include "third_party/WebKit/public/web/modules/serviceworker/WebServiceWorkerContextProxy.h" #include "third_party/WebKit/public/web/modules/serviceworker/WebServiceWorkerContextProxy.h"
using blink::WebURLRequest;
namespace content { namespace content {
namespace { namespace {
...@@ -94,7 +96,7 @@ class WebServiceWorkerNetworkProviderImpl ...@@ -94,7 +96,7 @@ class WebServiceWorkerNetworkProviderImpl
// Blink calls this method for each request starting with the main script, // Blink calls this method for each request starting with the main script,
// we tag them with the provider id. // we tag them with the provider id.
void WillSendRequest(blink::WebURLRequest& request) override { void WillSendRequest(WebURLRequest& request) override {
std::unique_ptr<RequestExtraData> extra_data(new RequestExtraData); std::unique_ptr<RequestExtraData> extra_data(new RequestExtraData);
extra_data->set_service_worker_provider_id(provider_->provider_id()); extra_data->set_service_worker_provider_id(provider_->provider_id());
extra_data->set_originated_from_service_worker(true); extra_data->set_originated_from_service_worker(true);
...@@ -109,7 +111,8 @@ class WebServiceWorkerNetworkProviderImpl ...@@ -109,7 +111,8 @@ class WebServiceWorkerNetworkProviderImpl
base::SingleThreadTaskRunner* task_runner) override { base::SingleThreadTaskRunner* task_runner) override {
RenderThreadImpl* child_thread = RenderThreadImpl::current(); RenderThreadImpl* child_thread = RenderThreadImpl::current();
if (child_thread && provider_->script_loader_factory() && if (child_thread && provider_->script_loader_factory() &&
ServiceWorkerUtils::IsServicificationEnabled()) { ServiceWorkerUtils::IsServicificationEnabled() &&
IsScriptRequest(request)) {
return base::MakeUnique<WebURLLoaderImpl>( return base::MakeUnique<WebURLLoaderImpl>(
child_thread->resource_dispatcher(), task_runner, child_thread->resource_dispatcher(), task_runner,
provider_->script_loader_factory()); provider_->script_loader_factory());
...@@ -120,6 +123,13 @@ class WebServiceWorkerNetworkProviderImpl ...@@ -120,6 +123,13 @@ class WebServiceWorkerNetworkProviderImpl
int GetProviderID() const override { return provider_->provider_id(); } int GetProviderID() const override { return provider_->provider_id(); }
private: private:
static bool IsScriptRequest(const WebURLRequest& request) {
auto request_context = request.GetRequestContext();
return request_context == WebURLRequest::kRequestContextServiceWorker ||
request_context == WebURLRequest::kRequestContextScript ||
request_context == WebURLRequest::kRequestContextImport;
}
std::unique_ptr<ServiceWorkerNetworkProvider> provider_; std::unique_ptr<ServiceWorkerNetworkProvider> provider_;
}; };
...@@ -151,31 +161,28 @@ ServiceWorkerStatusCode EventResultToStatus( ...@@ -151,31 +161,28 @@ ServiceWorkerStatusCode EventResultToStatus(
return SERVICE_WORKER_ERROR_FAILED; return SERVICE_WORKER_ERROR_FAILED;
} }
blink::WebURLRequest::FetchRequestMode GetBlinkFetchRequestMode( WebURLRequest::FetchRequestMode GetBlinkFetchRequestMode(
FetchRequestMode mode) { FetchRequestMode mode) {
return static_cast<blink::WebURLRequest::FetchRequestMode>(mode); return static_cast<WebURLRequest::FetchRequestMode>(mode);
} }
blink::WebURLRequest::FetchCredentialsMode GetBlinkFetchCredentialsMode( WebURLRequest::FetchCredentialsMode GetBlinkFetchCredentialsMode(
FetchCredentialsMode credentials_mode) { FetchCredentialsMode credentials_mode) {
return static_cast<blink::WebURLRequest::FetchCredentialsMode>( return static_cast<WebURLRequest::FetchCredentialsMode>(credentials_mode);
credentials_mode);
} }
blink::WebURLRequest::FetchRedirectMode GetBlinkFetchRedirectMode( WebURLRequest::FetchRedirectMode GetBlinkFetchRedirectMode(
FetchRedirectMode redirect_mode) { FetchRedirectMode redirect_mode) {
return static_cast<blink::WebURLRequest::FetchRedirectMode>(redirect_mode); return static_cast<WebURLRequest::FetchRedirectMode>(redirect_mode);
} }
blink::WebURLRequest::RequestContext GetBlinkRequestContext( WebURLRequest::RequestContext GetBlinkRequestContext(
RequestContextType request_context_type) { RequestContextType request_context_type) {
return static_cast<blink::WebURLRequest::RequestContext>( return static_cast<WebURLRequest::RequestContext>(request_context_type);
request_context_type);
} }
blink::WebURLRequest::FrameType GetBlinkFrameType( WebURLRequest::FrameType GetBlinkFrameType(RequestContextFrameType frame_type) {
RequestContextFrameType frame_type) { return static_cast<WebURLRequest::FrameType>(frame_type);
return static_cast<blink::WebURLRequest::FrameType>(frame_type);
} }
blink::WebServiceWorkerClientInfo blink::WebServiceWorkerClientInfo
......
...@@ -39,13 +39,6 @@ ...@@ -39,13 +39,6 @@
# http://crbug.com/721398 # http://crbug.com/721398
-ClearSiteDataThrottleBrowserTest.* -ClearSiteDataThrottleBrowserTest.*
# http://crbug.com/736362
-ServiceWorkerVersionBrowserTest.Activate_Rejected
-ServiceWorkerVersionBrowserTest.FetchEvent_Response
-ServiceWorkerVersionBrowserTest.Activate_NoEventListener
-ServiceWorkerVersionBrowserTest.FetchEvent_ResponseViaCache
-ServiceWorkerVersionBrowserTest.FetchEvent_respondWithRejection
-AsyncResourceHandlerBrowserTest/AsyncResourceHandlerBrowserTest.UploadProgress* -AsyncResourceHandlerBrowserTest/AsyncResourceHandlerBrowserTest.UploadProgress*
-BrowserSideNavigationBrowserTest.FailedNavigation -BrowserSideNavigationBrowserTest.FailedNavigation
-CrossSiteResourceHandlerTest.NoDeliveryToDetachedFrame -CrossSiteResourceHandlerTest.NoDeliveryToDetachedFrame
......
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