blob: 7d5d769df263a6ed1973599c6814e80fdf77b180 [file] [log] [blame]
// 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.
#ifndef CONTENT_RENDERER_LOADER_WEB_WORKER_FETCH_CONTEXT_IMPL_H_
#define CONTENT_RENDERER_LOADER_WEB_WORKER_FETCH_CONTEXT_IMPL_H_
#include <memory>
#include <string>
#include "base/synchronization/waitable_event.h"
#include "content/common/child_process.mojom.h"
#include "content/common/content_export.h"
#include "ipc/ipc_message.h"
#include "mojo/public/cpp/bindings/pending_receiver.h"
#include "mojo/public/cpp/bindings/pending_remote.h"
#include "mojo/public/cpp/bindings/receiver.h"
#include "mojo/public/cpp/bindings/remote.h"
#include "mojo/public/cpp/bindings/remote_set.h"
#include "mojo/public/cpp/bindings/shared_remote.h"
#include "services/network/public/cpp/shared_url_loader_factory.h"
#include "services/network/public/mojom/url_loader_factory.mojom.h"
#include "third_party/blink/public/mojom/blob/blob_registry.mojom.h"
#include "third_party/blink/public/mojom/renderer_preference_watcher.mojom.h"
#include "third_party/blink/public/mojom/renderer_preferences.mojom.h"
#include "third_party/blink/public/mojom/service_worker/service_worker_container.mojom.h"
#include "third_party/blink/public/mojom/service_worker/service_worker_object.mojom.h"
#include "third_party/blink/public/mojom/service_worker/service_worker_provider.mojom.h"
#include "third_party/blink/public/mojom/timing/worker_timing_container.mojom-forward.h"
#include "third_party/blink/public/mojom/worker/subresource_loader_updater.mojom.h"
#include "third_party/blink/public/platform/web_string.h"
#include "third_party/blink/public/platform/web_worker_fetch_context.h"
#include "url/gurl.h"
namespace IPC {
class Message;
} // namespace IPC
namespace content {
class FrameRequestBlocker;
class ResourceDispatcher;
class ServiceWorkerProviderContext;
class ThreadSafeSender;
class URLLoaderThrottleProvider;
class WebSocketHandshakeThrottleProvider;
struct NavigationResponseOverrideParameters;
// This class is used for fetching resource requests from workers (dedicated
// worker and shared worker). This class is created on the main thread and
// passed to the worker thread. This class is not used for service workers. For
// service workers, ServiceWorkerFetchContextImpl class is used instead.
class CONTENT_EXPORT WebWorkerFetchContextImpl
: public blink::WebWorkerFetchContext,
public blink::mojom::SubresourceLoaderUpdater,
public blink::mojom::ServiceWorkerWorkerClient,
public blink::mojom::RendererPreferenceWatcher {
public:
// Creates a new fetch context for a worker.
//
// |provider_context| is used to set up information for using service workers.
// It can be null if the worker is not allowed to use service workers due to
// security reasons like sandboxed iframes, insecure origins etc.
// |pending_loader_factory| is used for regular loading by the worker.
//
// If the worker is controlled by a service worker, this class makes another
// loader factory which sends requests to the service worker, and passes
// |pending_fallback_factory| to that factory to use for network fallback.
//
// |pending_loader_factory| and |pending_fallback_factory| are different
// because |pending_loader_factory| can possibly include a default factory
// like AppCache, while |pending_fallback_factory| should not have such a
// default factory and instead go directly to network for http(s) requests.
// |pending_fallback_factory| might not be simply the direct network factory,
// because it might additionally support non-NetworkService schemes (e.g.,
// chrome-extension://).
static scoped_refptr<WebWorkerFetchContextImpl> Create(
ServiceWorkerProviderContext* provider_context,
blink::mojom::RendererPreferences renderer_preferences,
mojo::PendingReceiver<blink::mojom::RendererPreferenceWatcher>
watcher_receiver,
std::unique_ptr<network::PendingSharedURLLoaderFactory>
pending_loader_factory,
std::unique_ptr<network::PendingSharedURLLoaderFactory>
pending_fallback_factory,
mojo::PendingReceiver<blink::mojom::SubresourceLoaderUpdater>
pending_subresource_loader_updater);
// Clones this fetch context for a nested worker.
// For non-PlzDedicatedWorker. This will be removed once PlzDedicatedWorker is
// enabled by default.
scoped_refptr<WebWorkerFetchContextImpl> CloneForNestedWorkerDeprecated(
scoped_refptr<base::SingleThreadTaskRunner> task_runner);
// For PlzDedicatedWorker. The cloned fetch context does not inherit some
// fields (e.g., ServiceWorkerProviderContext) from this fetch context, and
// instead that takes values passed from the browser process.
scoped_refptr<WebWorkerFetchContextImpl> CloneForNestedWorker(
ServiceWorkerProviderContext* service_worker_provider_context,
std::unique_ptr<network::PendingSharedURLLoaderFactory>
pending_loader_factory,
std::unique_ptr<network::PendingSharedURLLoaderFactory>
pending_fallback_factory,
mojo::PendingReceiver<blink::mojom::SubresourceLoaderUpdater>
pending_subresource_loader_updater,
scoped_refptr<base::SingleThreadTaskRunner> task_runner);
// blink::WebWorkerFetchContext implementation:
void SetTerminateSyncLoadEvent(base::WaitableEvent*) override;
void InitializeOnWorkerThread(blink::AcceptLanguagesWatcher*) override;
blink::WebURLLoaderFactory* GetURLLoaderFactory() override;
std::unique_ptr<blink::WebURLLoaderFactory> WrapURLLoaderFactory(
mojo::ScopedMessagePipeHandle url_loader_factory_handle) override;
std::unique_ptr<blink::CodeCacheLoader> CreateCodeCacheLoader() override;
void WillSendRequest(blink::WebURLRequest&) override;
blink::mojom::ControllerServiceWorkerMode GetControllerServiceWorkerMode()
const override;
void SetIsOnSubframe(bool) override;
bool IsOnSubframe() const override;
blink::WebURL SiteForCookies() const override;
base::Optional<blink::WebSecurityOrigin> TopFrameOrigin() const override;
void DidRunContentWithCertificateErrors() override;
void DidDisplayContentWithCertificateErrors() override;
void DidRunInsecureContent(const blink::WebSecurityOrigin&,
const blink::WebURL& insecure_url) override;
void SetSubresourceFilterBuilder(
std::unique_ptr<blink::WebDocumentSubresourceFilter::Builder>) override;
std::unique_ptr<blink::WebDocumentSubresourceFilter> TakeSubresourceFilter()
override;
std::unique_ptr<blink::WebSocketHandshakeThrottle>
CreateWebSocketHandshakeThrottle(
scoped_refptr<base::SingleThreadTaskRunner> task_runner) override;
mojo::ScopedMessagePipeHandle TakePendingWorkerTimingReceiver(
int request_id) override;
// blink::mojom::ServiceWorkerWorkerClient implementation:
void OnControllerChanged(blink::mojom::ControllerServiceWorkerMode) override;
// Sets the controller service worker mode.
// - For dedicated workers (non-PlzDedicatedWorker), they depend on the
// controller of the ancestor frame (directly for non-nested workers, or
// indirectly via its parent worker for nested workers), and inherit its
// controller mode.
// - For dedicated workers (PlzDedicatedWorker) and shared workers, the
// controller mode is passed from the browser processw when starting the
// worker.
void set_controller_service_worker_mode(
blink::mojom::ControllerServiceWorkerMode mode);
// Sets properties associated with frames.
// - For dedicated workers, the property is copied from the ancestor frame
// (directly for non-nested workers, or indirectly via its parent worker for
// nested workers).
// - For shared workers, there is no parent frame, so the default value, or a
// value calculated in some way is set.
//
// TODO(nhiroki): Add more comments about security/privacy implications to
// each property, for example, site_for_cookies and top_frame_origin.
void set_ancestor_frame_id(int id);
void set_frame_request_blocker(
scoped_refptr<FrameRequestBlocker> frame_request_blocker);
void set_site_for_cookies(const blink::WebURL& site_for_cookies);
void set_top_frame_origin(const blink::WebSecurityOrigin& top_frame_origin);
// Sets whether the worker context is a secure context.
// https://w3c.github.io/webappsec-secure-contexts/
void set_origin_url(const GURL& origin_url);
void set_client_id(const std::string& client_id);
// PlzWorker with off-the-main-thread worker script fetch:
// Sets the response for the worker main script loaded by the browser process.
void SetResponseOverrideForMainScript(
std::unique_ptr<NavigationResponseOverrideParameters> response_override);
using RewriteURLFunction = blink::WebURL (*)(const std::string&, bool);
static void InstallRewriteURLFunction(RewriteURLFunction rewrite_url);
blink::WebString GetAcceptLanguages() const override;
// Sets up |receiver| to receive resource performance timings for the given
// |request_id|. This receiver will be taken later by
// TakePendingWorkerTimingReceiver().
void AddPendingWorkerTimingReceiver(
int request_id,
mojo::PendingReceiver<blink::mojom::WorkerTimingContainer> receiver);
private:
class Factory;
using WorkerTimingContainerReceiverMap =
std::map<int /* request_id */,
mojo::PendingReceiver<blink::mojom::WorkerTimingContainer>>;
// - |service_worker_client_receiver| receives OnControllerChanged()
// notifications.
// - |service_worker_worker_client_registry| is used to register new
// ServiceWorkerWorkerClients, which is needed when creating a
// nested worker.
//
// Regarding the rest of params, see the comments on Create().
WebWorkerFetchContextImpl(
blink::mojom::RendererPreferences renderer_preferences,
mojo::PendingReceiver<blink::mojom::RendererPreferenceWatcher>
watcher_receiver,
mojo::PendingReceiver<blink::mojom::ServiceWorkerWorkerClient>
service_worker_client_receiver,
mojo::PendingRemote<blink::mojom::ServiceWorkerWorkerClientRegistry>
service_worker_worker_client_registry,
mojo::PendingRemote<blink::mojom::ServiceWorkerContainerHost>
service_worker_container_host,
std::unique_ptr<network::PendingSharedURLLoaderFactory>
pending_loader_factory,
std::unique_ptr<network::PendingSharedURLLoaderFactory>
pending_fallback_factory,
mojo::PendingReceiver<blink::mojom::SubresourceLoaderUpdater>
pending_subresource_loader_updater,
std::unique_ptr<URLLoaderThrottleProvider> throttle_provider,
std::unique_ptr<WebSocketHandshakeThrottleProvider>
websocket_handshake_throttle_provider,
ThreadSafeSender* thread_safe_sender,
mojo::SharedRemote<mojom::ChildProcessHost> process_host);
~WebWorkerFetchContextImpl() override;
scoped_refptr<WebWorkerFetchContextImpl> CloneForNestedWorkerInternal(
mojo::PendingReceiver<blink::mojom::ServiceWorkerWorkerClient>
service_worker_client_receiver,
mojo::PendingRemote<blink::mojom::ServiceWorkerWorkerClientRegistry>
service_worker_worker_client_registry,
mojo::PendingRemote<blink::mojom::ServiceWorkerContainerHost>
service_worker_container_host,
std::unique_ptr<network::PendingSharedURLLoaderFactory>
pending_loader_factory,
std::unique_ptr<network::PendingSharedURLLoaderFactory>
pending_fallback_factory,
mojo::PendingReceiver<blink::mojom::SubresourceLoaderUpdater>
pending_subresource_loader_updater,
scoped_refptr<base::SingleThreadTaskRunner> task_runner);
bool Send(IPC::Message* message);
// Resets the service worker url loader factory of a URLLoaderFactoryImpl
// which was passed to Blink. The url loader factory is connected to the
// controller service worker. Sets nullptr if the worker context is not
// controlled by a service worker.
void ResetServiceWorkerURLLoaderFactory();
// Implements blink::mojom::SubresourceLoaderUpdater.
void UpdateSubresourceLoaderFactories(
std::unique_ptr<blink::PendingURLLoaderFactoryBundle>
subresource_loader_factories) override;
// Implements blink::mojom::RendererPreferenceWatcher.
void NotifyUpdate(blink::mojom::RendererPreferencesPtr new_prefs) override;
// |receiver_| and |service_worker_worker_client_registry_| may be null if
// this context can't use service workers. See comments for Create().
mojo::Receiver<blink::mojom::ServiceWorkerWorkerClient> receiver_{this};
mojo::Remote<blink::mojom::ServiceWorkerWorkerClientRegistry>
service_worker_worker_client_registry_;
// Bound to |this| on the worker thread.
mojo::PendingReceiver<blink::mojom::ServiceWorkerWorkerClient>
service_worker_client_receiver_;
// Consumed on the worker thread to create
// |service_worker_worker_client_registry_|.
mojo::PendingRemote<blink::mojom::ServiceWorkerWorkerClientRegistry>
pending_service_worker_worker_client_registry_;
// Consumed on the worker thread to create |service_worker_container_host_|.
mojo::PendingRemote<blink::mojom::ServiceWorkerContainerHost>
pending_service_worker_container_host_;
// Consumed on the worker thread to create |loader_factory_|.
std::unique_ptr<network::PendingSharedURLLoaderFactory>
pending_loader_factory_;
// Consumed on the worker thread to create |fallback_factory_|.
std::unique_ptr<network::PendingSharedURLLoaderFactory>
pending_fallback_factory_;
blink::mojom::ControllerServiceWorkerMode controller_service_worker_mode_ =
blink::mojom::ControllerServiceWorkerMode::kNoController;
// Initialized on the worker thread when InitializeOnWorkerThread() is called.
// This can be null if the |provider_context| passed to Create() was null or
// already being destructed (see
// ServiceWorkerProviderContext::OnNetworkProviderDestroyed()).
mojo::Remote<blink::mojom::ServiceWorkerContainerHost>
service_worker_container_host_;
// The Client#id value of the shared worker or dedicated worker (since
// dedicated workers are not yet service worker clients, it is the parent
// document's id in that case). Passed to ControllerServiceWorkerConnector.
std::string client_id_;
// Initialized on the worker thread when InitializeOnWorkerThread() is called.
std::unique_ptr<ResourceDispatcher> resource_dispatcher_;
// Initialized on the worker thread when InitializeOnWorkerThread() is called.
// |loader_factory_| is used for regular loading by the worker. In
// If the worker is controlled by a service worker, it creates a
// ServiceWorkerSubresourceLoaderFactory instead.
scoped_refptr<network::SharedURLLoaderFactory> loader_factory_;
// Initialized on the worker thread when InitializeOnWorkerThread() is called.
// If the worker is controlled by a service worker, it passes this factory to
// ServiceWorkerSubresourceLoaderFactory to use for network fallback.
scoped_refptr<network::SharedURLLoaderFactory> fallback_factory_;
// Initialized on the worker thread when InitializeOnWorkerThread() is called.
// Used to reconnect to the Network Service after the Network Service crash.
// This is only used for dedicated workers when PlzDedicatedWorker is enabled.
// When PlzDedicatedWorker is disabled, the ancestor render frame updates the
// loaders via Host/TrackedChildURLLoaderFactoryBundle. For shared workers,
// the renderer process detects the crash, and terminates the worker instead
// of recovery.
mojo::PendingReceiver<blink::mojom::SubresourceLoaderUpdater>
pending_subresource_loader_updater_;
mojo::Receiver<blink::mojom::SubresourceLoaderUpdater>
subresource_loader_updater_{this};
// Initialized on the worker thread when InitializeOnWorkerThread() is called.
scoped_refptr<base::RefCountedData<mojo::Remote<blink::mojom::BlobRegistry>>>
blob_registry_;
scoped_refptr<ThreadSafeSender> thread_safe_sender_;
std::unique_ptr<blink::WebDocumentSubresourceFilter::Builder>
subresource_filter_builder_;
// For dedicated workers, this is the ancestor frame (the parent frame for
// non-nested workers, the closest ancestor for nested workers). For shared
// workers, this is the shadow page.
bool is_on_sub_frame_ = false;
int ancestor_frame_id_ = MSG_ROUTING_NONE;
// Set to non-null if the ancestor frame has an associated RequestBlocker,
// which blocks requests from this worker too when the ancestor frame is
// blocked.
scoped_refptr<FrameRequestBlocker> frame_request_blocker_;
GURL site_for_cookies_;
base::Optional<url::Origin> top_frame_origin_;
GURL origin_url_;
blink::mojom::RendererPreferences renderer_preferences_;
// |preference_watcher_receiver_| and |child_preference_watchers_| are for
// keeping track of updates in the renderer preferences.
mojo::Receiver<blink::mojom::RendererPreferenceWatcher>
preference_watcher_receiver_{this};
// Kept while staring up the worker thread. Valid until
// InitializeOnWorkerThread().
mojo::PendingReceiver<blink::mojom::RendererPreferenceWatcher>
preference_watcher_pending_receiver_;
mojo::RemoteSet<blink::mojom::RendererPreferenceWatcher>
child_preference_watchers_;
// This is owned by ThreadedMessagingProxyBase on the main thread.
base::WaitableEvent* terminate_sync_load_event_ = nullptr;
// The blink::WebURLLoaderFactory which was created and passed to
// Blink by GetURLLoaderFactory().
std::unique_ptr<Factory> web_loader_factory_;
std::unique_ptr<URLLoaderThrottleProvider> throttle_provider_;
std::unique_ptr<WebSocketHandshakeThrottleProvider>
websocket_handshake_throttle_provider_;
mojo::SharedRemote<mojom::ChildProcessHost> process_host_;
std::unique_ptr<NavigationResponseOverrideParameters> response_override_;
blink::AcceptLanguagesWatcher* accept_languages_watcher_ = nullptr;
// Contains pending receivers whose corresponding requests are still
// in-flight. The pending receivers are taken by
// TakePendingWorkerTimingReceiver() when the request is completed.
WorkerTimingContainerReceiverMap worker_timing_container_receivers_;
base::WeakPtrFactory<WebWorkerFetchContextImpl> weak_factory_{this};
};
} // namespace content
#endif // CONTENT_RENDERER_LOADER_WEB_WORKER_FETCH_CONTEXT_IMPL_H_