Commit 90a9b1a3 authored by Hiroki Nakagawa's avatar Hiroki Nakagawa Committed by Commit Bot

Worker: Introduce WorkerOptions for module workers

This CL introduces WorkerOptions for module workers. This is not exposed on the
ctor of any workers yet to avoid making developers confused about unimplemented
features.

This also passes the option from DedicatedWorker::Create() to
DedicatedWorkerMessagingProxy::StartWorkerGlobalScope(). Following CLs will
implement the remaining parts and add tests.

This CL doesn't change the existing behavior.

Rough design doc about module workers:
https://docs.google.com/a/chromium.org/document/d/1IMGWAK7Wq37mLehwkbysNRBBnhQBo3z2MbYyMkViEnY/edit?usp=sharing

Bug: 680046
Change-Id: I571e8f540d842bb06878e13d4b383eddc2df42f1
Reviewed-on: https://chromium-review.googlesource.com/813314Reviewed-by: default avatarKouhei Ueno <kouhei@chromium.org>
Reviewed-by: default avatarKinuko Yasuda <kinuko@chromium.org>
Reviewed-by: default avatarMatt Falkenhagen <falken@chromium.org>
Commit-Queue: Hiroki Nakagawa <nhiroki@chromium.org>
Cr-Commit-Position: refs/heads/master@{#524377}
parent 2ef3d9ac
...@@ -523,6 +523,7 @@ core_typedefs_enums_only_idl_files = ...@@ -523,6 +523,7 @@ core_typedefs_enums_only_idl_files =
"dom/CommonDefinitions.idl", "dom/CommonDefinitions.idl",
"timing/DOMHighResTimeStamp.idl", "timing/DOMHighResTimeStamp.idl",
"timing/PerformanceEntryList.idl", "timing/PerformanceEntryList.idl",
"workers/RequestCredentials.idl",
], ],
"abspath") "abspath")
...@@ -619,6 +620,7 @@ core_dictionary_idl_files = ...@@ -619,6 +620,7 @@ core_dictionary_idl_files =
"offscreencanvas/ImageEncodeOptions.idl", "offscreencanvas/ImageEncodeOptions.idl",
"page/scrolling/ScrollStateInit.idl", "page/scrolling/ScrollStateInit.idl",
"timing/PerformanceObserverInit.idl", "timing/PerformanceObserverInit.idl",
"workers/WorkerOptions.idl",
"workers/WorkletOptions.idl", "workers/WorkletOptions.idl",
], ],
"abspath") "abspath")
......
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
#include "core/frame/UseCounter.h" #include "core/frame/UseCounter.h"
#include "core/frame/WebLocalFrameImpl.h" #include "core/frame/WebLocalFrameImpl.h"
#include "core/inspector/MainThreadDebugger.h" #include "core/inspector/MainThreadDebugger.h"
#include "core/origin_trials/OriginTrialContext.h"
#include "core/probe/CoreProbes.h" #include "core/probe/CoreProbes.h"
#include "core/workers/DedicatedWorkerMessagingProxy.h" #include "core/workers/DedicatedWorkerMessagingProxy.h"
#include "core/workers/WorkerClients.h" #include "core/workers/WorkerClients.h"
...@@ -25,9 +26,29 @@ ...@@ -25,9 +26,29 @@
#include "public/platform/WebContentSettingsClient.h" #include "public/platform/WebContentSettingsClient.h"
#include "public/web/WebFrameClient.h" #include "public/web/WebFrameClient.h"
#include "services/network/public/interfaces/fetch_api.mojom-blink.h" #include "services/network/public/interfaces/fetch_api.mojom-blink.h"
#include "services/service_manager/public/cpp/interface_provider.h"
#include "services/service_manager/public/interfaces/interface_provider.mojom-blink.h"
#include "third_party/WebKit/public/platform/dedicated_worker_factory.mojom-blink.h"
namespace blink { namespace blink {
namespace {
service_manager::mojom::blink::InterfaceProviderPtrInfo
ConnectToWorkerInterfaceProvider(
Document* document,
scoped_refptr<const SecurityOrigin> script_origin) {
mojom::blink::DedicatedWorkerFactoryPtr worker_factory;
document->GetInterfaceProvider()->GetInterface(&worker_factory);
service_manager::mojom::blink::InterfaceProviderPtrInfo
interface_provider_ptr;
worker_factory->CreateDedicatedWorker(
script_origin, mojo::MakeRequest(&interface_provider_ptr));
return interface_provider_ptr;
}
} // namespace
DedicatedWorker* DedicatedWorker::Create(ExecutionContext* context, DedicatedWorker* DedicatedWorker::Create(ExecutionContext* context,
const String& url, const String& url,
ExceptionState& exception_state) { ExceptionState& exception_state) {
...@@ -45,15 +66,21 @@ DedicatedWorker* DedicatedWorker::Create(ExecutionContext* context, ...@@ -45,15 +66,21 @@ DedicatedWorker* DedicatedWorker::Create(ExecutionContext* context,
if (!script_url.IsValid()) if (!script_url.IsValid())
return nullptr; return nullptr;
DedicatedWorker* worker = new DedicatedWorker(context, script_url); // TODO(nhiroki): WorkerOptions should be passed from the caller of Create().
// See also the comment in Worker.idl (https://crbug.com/680046).
WorkerOptions options;
DedicatedWorker* worker = new DedicatedWorker(context, script_url, options);
worker->Start(); worker->Start();
return worker; return worker;
} }
DedicatedWorker::DedicatedWorker(ExecutionContext* context, DedicatedWorker::DedicatedWorker(ExecutionContext* context,
const KURL& script_url) const KURL& script_url,
const WorkerOptions& options)
: AbstractWorker(context), : AbstractWorker(context),
script_url_(script_url), script_url_(script_url),
options_(options),
context_proxy_(CreateMessagingProxy(context)) { context_proxy_(CreateMessagingProxy(context)) {
DCHECK(IsMainThread()); DCHECK(IsMainThread());
DCHECK(script_url_.IsValid()); DCHECK(script_url_.IsValid());
...@@ -84,24 +111,40 @@ void DedicatedWorker::postMessage(ScriptState* script_state, ...@@ -84,24 +111,40 @@ void DedicatedWorker::postMessage(ScriptState* script_state,
void DedicatedWorker::Start() { void DedicatedWorker::Start() {
DCHECK(IsMainThread()); DCHECK(IsMainThread());
network::mojom::FetchRequestMode fetch_request_mode =
network::mojom::FetchRequestMode::kSameOrigin;
network::mojom::FetchCredentialsMode fetch_credentials_mode =
network::mojom::FetchCredentialsMode::kSameOrigin;
if (script_url_.ProtocolIsData()) {
fetch_request_mode = network::mojom::FetchRequestMode::kNoCORS;
fetch_credentials_mode = network::mojom::FetchCredentialsMode::kInclude;
}
v8_inspector::V8StackTraceId stack_id = v8_inspector::V8StackTraceId stack_id =
MainThreadDebugger::Instance()->StoreCurrentStackTrace("Worker Created"); MainThreadDebugger::Instance()->StoreCurrentStackTrace("Worker Created");
script_loader_ = WorkerScriptLoader::Create();
script_loader_->LoadAsynchronously( if (options_.type() == "classic") {
*GetExecutionContext(), script_url_, WebURLRequest::kRequestContextWorker, network::mojom::FetchRequestMode fetch_request_mode =
fetch_request_mode, fetch_credentials_mode, network::mojom::FetchRequestMode::kSameOrigin;
GetExecutionContext()->GetSecurityContext().AddressSpace(), network::mojom::FetchCredentialsMode fetch_credentials_mode =
WTF::Bind(&DedicatedWorker::OnResponse, WrapPersistent(this)), network::mojom::FetchCredentialsMode::kSameOrigin;
WTF::Bind(&DedicatedWorker::OnFinished, WrapPersistent(this), stack_id)); if (script_url_.ProtocolIsData()) {
fetch_request_mode = network::mojom::FetchRequestMode::kNoCORS;
fetch_credentials_mode = network::mojom::FetchCredentialsMode::kInclude;
}
script_loader_ = WorkerScriptLoader::Create();
script_loader_->LoadAsynchronously(
*GetExecutionContext(), script_url_,
WebURLRequest::kRequestContextWorker, fetch_request_mode,
fetch_credentials_mode,
GetExecutionContext()->GetSecurityContext().AddressSpace(),
WTF::Bind(&DedicatedWorker::OnResponse, WrapPersistent(this)),
WTF::Bind(&DedicatedWorker::OnFinished, WrapPersistent(this),
stack_id));
return;
}
if (options_.type() == "module") {
// Specify empty source code here because module scripts will be fetched on
// the worker thread as opposed to classic scripts that are fetched on the
// main thread.
context_proxy_->StartWorkerGlobalScope(CreateGlobalScopeCreationParams(),
options_, script_url_, stack_id,
String() /* source_code */);
return;
}
NOTREACHED() << "Invalid type: " << options_.type();
} }
void DedicatedWorker::terminate() { void DedicatedWorker::terminate() {
...@@ -159,15 +202,33 @@ void DedicatedWorker::OnFinished(const v8_inspector::V8StackTraceId& stack_id) { ...@@ -159,15 +202,33 @@ void DedicatedWorker::OnFinished(const v8_inspector::V8StackTraceId& stack_id) {
script_loader_->GetReferrerPolicy(), script_loader_->GetReferrerPolicy(),
kDoNotSupportReferrerPolicyLegacyKeywords, &referrer_policy); kDoNotSupportReferrerPolicyLegacyKeywords, &referrer_policy);
} }
context_proxy_->StartWorkerGlobalScope( std::unique_ptr<GlobalScopeCreationParams> creation_params =
script_loader_->Url(), GetExecutionContext()->UserAgent(), CreateGlobalScopeCreationParams();
script_loader_->SourceText(), referrer_policy, stack_id); creation_params->referrer_policy = referrer_policy;
context_proxy_->StartWorkerGlobalScope(std::move(creation_params), options_,
script_url_, stack_id,
script_loader_->SourceText());
probe::scriptImported(GetExecutionContext(), script_loader_->Identifier(), probe::scriptImported(GetExecutionContext(), script_loader_->Identifier(),
script_loader_->SourceText()); script_loader_->SourceText());
} }
script_loader_ = nullptr; script_loader_ = nullptr;
} }
std::unique_ptr<GlobalScopeCreationParams>
DedicatedWorker::CreateGlobalScopeCreationParams() {
Document* document = ToDocument(GetExecutionContext());
const SecurityOrigin* starter_origin = document->GetSecurityOrigin();
return std::make_unique<GlobalScopeCreationParams>(
script_url_, GetExecutionContext()->UserAgent(),
document->GetContentSecurityPolicy()->Headers().get(),
kReferrerPolicyDefault, starter_origin, nullptr /* worker_clients */,
document->AddressSpace(), OriginTrialContext::GetTokens(document).get(),
std::make_unique<WorkerSettings>(document->GetSettings()),
kV8CacheOptionsDefault,
ConnectToWorkerInterfaceProvider(document,
SecurityOrigin::Create(script_url_)));
}
const AtomicString& DedicatedWorker::InterfaceName() const { const AtomicString& DedicatedWorker::InterfaceName() const {
return EventTargetNames::Worker; return EventTargetNames::Worker;
} }
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
#include "core/dom/events/EventListener.h" #include "core/dom/events/EventListener.h"
#include "core/dom/events/EventTarget.h" #include "core/dom/events/EventTarget.h"
#include "core/workers/AbstractWorker.h" #include "core/workers/AbstractWorker.h"
#include "core/workers/WorkerOptions.h"
#include "platform/wtf/Forward.h" #include "platform/wtf/Forward.h"
namespace v8_inspector { namespace v8_inspector {
...@@ -26,6 +27,7 @@ class ExceptionState; ...@@ -26,6 +27,7 @@ class ExceptionState;
class ExecutionContext; class ExecutionContext;
class ScriptState; class ScriptState;
class WorkerScriptLoader; class WorkerScriptLoader;
struct GlobalScopeCreationParams;
// Implementation of the Worker interface defined in the WebWorker HTML spec: // Implementation of the Worker interface defined in the WebWorker HTML spec:
// https://html.spec.whatwg.org/multipage/workers.html#worker // https://html.spec.whatwg.org/multipage/workers.html#worker
...@@ -67,17 +69,22 @@ class CORE_EXPORT DedicatedWorker final ...@@ -67,17 +69,22 @@ class CORE_EXPORT DedicatedWorker final
void Trace(blink::Visitor*) override; void Trace(blink::Visitor*) override;
private: private:
DedicatedWorker(ExecutionContext*, const KURL& script_url); DedicatedWorker(ExecutionContext*,
const KURL& script_url,
const WorkerOptions&);
// Starts the worker. // Starts the worker.
void Start(); void Start();
std::unique_ptr<GlobalScopeCreationParams> CreateGlobalScopeCreationParams();
// Creates a proxy to allow communicating with the worker's global scope. // Creates a proxy to allow communicating with the worker's global scope.
// DedicatedWorker does not take ownership of the created proxy. The proxy // DedicatedWorker does not take ownership of the created proxy. The proxy
// is expected to manage its own lifetime, and delete itself in response to // is expected to manage its own lifetime, and delete itself in response to
// terminateWorkerGlobalScope(). // terminateWorkerGlobalScope().
DedicatedWorkerMessagingProxy* CreateMessagingProxy(ExecutionContext*); DedicatedWorkerMessagingProxy* CreateMessagingProxy(ExecutionContext*);
// [classic script only]
// Callbacks for |script_loader_|. // Callbacks for |script_loader_|.
void OnResponse(); void OnResponse();
void OnFinished(const v8_inspector::V8StackTraceId&); void OnFinished(const v8_inspector::V8StackTraceId&);
...@@ -86,6 +93,7 @@ class CORE_EXPORT DedicatedWorker final ...@@ -86,6 +93,7 @@ class CORE_EXPORT DedicatedWorker final
const AtomicString& InterfaceName() const final; const AtomicString& InterfaceName() const final;
const KURL script_url_; const KURL script_url_;
const WorkerOptions options_;
const Member<DedicatedWorkerMessagingProxy> context_proxy_; const Member<DedicatedWorkerMessagingProxy> context_proxy_;
scoped_refptr<WorkerScriptLoader> script_loader_; scoped_refptr<WorkerScriptLoader> script_loader_;
......
...@@ -11,38 +11,18 @@ ...@@ -11,38 +11,18 @@
#include "core/events/MessageEvent.h" #include "core/events/MessageEvent.h"
#include "core/frame/csp/ContentSecurityPolicy.h" #include "core/frame/csp/ContentSecurityPolicy.h"
#include "core/inspector/MainThreadDebugger.h" #include "core/inspector/MainThreadDebugger.h"
#include "core/origin_trials/OriginTrialContext.h"
#include "core/workers/DedicatedWorker.h" #include "core/workers/DedicatedWorker.h"
#include "core/workers/DedicatedWorkerObjectProxy.h" #include "core/workers/DedicatedWorkerObjectProxy.h"
#include "core/workers/DedicatedWorkerThread.h" #include "core/workers/DedicatedWorkerThread.h"
#include "core/workers/GlobalScopeCreationParams.h"
#include "core/workers/WorkerClients.h" #include "core/workers/WorkerClients.h"
#include "core/workers/WorkerInspectorProxy.h" #include "core/workers/WorkerInspectorProxy.h"
#include "core/workers/WorkerOptions.h"
#include "platform/CrossThreadFunctional.h" #include "platform/CrossThreadFunctional.h"
#include "platform/WebTaskRunner.h" #include "platform/WebTaskRunner.h"
#include "platform/wtf/WTF.h" #include "platform/wtf/WTF.h"
#include "public/platform/TaskType.h" #include "public/platform/TaskType.h"
#include "services/service_manager/public/cpp/interface_provider.h"
#include "services/service_manager/public/interfaces/interface_provider.mojom-blink.h"
#include "third_party/WebKit/public/platform/dedicated_worker_factory.mojom-blink.h"
namespace blink { namespace blink {
namespace {
service_manager::mojom::blink::InterfaceProviderPtrInfo
ConnectToWorkerInterfaceProvider(
Document* document,
scoped_refptr<const SecurityOrigin> script_origin) {
mojom::blink::DedicatedWorkerFactoryPtr worker_factory;
document->GetInterfaceProvider()->GetInterface(&worker_factory);
service_manager::mojom::blink::InterfaceProviderPtrInfo
interface_provider_ptr;
worker_factory->CreateDedicatedWorker(
script_origin, mojo::MakeRequest(&interface_provider_ptr));
return interface_provider_ptr;
}
} // namespace
struct DedicatedWorkerMessagingProxy::QueuedTask { struct DedicatedWorkerMessagingProxy::QueuedTask {
scoped_refptr<SerializedScriptValue> message; scoped_refptr<SerializedScriptValue> message;
...@@ -63,11 +43,11 @@ DedicatedWorkerMessagingProxy::DedicatedWorkerMessagingProxy( ...@@ -63,11 +43,11 @@ DedicatedWorkerMessagingProxy::DedicatedWorkerMessagingProxy(
DedicatedWorkerMessagingProxy::~DedicatedWorkerMessagingProxy() = default; DedicatedWorkerMessagingProxy::~DedicatedWorkerMessagingProxy() = default;
void DedicatedWorkerMessagingProxy::StartWorkerGlobalScope( void DedicatedWorkerMessagingProxy::StartWorkerGlobalScope(
std::unique_ptr<GlobalScopeCreationParams> creation_params,
const WorkerOptions& options,
const KURL& script_url, const KURL& script_url,
const String& user_agent, const v8_inspector::V8StackTraceId& stack_id,
const String& source_code, const String& source_code) {
ReferrerPolicy referrer_policy,
const v8_inspector::V8StackTraceId& stack_id) {
DCHECK(IsParentContextThread()); DCHECK(IsParentContextThread());
if (AskedToTerminate()) { if (AskedToTerminate()) {
// Worker.terminate() could be called from JS before the thread was // Worker.terminate() could be called from JS before the thread was
...@@ -75,25 +55,15 @@ void DedicatedWorkerMessagingProxy::StartWorkerGlobalScope( ...@@ -75,25 +55,15 @@ void DedicatedWorkerMessagingProxy::StartWorkerGlobalScope(
return; return;
} }
Document* document = ToDocument(GetExecutionContext()); // TODO(nhiroki): Move ReleaseWorkerClients() to DedicatedWorker for cleanup.
const SecurityOrigin* starter_origin = document->GetSecurityOrigin(); creation_params->worker_clients = ReleaseWorkerClients();
ContentSecurityPolicy* csp = document->GetContentSecurityPolicy(); // TODO(nhiroki): Support module scripts (https://crbug.com/680046).
DCHECK(csp); DCHECK_EQ("classic", options.type());
InitializeWorkerThread(
auto global_scope_creation_params = std::move(creation_params),
std::make_unique<GlobalScopeCreationParams>( CreateBackingThreadStartupData(ToIsolate(GetExecutionContext())),
script_url, user_agent, csp->Headers().get(), referrer_policy, script_url, stack_id, source_code);
starter_origin, ReleaseWorkerClients(), document->AddressSpace(),
OriginTrialContext::GetTokens(document).get(),
std::make_unique<WorkerSettings>(document->GetSettings()),
kV8CacheOptionsDefault,
ConnectToWorkerInterfaceProvider(document,
SecurityOrigin::Create(script_url)));
InitializeWorkerThread(std::move(global_scope_creation_params),
CreateBackingThreadStartupData(ToIsolate(document)),
script_url, stack_id, source_code);
// Post all queued tasks to the worker. // Post all queued tasks to the worker.
for (auto& queued_task : queued_early_tasks_) { for (auto& queued_task : queued_early_tasks_) {
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#include "base/memory/scoped_refptr.h" #include "base/memory/scoped_refptr.h"
#include "core/CoreExport.h" #include "core/CoreExport.h"
#include "core/dom/MessagePort.h" #include "core/dom/MessagePort.h"
#include "core/workers/GlobalScopeCreationParams.h"
#include "core/workers/ThreadedMessagingProxyBase.h" #include "core/workers/ThreadedMessagingProxyBase.h"
#include "core/workers/WorkerBackingThreadStartupData.h" #include "core/workers/WorkerBackingThreadStartupData.h"
#include "platform/heap/Handle.h" #include "platform/heap/Handle.h"
...@@ -26,6 +27,7 @@ class DedicatedWorker; ...@@ -26,6 +27,7 @@ class DedicatedWorker;
class DedicatedWorkerObjectProxy; class DedicatedWorkerObjectProxy;
class SerializedScriptValue; class SerializedScriptValue;
class WorkerClients; class WorkerClients;
class WorkerOptions;
// A proxy class to talk to the DedicatedWorkerGlobalScope on a worker thread // A proxy class to talk to the DedicatedWorkerGlobalScope on a worker thread
// via the DedicatedWorkerMessagingProxy from the main thread. See class // via the DedicatedWorkerMessagingProxy from the main thread. See class
...@@ -39,11 +41,11 @@ class CORE_EXPORT DedicatedWorkerMessagingProxy ...@@ -39,11 +41,11 @@ class CORE_EXPORT DedicatedWorkerMessagingProxy
~DedicatedWorkerMessagingProxy() override; ~DedicatedWorkerMessagingProxy() override;
// These methods should only be used on the parent context thread. // These methods should only be used on the parent context thread.
void StartWorkerGlobalScope(const KURL& script_url, void StartWorkerGlobalScope(std::unique_ptr<GlobalScopeCreationParams>,
const String& user_agent, const WorkerOptions&,
const String& source_code, const KURL& script_url,
ReferrerPolicy, const v8_inspector::V8StackTraceId&,
const v8_inspector::V8StackTraceId&); const String& source_code);
void PostMessageToWorkerGlobalScope(scoped_refptr<SerializedScriptValue>, void PostMessageToWorkerGlobalScope(scoped_refptr<SerializedScriptValue>,
Vector<MessagePortChannel>, Vector<MessagePortChannel>,
const v8_inspector::V8StackTraceId&); const v8_inspector::V8StackTraceId&);
......
// Copyright 2017 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.
// https://fetch.spec.whatwg.org/#requestcredentials
// Copied from modules/fetch/Request.idl because it's not accessible from core/
// directory.
// TODO(nhiroki): Consider how to reuse the existing enum (e.g.,
// https://crbug.com/794837)
enum RequestCredentials { "omit", "same-origin", "include" };
...@@ -29,7 +29,10 @@ ...@@ -29,7 +29,10 @@
[ [
ActiveScriptWrappable, ActiveScriptWrappable,
Constructor(DOMString scriptUrl), // TODO(nhiroki): Support WorkerOptions for module workers.
// (https://crbug.com/680046)
// Constructor(DOMString scriptURL, optional WorkerOptions options),
Constructor(DOMString scriptURL),
ConstructorCallWith=ExecutionContext, ConstructorCallWith=ExecutionContext,
// TODO(foolip): Exposed=(Window,Worker), // TODO(foolip): Exposed=(Window,Worker),
RaisesException=Constructor, RaisesException=Constructor,
......
// Copyright 2017 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.
// https://html.spec.whatwg.org/multipage/workers.html#workeroptions
dictionary WorkerOptions {
WorkerType type = "classic";
RequestCredentials credentials = "omit";
// TODO(nhiroki): Implement "name" option (https://crbug.com/721219)
// DOMString name = "";
};
enum WorkerType { "classic", "module" };
...@@ -2,12 +2,6 @@ ...@@ -2,12 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
// https://fetch.spec.whatwg.org/#requestcredentials
// Copied from modules/fetch/Request.idl because it's not accessible from core/
// directory.
// TODO(nhiroki): Consider how to reuse the existing enum.
enum RequestCredentials { "omit", "same-origin", "include" };
// https://drafts.css-houdini.org/worklets/#dictdef-workletoptions // https://drafts.css-houdini.org/worklets/#dictdef-workletoptions
dictionary WorkletOptions { dictionary WorkletOptions {
RequestCredentials credentials = "omit"; RequestCredentials credentials = "omit";
......
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