Commit 9e4b946a authored by Makoto Shimazu's avatar Makoto Shimazu Committed by Commit Bot

COEP takes effect on a new service worker except for importScripts

Currently Cross-Origin-Embedder-Policy header is parsed in
ServiceWorkerNewScriptLoader when launching a new service worker.
However, the COEP in the response header for the main script isn't
applied for the network loader created on launching a service worker
because the network loader is created before starting to load the main
script.
This CL is to pause the service worker's script evaluation until the
main script is loaded. Once the main script loaded, new subresource
loaders are created by using the COEP value, and they are sent to the
service worker.
Imported scripts also need to refer to the new value, but the loaders
are in different place (ServiceWorkerScriptLoaderFactory), so it'll be
addressed in a later patch.

Bug: 1039613
Change-Id: Ice82eef86beec2f2f5c5e91f3aa136229f14c3ab
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2029403
Commit-Queue: Makoto Shimazu <shimazu@chromium.org>
Reviewed-by: default avatarKent Tamura <tkent@chromium.org>
Reviewed-by: default avatarKinuko Yasuda <kinuko@chromium.org>
Reviewed-by: default avatarKenichi Ishibashi <bashi@chromium.org>
Auto-Submit: Makoto Shimazu <shimazu@chromium.org>
Cr-Commit-Position: refs/heads/master@{#748112}
parent 1c32915d
......@@ -41,7 +41,9 @@ void FakeServiceWorker::InitializeGlobalScope(
service_worker_host,
blink::mojom::ServiceWorkerRegistrationObjectInfoPtr registration_info,
blink::mojom::ServiceWorkerObjectInfoPtr service_worker_info,
blink::mojom::FetchHandlerExistence fetch_handler_existence) {
blink::mojom::FetchHandlerExistence fetch_handler_existence,
std::unique_ptr<blink::PendingURLLoaderFactoryBundle>
subresource_loader_factories) {
host_.Bind(std::move(service_worker_host));
// Enable callers to use these endpoints without us actually binding them
......
......@@ -57,7 +57,9 @@ class FakeServiceWorker : public blink::mojom::ServiceWorker {
service_worker_host,
blink::mojom::ServiceWorkerRegistrationObjectInfoPtr registration_info,
blink::mojom::ServiceWorkerObjectInfoPtr service_worker_info,
FetchHandlerExistence fetch_handler_existence) override;
FetchHandlerExistence fetch_handler_existence,
std::unique_ptr<blink::PendingURLLoaderFactoryBundle>
subresource_loader_factories) override;
void DispatchInstallEvent(DispatchInstallEventCallback callback) override;
void DispatchActivateEvent(DispatchActivateEventCallback callback) override;
void DispatchBackgroundFetchAbortEvent(
......
......@@ -1277,7 +1277,8 @@ class UpdateJobTestHelper : public EmbeddedWorkerTestHelper,
mojo::PendingAssociatedRemote<blink::mojom::ServiceWorkerHost>,
blink::mojom::ServiceWorkerRegistrationObjectInfoPtr,
blink::mojom::ServiceWorkerObjectInfoPtr,
blink::mojom::FetchHandlerExistence) override {
blink::mojom::FetchHandlerExistence,
std::unique_ptr<blink::PendingURLLoaderFactoryBundle>) override {
client_->SimulateFailureOfScriptEvaluation();
}
......
......@@ -500,6 +500,13 @@ void ServiceWorkerRegisterJob::StartWorkerForUpdate(
update_checker_.reset();
}
if (!registration()->GetNewestVersion()) {
// Subresource loader factories needs to be updated after the main script is
// loaded. This flag lets the script evaluation wait until the browser sends
// a message with a new subresoruce loader factories.
new_version()->set_initialize_global_scope_after_main_script_loaded();
}
new_version()->set_outside_fetch_client_settings_object(
std::move(outside_fetch_client_settings_object_));
......
......@@ -23,6 +23,7 @@
#include "base/stl_util.h"
#include "base/strings/string16.h"
#include "base/strings/utf_string_conversions.h"
#include "base/task/post_task.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/time/default_clock.h"
#include "base/time/default_tick_clock.h"
......@@ -204,6 +205,29 @@ base::TimeDelta GetUpdateDelay() {
return base::TimeDelta::FromMilliseconds(kUpdateDelayParam.Get());
}
void CreateFactoryBundleForSubresourceOnUI(
int process_id,
int routing_id,
const url::Origin& origin,
network::CrossOriginEmbedderPolicy cross_origin_embedder_policy,
base::OnceCallback<
void(std::unique_ptr<blink::PendingURLLoaderFactoryBundle>)> callback) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
auto* rph = RenderProcessHost::FromID(process_id);
if (!rph) {
// Return nullptr because we can't create a factory bundle because of
// missing renderer.
ServiceWorkerContextWrapper::RunOrPostTaskOnCoreThread(
FROM_HERE, base::BindOnce(std::move(callback), nullptr));
return;
}
auto bundle = EmbeddedWorkerInstance::CreateFactoryBundleOnUI(
rph, routing_id, origin, cross_origin_embedder_policy,
ContentBrowserClient::URLLoaderFactoryType::kServiceWorkerSubResource);
ServiceWorkerContextWrapper::RunOrPostTaskOnCoreThread(
FROM_HERE, base::BindOnce(std::move(callback), std::move(bundle)));
}
} // namespace
constexpr base::TimeDelta ServiceWorkerVersion::kTimeoutTimerDelay;
......@@ -953,17 +977,56 @@ void ServiceWorkerVersion::Doom() {
}
void ServiceWorkerVersion::OnMainScriptLoaded() {
// If this startup isn't paused the service worker after the script load,
// there is nothing to do. We already called InitializeGlobalScope() in
// StartWorkerInternal().
if (!pause_after_download_)
if (!initialize_global_scope_after_main_script_loaded_)
return;
// If the script load was successful, unpause the worker by calling
// InitializeGlobalScope(). Otherwise, keep it paused and the original
// caller of StartWorker() is expected to terminate the worker.
initialize_global_scope_after_main_script_loaded_ = false;
int net_error = script_cache_map()->main_script_net_error();
if (net_error == net::OK)
InitializeGlobalScope();
if (net_error != net::OK)
return;
// The subresource loaders need to be updated. Get the factories with the
// correct COEP value and pass it to the service worker.
//
// TODO(https://crbug.com/1039613): Update the loader factories passed to the
// script loader factory too.
DCHECK_EQ(NEW, status());
RunOrPostTaskOnThread(
FROM_HERE, BrowserThread::UI,
base::BindOnce(
&CreateFactoryBundleForSubresourceOnUI,
embedded_worker()->process_id(),
embedded_worker()->worker_devtools_agent_route_id(), script_origin(),
cross_origin_embedder_policy(),
base::BindOnce(&ServiceWorkerVersion::InitializeGlobalScope,
weak_factory_.GetWeakPtr())));
}
void ServiceWorkerVersion::InitializeGlobalScope(
std::unique_ptr<blink::PendingURLLoaderFactoryBundle>
subresource_loader_factories) {
DCHECK(service_worker_host_);
scoped_refptr<ServiceWorkerRegistration> registration =
base::WrapRefCounted(context_->GetLiveRegistration(registration_id_));
// The registration must exist since we keep a reference to it during
// service worker startup.
DCHECK(registration);
if (subresource_loader_factories) {
// |subresource_loader_factories| is valid only when the service worker is
// a new worker.
DCHECK_EQ(nullptr, registration->GetNewestVersion());
DCHECK_EQ(NEW, status());
}
DCHECK(provider_host_);
service_worker_remote_->InitializeGlobalScope(
std::move(service_worker_host_),
provider_host_->container_host()
->CreateServiceWorkerRegistrationObjectInfo(std::move(registration)),
provider_host_->container_host()->CreateServiceWorkerObjectInfoToSend(
this),
fetch_handler_existence_, std::move(subresource_loader_factories));
}
void ServiceWorkerVersion::SetValidOriginTrialTokens(
......@@ -1787,8 +1850,8 @@ void ServiceWorkerVersion::StartWorkerInternal() {
receiver_.Bind(service_worker_host_.InitWithNewEndpointAndPassReceiver());
// Initialize the global scope now if the worker won't be paused. Otherwise,
// delay initialization until the main script is loaded.
if (!pause_after_download())
InitializeGlobalScope();
if (!initialize_global_scope_after_main_script_loaded_)
InitializeGlobalScope(/*subresource_loader_factories=*/nullptr);
if (!controller_receiver_.is_valid()) {
controller_receiver_ = remote_controller_.BindNewPipeAndPassReceiver();
......@@ -2317,24 +2380,6 @@ void ServiceWorkerVersion::MaybeReportConsoleMessageToInternals(
script_url_);
}
void ServiceWorkerVersion::InitializeGlobalScope() {
DCHECK(service_worker_host_);
scoped_refptr<ServiceWorkerRegistration> registration =
base::WrapRefCounted(context_->GetLiveRegistration(registration_id_));
// The registration must exist since we keep a reference to it during
// service worker startup.
DCHECK(registration);
DCHECK(provider_host_);
service_worker_remote_->InitializeGlobalScope(
std::move(service_worker_host_),
provider_host_->container_host()
->CreateServiceWorkerRegistrationObjectInfo(std::move(registration)),
provider_host_->container_host()->CreateServiceWorkerObjectInfoToSend(
this),
fetch_handler_existence_);
}
void ServiceWorkerVersion::UpdateIdleDelayIfNeeded(base::TimeDelta delay) {
// The idle delay can be updated only when the worker is still running.
bool update_idle_delay = running_status() == EmbeddedWorkerStatus::STARTING ||
......
......@@ -39,6 +39,8 @@
#include "content/browser/service_worker/service_worker_script_cache_map.h"
#include "content/browser/service_worker/service_worker_update_checker.h"
#include "content/common/content_export.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "ipc/ipc_message.h"
#include "mojo/public/cpp/bindings/associated_receiver.h"
#include "mojo/public/cpp/bindings/pending_associated_remote.h"
......@@ -56,6 +58,10 @@
#include "url/gurl.h"
#include "url/origin.h"
namespace blink {
class PendingURLLoaderFactoryBundle;
}
namespace net {
class HttpResponseInfo;
}
......@@ -440,7 +446,10 @@ class CONTENT_EXPORT ServiceWorkerVersion
force_bypass_cache_for_scripts_ = force_bypass_cache_for_scripts;
}
bool pause_after_download() const { return pause_after_download_; }
void set_initialize_global_scope_after_main_script_loaded() {
DCHECK(!initialize_global_scope_after_main_script_loaded_);
initialize_global_scope_after_main_script_loaded_ = true;
}
void set_outside_fetch_client_settings_object(
blink::mojom::FetchClientSettingsObjectPtr
......@@ -863,7 +872,9 @@ class CONTENT_EXPORT ServiceWorkerVersion
GetClientCallback callback,
bool success);
void InitializeGlobalScope();
void InitializeGlobalScope(
std::unique_ptr<blink::PendingURLLoaderFactoryBundle>
subresource_loader_factories);
// Update the idle delay if the worker is starting or running and we don't
// have to terminate the worker ASAP (e.g. for activation).
......@@ -998,11 +1009,8 @@ class CONTENT_EXPORT ServiceWorkerVersion
// When true, script evaluation doesn't start until InitializeGlobalScope() is
// called. This allows the browser process to prevent the renderer from
// evaluating the script immediately after the script has been loaded, until
// certain checks are satisfied.
// TODO(https://crbug.com/1039613): Use this to get proper COEP value and
// re-create URLLoaderFactories for the service workers before evaluating the
// script.
bool pause_after_download_ = false;
// the subresource loader factories are updated.
bool initialize_global_scope_after_main_script_loaded_ = false;
std::unique_ptr<net::HttpResponseInfo> main_script_http_info_;
......
......@@ -366,7 +366,7 @@ void ServiceWorkerContextClient::ReportConsoleMessage(
blink::WebStringToGURL(source_url));
}
scoped_refptr<blink::WebWorkerFetchContext>
scoped_refptr<blink::WebServiceWorkerFetchContext>
ServiceWorkerContextClient::CreateWorkerFetchContextOnInitiatorThread() {
DCHECK(initiator_thread_task_runner_->RunsTasksInCurrentSequence());
DCHECK(preference_watcher_receiver_.is_valid());
......
......@@ -57,7 +57,7 @@ namespace content {
class ChildURLLoaderFactoryBundle;
class EmbeddedWorkerInstanceClientImpl;
class WebWorkerFetchContext;
class WebServiceWorkerFetchContext;
// ServiceWorkerContextClient is a "client" of a service worker execution
// context. It enables communication between the embedder and Blink's
......@@ -122,6 +122,7 @@ class CONTENT_EXPORT ServiceWorkerContextClient
mojo::ScopedMessagePipeHandle content_settings_handle,
mojo::ScopedMessagePipeHandle cache_storage,
mojo::ScopedMessagePipeHandle browser_interface_broker);
// Called on the initiator thread.
blink::WebEmbeddedWorker& worker();
......@@ -155,7 +156,7 @@ class CONTENT_EXPORT ServiceWorkerContextClient
std::unique_ptr<blink::WebFetchEventPreloadHandle>
preload_handle) override;
void RequestTermination(RequestTerminationCallback callback) override;
scoped_refptr<blink::WebWorkerFetchContext>
scoped_refptr<blink::WebServiceWorkerFetchContext>
CreateWorkerFetchContextOnInitiatorThread() override;
/////////////////////////////////////////////////////////////////////////////
......
......@@ -176,6 +176,11 @@ ServiceWorkerFetchContextImpl::CreateWebSocketHandshakeThrottle(
MSG_ROUTING_NONE, std::move(task_runner));
}
blink::mojom::SubresourceLoaderUpdater*
ServiceWorkerFetchContextImpl::GetSubresourceLoaderUpdater() {
return this;
}
void ServiceWorkerFetchContextImpl::UpdateSubresourceLoaderFactories(
std::unique_ptr<blink::PendingURLLoaderFactoryBundle>
subresource_loader_factories) {
......
......@@ -13,7 +13,7 @@
#include "third_party/blink/public/mojom/renderer_preferences.mojom.h"
#include "third_party/blink/public/mojom/service_worker/service_worker.mojom-forward.h"
#include "third_party/blink/public/mojom/worker/subresource_loader_updater.mojom.h"
#include "third_party/blink/public/platform/web_worker_fetch_context.h"
#include "third_party/blink/public/platform/modules/service_worker/web_service_worker_fetch_context.h"
#include "url/gurl.h"
namespace content {
......@@ -23,9 +23,9 @@ class URLLoaderThrottleProvider;
class WebSocketHandshakeThrottleProvider;
class CONTENT_EXPORT ServiceWorkerFetchContextImpl final
: public blink::WebWorkerFetchContext,
public blink::mojom::SubresourceLoaderUpdater,
public blink::mojom::RendererPreferenceWatcher {
: public blink::WebServiceWorkerFetchContext,
public blink::mojom::RendererPreferenceWatcher,
public blink::mojom::SubresourceLoaderUpdater {
public:
// |pending_url_loader_factory| is used for regular loads from the service
// worker (i.e., Fetch API). It typically goes to network, but it might
......@@ -54,7 +54,7 @@ class CONTENT_EXPORT ServiceWorkerFetchContextImpl final
pending_subresource_loader_updater,
int32_t service_worker_route_id);
// blink::WebWorkerFetchContext implementation:
// blink::WebServiceWorkerFetchContext implementation:
void SetTerminateSyncLoadEvent(base::WaitableEvent*) override;
void InitializeOnWorkerThread(blink::AcceptLanguagesWatcher*) override;
blink::WebURLLoaderFactory* GetURLLoaderFactory() override;
......@@ -66,7 +66,6 @@ class CONTENT_EXPORT ServiceWorkerFetchContextImpl final
const override;
net::SiteForCookies SiteForCookies() const override;
base::Optional<blink::WebSecurityOrigin> TopFrameOrigin() const override;
std::unique_ptr<blink::WebSocketHandshakeThrottle>
CreateWebSocketHandshakeThrottle(
scoped_refptr<base::SingleThreadTaskRunner> task_runner) override;
......@@ -74,15 +73,17 @@ class CONTENT_EXPORT ServiceWorkerFetchContextImpl final
mojo::ScopedMessagePipeHandle TakePendingWorkerTimingReceiver(
int request_id) override;
void SetIsOfflineMode(bool) override;
blink::mojom::SubresourceLoaderUpdater* GetSubresourceLoaderUpdater()
override;
private:
~ServiceWorkerFetchContextImpl() override;
// Implements blink::mojom::ServiceWorkerFetchContext
// blink::mojom::SubresourceLoaderUpdater implementation:
void UpdateSubresourceLoaderFactories(
std::unique_ptr<blink::PendingURLLoaderFactoryBundle>
subresource_loader_factories) override;
private:
~ServiceWorkerFetchContextImpl() override;
// Implements blink::mojom::RendererPreferenceWatcher.
void NotifyUpdate(blink::mojom::RendererPreferencesPtr new_prefs) override;
......
......@@ -56,7 +56,12 @@ def _CheckForWrongMojomIncludes(input_api, output_api):
# - Its pros/cons is discussed and have consensus on platform-architecture-dev@ and/or
# - It uses POD types that will not import STL (or base string) types into blink
# (such as no strings or vectors).
allowed_interfaces = (r'services/network/public/mojom/load_timing_info.mojom')
#
# So far, non-blink interfaces are allowed only for loading / loader
# interfaces so that we don't need type conversions to get through the
# boundary between Blink and non-Blink.
allowed_interfaces = (r'services/network/public/mojom/load_timing_info',
r'third_party/blink/public/mojom/worker/subresource_loader_updater')
for f in input_api.AffectedFiles(file_filter=source_file_filter):
for line_num, line in f.ChangedContents():
......
......@@ -132,6 +132,7 @@ source_set("blink_headers") {
"platform/modules/mediastream/web_platform_media_stream_track.h",
"platform/modules/remoteplayback/web_remote_playback_client.h",
"platform/modules/service_worker/web_service_worker_error.h",
"platform/modules/service_worker/web_service_worker_fetch_context.h",
"platform/modules/service_worker/web_service_worker_network_provider.h",
"platform/modules/service_worker/web_service_worker_object_info.h",
"platform/modules/service_worker/web_service_worker_provider.h",
......
......@@ -6,6 +6,9 @@ mojom =
"//third_party/blink/public/mojom/loader/url_loader_factory_bundle.mojom"
public_headers =
[ "//third_party/blink/public/common/loader/url_loader_factory_bundle.h" ]
traits_headers = [ "//third_party/blink/public/common/loader/url_loader_factory_bundle_mojom_traits.h" ]
traits_headers = [
"//third_party/blink/public/common/loader/url_loader_factory_bundle_mojom_traits.h",
"//url/mojom/origin_mojom_traits.h",
]
type_mappings = [ "blink.mojom.URLLoaderFactoryBundle=::std::unique_ptr<::blink::PendingURLLoaderFactoryBundle>[move_only,nullable_is_same_type]" ]
......@@ -12,6 +12,7 @@ import "services/network/public/mojom/url_loader_factory.mojom";
import "third_party/blink/public/mojom/background_fetch/background_fetch.mojom";
import "third_party/blink/public/mojom/devtools/console_message.mojom";
import "third_party/blink/public/mojom/fetch/fetch_api_response.mojom";
import "third_party/blink/public/mojom/loader/url_loader_factory_bundle.mojom";
import "third_party/blink/public/mojom/messaging/transferable_message.mojom";
import "third_party/blink/public/mojom/notifications/notification.mojom";
import "third_party/blink/public/mojom/payments/payment_app.mojom";
......@@ -176,11 +177,15 @@ interface ServiceWorker {
// ServiceWorkerGlobalScope#registration object and
// ServiceWorkerGlobalScope#serviceWorker object. JavaScript execution of the
// service worker does not start until this message is received.
// When the service worker is new and going to be registered,
// |subresource_loader_factories| is non-null and it should be used for all
// subsequent requests.
InitializeGlobalScope(
pending_associated_remote<ServiceWorkerHost> service_worker_host,
ServiceWorkerRegistrationObjectInfo registration_info,
ServiceWorkerObjectInfo service_worker_info,
FetchHandlerExistence fetch_handler_existence);
FetchHandlerExistence fetch_handler_existence,
URLLoaderFactoryBundle? subresource_loader_factories);
DispatchInstallEvent()
=> (ServiceWorkerEventStatus status, bool has_fetch_handler);
......
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef THIRD_PARTY_BLINK_PUBLIC_PLATFORM_MODULES_SERVICE_WORKER_WEB_SERVICE_WORKER_FETCH_CONTEXT_H_
#define THIRD_PARTY_BLINK_PUBLIC_PLATFORM_MODULES_SERVICE_WORKER_WEB_SERVICE_WORKER_FETCH_CONTEXT_H_
#include "third_party/blink/public/platform/web_worker_fetch_context.h"
namespace blink {
namespace mojom {
class SubresourceLoaderUpdater;
} // namespace mojom
// Worker fetch context for service worker. This has a feature to update the
// subresource loader factories through the subresouruce loader updater in
// addition to WebWorkerFetchContext.
class WebServiceWorkerFetchContext : public WebWorkerFetchContext {
public:
virtual mojom::SubresourceLoaderUpdater* GetSubresourceLoaderUpdater() = 0;
};
} // namespace blink
#endif // THIRD_PARTY_BLINK_PUBLIC_PLATFORM_MODULES_SERVICE_WORKER_WEB_SERVICE_WORKER_FETCH_CONTEXT_H_
......@@ -39,8 +39,8 @@
#include "third_party/blink/public/mojom/devtools/console_message.mojom-shared.h"
#include "third_party/blink/public/mojom/service_worker/service_worker_event_status.mojom-shared.h"
#include "third_party/blink/public/mojom/web_feature/web_feature.mojom-shared.h"
#include "third_party/blink/public/platform/modules/service_worker/web_service_worker_fetch_context.h"
#include "third_party/blink/public/platform/web_url.h"
#include "third_party/blink/public/platform/web_worker_fetch_context.h"
#include "v8/include/v8.h"
namespace base {
......@@ -173,7 +173,7 @@ class WebServiceWorkerContextClient {
// Off-main-thread start up:
// Creates a WebWorkerFetchContext for subresource fetches on a service
// worker. This is called on the initiator thread.
virtual scoped_refptr<blink::WebWorkerFetchContext>
virtual scoped_refptr<blink::WebServiceWorkerFetchContext>
CreateWorkerFetchContextOnInitiatorThread() = 0;
};
......
......@@ -180,6 +180,10 @@ class CORE_EXPORT WorkerOrWorkletGlobalScope : public EventTargetWithInlineData,
web_worker_fetch_context_->SetIsOfflineMode(is_offline_mode);
}
WebWorkerFetchContext* web_worker_fetch_context() const {
return web_worker_fetch_context_.get();
}
private:
void InitializeWebFetchContextIfNeeded();
ResourceFetcher* CreateFetcherInternal(const FetchClientSettingsObject&,
......
......@@ -43,7 +43,9 @@
#include "third_party/blink/public/common/features.h"
#include "third_party/blink/public/mojom/appcache/appcache.mojom-blink.h"
#include "third_party/blink/public/mojom/timing/worker_timing_container.mojom-blink.h"
#include "third_party/blink/public/mojom/worker/subresource_loader_updater.mojom.h"
#include "third_party/blink/public/platform/modules/service_worker/web_service_worker_error.h"
#include "third_party/blink/public/platform/modules/service_worker/web_service_worker_fetch_context.h"
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/public/platform/web_url.h"
#include "third_party/blink/renderer/bindings/core/v8/callback_promise_adapter.h"
......@@ -1525,7 +1527,9 @@ void ServiceWorkerGlobalScope::InitializeGlobalScope(
service_worker_host,
mojom::blink::ServiceWorkerRegistrationObjectInfoPtr registration_info,
mojom::blink::ServiceWorkerObjectInfoPtr service_worker_info,
mojom::blink::FetchHandlerExistence fetch_hander_existence) {
mojom::blink::FetchHandlerExistence fetch_hander_existence,
std::unique_ptr<PendingURLLoaderFactoryBundle>
subresource_loader_factories) {
DCHECK(IsContextThread());
DCHECK(!global_scope_initialized_);
......@@ -1534,6 +1538,13 @@ void ServiceWorkerGlobalScope::InitializeGlobalScope(
service_worker_host_.Bind(std::move(service_worker_host),
GetTaskRunner(TaskType::kInternalDefault));
if (subresource_loader_factories) {
static_cast<WebServiceWorkerFetchContext*>(web_worker_fetch_context())
->GetSubresourceLoaderUpdater()
->UpdateSubresourceLoaderFactories(
std::move(subresource_loader_factories));
}
// Set ServiceWorkerGlobalScope#registration.
DCHECK_NE(registration_info->registration_id,
mojom::blink::kInvalidServiceWorkerRegistrationId);
......
......@@ -60,6 +60,7 @@ namespace blink {
class ExceptionState;
class FetchEvent;
class PendingURLLoaderFactoryBundle;
class RespondWithObserver;
class RequestInit;
class ScriptPromise;
......@@ -389,7 +390,9 @@ class MODULES_EXPORT ServiceWorkerGlobalScope final
service_worker_host,
mojom::blink::ServiceWorkerRegistrationObjectInfoPtr registration_info,
mojom::blink::ServiceWorkerObjectInfoPtr service_worker_info,
mojom::blink::FetchHandlerExistence fetch_hander_existence) override;
mojom::blink::FetchHandlerExistence fetch_handler_existence,
std::unique_ptr<PendingURLLoaderFactoryBundle>
subresource_loader_factories) override;
void DispatchInstallEvent(DispatchInstallEventCallback callback) override;
void DispatchActivateEvent(DispatchActivateEventCallback callback) override;
void DispatchBackgroundFetchAbortEvent(
......
......@@ -100,9 +100,10 @@ class FakeWebURLLoaderFactory final : public WebURLLoaderFactory {
}
};
// A fake WebWorkerFetchContext which is used for off-main-thread script fetch
// tests.
class FakeWebWorkerFetchContext final : public WebWorkerFetchContext {
// A fake WebServiceWorkerFetchContext which is used for off-main-thread script
// fetch tests.
class FakeWebServiceWorkerFetchContext final
: public WebServiceWorkerFetchContext {
public:
void SetTerminateSyncLoadEvent(base::WaitableEvent*) override {}
void InitializeOnWorkerThread(AcceptLanguagesWatcher*) override {}
......@@ -130,6 +131,9 @@ class FakeWebWorkerFetchContext final : public WebWorkerFetchContext {
return {};
}
void SetIsOfflineMode(bool is_offline_mode) override {}
mojom::SubresourceLoaderUpdater* GetSubresourceLoaderUpdater() override {
return nullptr;
}
private:
FakeWebURLLoaderFactory fake_web_url_loader_factory_;
......@@ -183,7 +187,8 @@ class MockServiceWorkerContextClient final
mojom::blink::ServiceWorkerState::kParsed,
KURL("https://example.com"), std::move(service_worker_object_host),
service_worker_object.InitWithNewEndpointAndPassReceiver()),
mojom::blink::FetchHandlerExistence::EXISTS);
mojom::blink::FetchHandlerExistence::EXISTS,
/*subresource_loader_factories=*/nullptr);
// To make the other side callable.
mojo::AssociateWithDisconnectedPipe(host_receiver.PassHandle());
......@@ -201,9 +206,9 @@ class MockServiceWorkerContextClient final
script_evaluated_event_.Signal();
}
scoped_refptr<WebWorkerFetchContext>
scoped_refptr<WebServiceWorkerFetchContext>
CreateWorkerFetchContextOnInitiatorThread() override {
return base::MakeRefCounted<FakeWebWorkerFetchContext>();
return base::MakeRefCounted<FakeWebServiceWorkerFetchContext>();
}
void WorkerContextDestroyed() override { termination_event_.Signal(); }
......
......@@ -14,6 +14,7 @@ typemaps = [
"//services/network/public/cpp/p2p.typemap",
"//third_party/blink/common/feature_policy/feature_policy.typemap",
"//third_party/blink/common/frame/frame_policy.typemap",
"//third_party/blink/public/common/loader/url_loader_factory_bundle.typemap",
"//third_party/blink/public/common/messaging/message_port_descriptor.typemap",
"//third_party/blink/renderer/core/messaging/blink_cloneable_message.typemap",
"//third_party/blink/renderer/core/messaging/blink_transferable_message.typemap",
......
This is a testharness.js-based test.
PASS Set up global state
PASS fetch() to 'CORP: cross-origin' response should succeed.
FAIL fetch() to no CORP response should not succeed. assert_equals: expected "TypeError: Failed to fetch" but got "opaque"
PASS fetch() to no CORP response should not succeed.
FAIL importScripts() fails for a script with no corp. assert_unreached: Should have rejected: register() should fail. Reached unreachable code
PASS importScripts() succeeds for a script with corp: cross-origin.
PASS Clean up global state
Harness: the test ran to completion.
......@@ -34,4 +34,20 @@ promise_test(async t => {
worker.postMessage('WithoutCorp');
assert_equals((await p).data, 'TypeError: Failed to fetch');
}, "fetch() to no CORP response should not succeed.");
promise_test(async t => {
const scope = `${SCOPE}-2`;
await service_worker_unregister(t, scope);
const promise = navigator.serviceWorker.register(
'resources/require-corp-sw-import-scripts.js', {scope});
await promise_rejects_js(t, TypeError, promise, 'register() should fail.');
}, 'importScripts() fails for a script with no corp.');
promise_test(async t => {
const scope = `${SCOPE}-3`;
await service_worker_unregister(t, scope);
const registration = await navigator.serviceWorker.register(
'resources/require-corp-sw-import-scripts.js?corp=cross-origin', {scope});
t.add_cleanup(() => registration.unregister());
}, 'importScripts() succeeds for a script with corp: cross-origin.');
</script>
// Service worker with 'COEP: require-corp' response header.
// This service worker issues a network request to import scripts with or
// without CORP response header.
importScripts("/common/get-host-info.sub.js");
function url_for_empty_js(corp) {
const url = new URL(get_host_info().HTTPS_REMOTE_ORIGIN);
url.pathname = '/service-workers/service-worker/resources/empty.js';
if (corp) {
url.searchParams.set(
'pipe', `header(Cross-Origin-Resource-Policy, ${corp})`);
}
return url.href;
}
const params = new URL(location.href).searchParams;
if (params.get('corp') === 'cross-origin') {
importScripts(url_for_empty_js('cross-origin'));
} else {
importScripts(url_for_empty_js());
}
This is a testharness.js-based test.
PASS Set up global state
PASS fetch() to 'CORP: cross-origin' response should succeed.
FAIL fetch() to no CORP response should not succeed. assert_equals: expected "TypeError: Failed to fetch" but got "opaque"
FAIL importScripts() fails for a script with no corp. assert_unreached: Should have rejected: register() should fail. Reached unreachable code
PASS importScripts() succeeds for a script with corp: cross-origin.
PASS Clean up global state
Harness: the test ran to completion.
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