blob: fa153dab555d6f084806798698d5e3e4a8f37b80 [file] [log] [blame]
// Copyright 2014 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "content/renderer/worker/embedded_shared_worker_stub.h"
#include <stdint.h>
#include <algorithm>
#include <utility>
#include "base/containers/to_vector.h"
#include "base/feature_list.h"
#include "base/functional/bind.h"
#include "content/renderer/content_security_policy_util.h"
#include "content/renderer/policy_container_util.h"
#include "content/renderer/worker/fetch_client_settings_object_helpers.h"
#include "services/network/public/cpp/shared_url_loader_factory.h"
#include "third_party/blink/public/common/features.h"
#include "third_party/blink/public/common/loader/worker_main_script_load_parameters.h"
#include "third_party/blink/public/common/messaging/message_port_channel.h"
#include "third_party/blink/public/common/messaging/message_port_descriptor.h"
#include "third_party/blink/public/mojom/browser_interface_broker.mojom.h"
#include "third_party/blink/public/mojom/devtools/devtools_agent.mojom.h"
#include "third_party/blink/public/mojom/renderer_preference_watcher.mojom.h"
#include "third_party/blink/public/mojom/service_worker/service_worker_object.mojom.h"
#include "third_party/blink/public/mojom/worker/worker_content_settings_proxy.mojom.h"
#include "third_party/blink/public/platform/child_url_loader_factory_bundle.h"
#include "third_party/blink/public/platform/web_dedicated_or_shared_worker_global_scope_context.h"
#include "third_party/blink/public/platform/web_fetch_client_settings_object.h"
#include "third_party/blink/public/platform/web_string.h"
#include "third_party/blink/public/web/web_shared_worker.h"
#include "url/origin.h"
namespace content {
EmbeddedSharedWorkerStub::EmbeddedSharedWorkerStub(
blink::mojom::SharedWorkerInfoPtr info,
const blink::SharedWorkerToken& token,
const blink::StorageKey& constructor_key,
const url::Origin& origin,
bool is_constructor_secure_context,
const std::string& user_agent,
const blink::UserAgentMetadata& ua_metadata,
bool pause_on_start,
const base::UnguessableToken& devtools_worker_token,
const blink::RendererPreferences& renderer_preferences,
mojo::PendingReceiver<blink::mojom::RendererPreferenceWatcher>
preference_watcher_receiver,
mojo::PendingRemote<blink::mojom::WorkerContentSettingsProxy>
content_settings,
blink::mojom::ServiceWorkerContainerInfoForClientPtr
service_worker_container_info,
blink::mojom::WorkerMainScriptLoadParamsPtr main_script_load_params,
std::unique_ptr<blink::PendingURLLoaderFactoryBundle>
pending_subresource_loader_factory_bundle,
blink::mojom::ControllerServiceWorkerInfoPtr controller_info,
blink::mojom::PolicyContainerPtr policy_container,
mojo::PendingRemote<blink::mojom::SharedWorkerHost> host,
mojo::PendingReceiver<blink::mojom::SharedWorker> receiver,
mojo::PendingRemote<blink::mojom::BrowserInterfaceBroker>
browser_interface_broker,
ukm::SourceId ukm_source_id,
bool require_cross_site_request_for_cookies,
mojo::PendingReceiver<blink::mojom::ReportingObserver>
coep_reporting_observer,
mojo::PendingReceiver<blink::mojom::ReportingObserver>
dip_reporting_observer,
const std::vector<std::string>& cors_exempt_header_list)
: receiver_(this, std::move(receiver)) {
DCHECK(main_script_load_params);
DCHECK(pending_subresource_loader_factory_bundle);
// Initialize the loading parameters for the main worker script loaded by
// the browser process.
auto worker_main_script_load_params =
std::make_unique<blink::WorkerMainScriptLoadParameters>();
worker_main_script_load_params->request_id =
main_script_load_params->request_id;
worker_main_script_load_params->response_head =
std::move(main_script_load_params->response_head);
worker_main_script_load_params->response_body =
std::move(main_script_load_params->response_body);
worker_main_script_load_params->redirect_responses =
std::move(main_script_load_params->redirect_response_heads);
worker_main_script_load_params->redirect_infos =
main_script_load_params->redirect_infos;
worker_main_script_load_params->url_loader_client_endpoints =
std::move(main_script_load_params->url_loader_client_endpoints);
// If the network service crashes, then self-destruct so clients don't get
// stuck with a worker with a broken loader. Self-destruction is effectively
// the same as the worker's process crashing.
default_factory_disconnect_handler_holder_.Bind(std::move(
pending_subresource_loader_factory_bundle->pending_default_factory()));
default_factory_disconnect_handler_holder_->Clone(
pending_subresource_loader_factory_bundle->pending_default_factory()
.InitWithNewPipeAndPassReceiver());
default_factory_disconnect_handler_holder_.set_disconnect_handler(
base::BindOnce(&EmbeddedSharedWorkerStub::Terminate,
base::Unretained(this)));
// Initialize the subresource loader factory bundle passed by the browser
// process.
subresource_loader_factory_bundle_ =
base::MakeRefCounted<blink::ChildURLLoaderFactoryBundle>(
std::make_unique<blink::ChildPendingURLLoaderFactoryBundle>(
std::move(pending_subresource_loader_factory_bundle)));
if (service_worker_container_info) {
service_worker_provider_context_ =
base::MakeRefCounted<ServiceWorkerProviderContext>(
blink::mojom::ServiceWorkerContainerType::kForSharedWorker,
std::move(service_worker_container_info->client_receiver),
std::move(service_worker_container_info->host_remote),
std::move(controller_info), subresource_loader_factory_bundle_);
service_worker_provider_context_->set_container_is_blob_url_shared_worker(
info->url.SchemeIsBlob());
}
scoped_refptr<blink::WebWorkerFetchContext> web_worker_fetch_context =
CreateWorkerFetchContext(constructor_key, std::move(renderer_preferences),
std::move(preference_watcher_receiver),
cors_exempt_header_list,
require_cross_site_request_for_cookies);
impl_ = blink::WebSharedWorker::CreateAndStart(
token, info->url, info->options->type, info->options->credentials,
blink::WebString::FromUTF8(info->options->name),
blink::WebSecurityOrigin(constructor_key.origin()),
blink::WebSecurityOrigin(origin), is_constructor_secure_context,
blink::WebString::FromUTF8(user_agent), ua_metadata,
ToWebContentSecurityPolicies(std::move(info->content_security_policies)),
FetchClientSettingsObjectFromMojomToWeb(
info->outside_fetch_client_settings_object),
devtools_worker_token, std::move(content_settings),
std::move(browser_interface_broker), pause_on_start,
std::move(worker_main_script_load_params),
ToWebPolicyContainer(std::move(policy_container)),
std::move(web_worker_fetch_context), std::move(host), this, ukm_source_id,
require_cross_site_request_for_cookies,
std::move(coep_reporting_observer), std::move(dip_reporting_observer));
// If the host drops its connection, then self-destruct.
receiver_.set_disconnect_handler(base::BindOnce(
&EmbeddedSharedWorkerStub::Terminate, base::Unretained(this)));
}
EmbeddedSharedWorkerStub::~EmbeddedSharedWorkerStub() {
// Destruction closes our connection to the host, triggering the host to
// cleanup and notify clients of this worker going away.
}
void EmbeddedSharedWorkerStub::WorkerContextDestroyed() {
delete this;
}
scoped_refptr<blink::WebWorkerFetchContext>
EmbeddedSharedWorkerStub::CreateWorkerFetchContext(
const blink::StorageKey& constructor_key,
const blink::RendererPreferences& renderer_preferences,
mojo::PendingReceiver<blink::mojom::RendererPreferenceWatcher>
preference_watcher_receiver,
const std::vector<std::string>& cors_exempt_header_list,
bool require_cross_site_request_for_cookies) {
// Make the factory used for service worker network fallback.
std::unique_ptr<network::PendingSharedURLLoaderFactory> fallback_factory =
subresource_loader_factory_bundle_->Clone();
std::vector<blink::WebString> web_cors_exempt_header_list =
base::ToVector(cors_exempt_header_list, &blink::WebString::FromLatin1);
// |pending_subresource_loader_updater| and
// |pending_resource_load_info_notifier| are not used for shared workers.
scoped_refptr<blink::WebDedicatedOrSharedWorkerGlobalScopeContext>
web_dedicated_or_shared_worker_global_scope_context =
blink::WebDedicatedOrSharedWorkerGlobalScopeContext::Create(
service_worker_provider_context_.get(), renderer_preferences,
std::move(preference_watcher_receiver),
subresource_loader_factory_bundle_->Clone(),
std::move(fallback_factory),
/*pending_subresource_loader_updater=*/mojo::NullReceiver(),
web_cors_exempt_header_list,
/*pending_resource_load_info_notifier=*/mojo::NullRemote());
web_dedicated_or_shared_worker_global_scope_context->set_site_for_cookies(
require_cross_site_request_for_cookies
? net::SiteForCookies()
: constructor_key.ToNetSiteForCookies());
// Since this is within `EmbeddedSharedWorkerStub`, the flag should be
// definitely true.
// TODO(crbug.com/324939068): remove the code when the feature launched.
web_dedicated_or_shared_worker_global_scope_context
->set_container_is_shared_worker(true);
return web_dedicated_or_shared_worker_global_scope_context;
}
void EmbeddedSharedWorkerStub::Connect(int connection_request_id,
blink::MessagePortDescriptor port) {
impl_->Connect(connection_request_id, std::move(port));
}
void EmbeddedSharedWorkerStub::Terminate() {
impl_->TerminateWorkerContext();
}
} // namespace content