| // Copyright 2013 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_BROWSER_SERVICE_WORKER_SERVICE_WORKER_PROVIDER_HOST_H_ |
| #define CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_PROVIDER_HOST_H_ |
| |
| #include <stddef.h> |
| #include <stdint.h> |
| |
| #include <map> |
| #include <memory> |
| #include <set> |
| #include <string> |
| #include <vector> |
| |
| #include "base/gtest_prod_util.h" |
| #include "base/macros.h" |
| #include "base/memory/ref_counted.h" |
| #include "base/memory/weak_ptr.h" |
| #include "base/time/time.h" |
| #include "base/unguessable_token.h" |
| #include "content/browser/service_worker/service_worker_object_host.h" |
| #include "content/browser/service_worker/service_worker_registration.h" |
| #include "content/common/content_export.h" |
| #include "content/common/service_worker/service_worker_types.h" |
| #include "content/public/common/resource_type.h" |
| #include "mojo/public/cpp/bindings/associated_binding.h" |
| #include "mojo/public/cpp/bindings/binding.h" |
| #include "mojo/public/cpp/bindings/binding_set.h" |
| #include "services/network/public/mojom/fetch_api.mojom.h" |
| #include "third_party/blink/public/mojom/fetch/fetch_api_request.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_provider.mojom.h" |
| #include "third_party/blink/public/mojom/service_worker/service_worker_provider_type.mojom.h" |
| #include "third_party/blink/public/mojom/service_worker/service_worker_registration.mojom.h" |
| #include "third_party/blink/public/mojom/web_feature/web_feature.mojom.h" |
| |
| namespace network { |
| class ResourceRequestBody; |
| } |
| |
| namespace service_worker_object_host_unittest { |
| class ServiceWorkerObjectHostTest; |
| } |
| |
| namespace content { |
| |
| class NavigationLoaderInterceptor; |
| class ServiceWorkerContextCore; |
| class ServiceWorkerRegistrationObjectHost; |
| class ServiceWorkerVersion; |
| class WebContents; |
| |
| // ServiceWorkerProviderHost is the browser-process representation of a |
| // renderer-process entity that can involve service workers. Currently, these |
| // entities are frames or workers. So basically, one ServiceWorkerProviderHost |
| // instance is the browser process's source of truth about one frame/worker in a |
| // renderer process, which the browser process uses when performing operations |
| // involving service workers. |
| // |
| // ServiceWorkerProviderHost lives on the IO thread, since all nearly all |
| // browser process service worker machinery lives on the IO thread. |
| // |
| // Example: |
| // * A new service worker registration is created. The browser process loops |
| // over all ServiceWorkerProviderHosts to find clients (frames and shared |
| // workers) with a URL inside the registration's scope, and has the provider |
| // host watch the registration in order to resolve navigator.serviceWorker.ready |
| // once the registration settles, if neeed. |
| // |
| // "Provider" is a somewhat tricky term. The idea is that a provider is what |
| // attaches to a frame/worker and "provides" it with functionality related to |
| // service workers. This functionality is mostly granted by creating the |
| // ServiceWorkerProviderHost for this frame/worker, which, again, makes the |
| // frame/worker alive in the browser's service worker world. |
| // |
| // A provider host has a Mojo connection to the provider in the renderer. |
| // Destruction of the host happens upon disconnection of the Mojo pipe. |
| // |
| // There are two general types of providers: |
| // 1) those for service worker clients (windows or shared workers), and |
| // 2) those for service workers themselves. |
| // |
| // For client providers, there is a provider (ServiceWorkerProviderContext) per |
| // frame or shared worker in the renderer process. The lifetime of this host |
| // object is tied to the lifetime of the document or the worker. |
| // |
| // For service worker providers, there is a provider |
| // (ServiceWorkerContextClient) per running service worker in the renderer |
| // process. The lifetime of this host object is tied to the lifetime of the |
| // running service worker. |
| // |
| // A ServiceWorkerProviderHost is created in the following situations: |
| // |
| // 1) For a client created for a navigation (for both top-level and |
| // non-top-level frames), the provider host for the resulting document is |
| // pre-created by the browser process and the provider info is sent in the |
| // navigation commit IPC. |
| // |
| // 2) For shared workers and for service workers, the provider host is |
| // pre-created by the browser process and the provider info is sent in the start |
| // worker IPC message. |
| class CONTENT_EXPORT ServiceWorkerProviderHost |
| : public ServiceWorkerRegistration::Listener, |
| public base::SupportsWeakPtr<ServiceWorkerProviderHost>, |
| public blink::mojom::ServiceWorkerContainerHost, |
| public service_manager::mojom::InterfaceProvider { |
| public: |
| using WebContentsGetter = base::RepeatingCallback<WebContents*()>; |
| using ExecutionReadyCallback = base::OnceClosure; |
| |
| // Used to pre-create a ServiceWorkerProviderHost for a navigation. The |
| // ServiceWorkerProviderContext will later be created in the renderer, should |
| // the navigation succeed. |are_ancestors_secure| should be true for main |
| // frames. Otherwise it is true iff all ancestor frames of this frame have a |
| // secure origin. |frame_tree_node_id| is FrameTreeNode |
| // id. |web_contents_getter| indicates the tab where the navigation is |
| // occurring. |
| // |
| // The returned host stays alive as long as the filled |out_provider_info| |
| // stays alive (namely, as long as |out_provider_info->host_ptr_info| stays |
| // alive). Upon navigation commit, OnBeginNavigationCommit() will complete |
| // initialization for it. |
| static base::WeakPtr<ServiceWorkerProviderHost> PreCreateNavigationHost( |
| base::WeakPtr<ServiceWorkerContextCore> context, |
| bool are_ancestors_secure, |
| int frame_tree_node_id, |
| blink::mojom::ServiceWorkerProviderInfoForWindowPtr* out_provider_info); |
| |
| // Used for starting a service worker. Returns a provider host for the service |
| // worker and partially fills |out_provider_info|. The host stays alive as |
| // long as this info stays alive (namely, as long as |
| // |out_provider_info->host_ptr_info| stays alive). |
| // CompleteStartWorkerPreparation() must be called later to get a full info to |
| // send to the renderer. |
| static base::WeakPtr<ServiceWorkerProviderHost> PreCreateForController( |
| base::WeakPtr<ServiceWorkerContextCore> context, |
| scoped_refptr<ServiceWorkerVersion> version, |
| blink::mojom::ServiceWorkerProviderInfoForStartWorkerPtr* |
| out_provider_info); |
| |
| // Used for starting a shared worker. Returns a provider host for the shared |
| // worker and fills |out_provider_info| with info to send to the renderer to |
| // connect to the host. The host stays alive as long as this info stays alive |
| // (namely, as long as |out_provider_info->host_ptr_info| stays alive). |
| static base::WeakPtr<ServiceWorkerProviderHost> PreCreateForSharedWorker( |
| base::WeakPtr<ServiceWorkerContextCore> context, |
| int process_id, |
| blink::mojom::ServiceWorkerProviderInfoForWorkerPtr* out_provider_info); |
| |
| ~ServiceWorkerProviderHost() override; |
| |
| const std::string& client_uuid() const { return client_uuid_; } |
| const base::UnguessableToken& fetch_request_window_id() const { |
| return fetch_request_window_id_; |
| } |
| base::TimeTicks create_time() const { return create_time_; } |
| int process_id() const { return render_process_id_; } |
| int provider_id() const { return provider_id_; } |
| int frame_id() const { return frame_id_; } |
| const WebContentsGetter& web_contents_getter() const { |
| return web_contents_getter_; |
| } |
| |
| bool is_parent_frame_secure() const { return is_parent_frame_secure_; } |
| |
| // Returns whether this provider host is secure enough to have a service |
| // worker controller. |
| // Analogous to Blink's Document::IsSecureContext. Because of how service |
| // worker intercepts main resource requests, this check must be done |
| // browser-side once the URL is known (see comments in |
| // ServiceWorkerNetworkProviderForFrame::Create). This function uses |
| // |url_| and |is_parent_frame_secure_| to determine context security, so they |
| // must be set properly before calling this function. |
| bool IsContextSecureForServiceWorker() const; |
| |
| // For service worker clients. Describes whether the client has a controller |
| // and if it has a fetch event handler. |
| blink::mojom::ControllerServiceWorkerMode GetControllerMode() const; |
| |
| // For service worker clients. Returns this client's controller. |
| ServiceWorkerVersion* controller() const; |
| |
| ServiceWorkerRegistration* controller_registration() const { |
| #if DCHECK_IS_ON() |
| CheckControllerConsistency(false); |
| #endif // DCHECK_IS_ON() |
| |
| return controller_registration_.get(); |
| } |
| |
| // For service worker execution contexts. The version of the service worker. |
| // This is nullptr when the worker is still starting up (until |
| // CompleteStartWorkerPreparation() is called). |
| ServiceWorkerVersion* running_hosted_version() const { |
| DCHECK(!running_hosted_version_ || |
| type_ == blink::mojom::ServiceWorkerProviderType::kForServiceWorker); |
| return running_hosted_version_.get(); |
| } |
| |
| // For service worker clients. Similar to EnsureControllerServiceWorker, but |
| // this returns a bound Mojo ptr which is supposed to be sent to clients. The |
| // controller ptr passed to the clients will be used to intercept requests |
| // from them. |
| // It is invalid to call this when controller_ is null. |
| // |
| // This method can be called in one of the following cases: |
| // |
| // - During navigation, right after a request handler for the main resource |
| // has found the matching registration and has started the worker. |
| // - When a controller is updated by UpdateController() (e.g. |
| // by OnSkippedWaiting() or SetControllerRegistration()). |
| // In some cases the controller worker may not be started yet. |
| // |
| // This may return nullptr if the controller service worker does not have a |
| // fetch handler, i.e. when the renderer does not need the controller ptr. |
| // |
| // WARNING: |
| // Unlike EnsureControllerServiceWorker, this method doesn't guarantee that |
| // the controller worker is running because this method can be called in some |
| // situations where the worker isn't running yet. When the returned ptr is |
| // stored somewhere and intended to use later, clients need to make sure |
| // that the worker is eventually started to use the ptr. |
| // Currently all the callsites do this, i.e. they start the worker before |
| // or after calling this, but there's no mechanism to prevent future breakage. |
| // TODO(crbug.com/827935): Figure out a way to prevent misuse of this method. |
| // TODO(crbug.com/827935): Make sure the connection error handler fires in |
| // ControllerServiceWorkerConnector (so that it can correctly call |
| // EnsureControllerServiceWorker later) if the worker gets killed before |
| // events are dispatched. |
| // |
| // TODO(kinuko): revisit this if we start to use the ControllerServiceWorker |
| // for posting messages. |
| blink::mojom::ControllerServiceWorkerPtr GetControllerServiceWorkerPtr(); |
| |
| // For service worker clients. Sets |url_| and |site_for_cookies_| and updates |
| // the client uuid if it's a cross-origin transition. |
| void UpdateUrls(const GURL& url, const GURL& site_for_cookies); |
| |
| // The URL of this context. For service worker clients, this is the document |
| // URL (for documents) or script URL (for workers). For service worker |
| // execution contexts, this is the script URL. |
| // |
| // For clients, url() may be empty if loading has not started, or our custom |
| // loading handler didn't see the load (because e.g. another handler did |
| // first, or the initial request URL was such that |
| // OriginCanAccessServiceWorkers returned false). |
| // |
| // The URL may also change on redirects during loading. Once |
| // is_response_committed() is true, the URL should no longer change. |
| const GURL& url() const; |
| |
| // The URL representing the first-party site for this context. See |
| // |network::ResourceRequest::site_for_cookies| for details. |
| // For service worker execution contexts, site_for_cookies() always |
| // returns the service worker script URL. |
| const GURL& site_for_cookies() const; |
| |
| blink::mojom::ServiceWorkerProviderType provider_type() const { |
| return type_; |
| } |
| bool IsProviderForServiceWorker() const; |
| bool IsProviderForClient() const; |
| // Can only be called when IsProviderForClient() is true. |
| blink::mojom::ServiceWorkerClientType client_type() const; |
| |
| // For service worker clients. Makes this client be controlled by |
| // |registration|'s active worker, or makes this client be not |
| // controlled if |registration| is null. If |notify_controllerchange| is true, |
| // instructs the renderer to dispatch a 'controllerchange' event. |
| void SetControllerRegistration( |
| scoped_refptr<ServiceWorkerRegistration> controller_registration, |
| bool notify_controllerchange); |
| |
| // For use by the ServiceWorkerControlleeRequestHandler to disallow a |
| // registration claiming this host while its main resource request is |
| // occurring. |
| // |
| // TODO(crbug.com/866353): This should be unneccessary: registration code |
| // already avoids claiming clients that are not execution ready. However |
| // there may be edge cases with shared workers (pre-NetS13nServiceWorker) and |
| // about:blank iframes, since |is_execution_ready()| is initialized true for |
| // them. Try to remove this after S13nServiceWorker. |
| void AllowSetControllerRegistration(bool allow) { |
| allow_set_controller_registration_ = allow; |
| } |
| bool IsSetControllerRegistrationAllowed() { |
| return allow_set_controller_registration_; |
| } |
| |
| // Returns an interceptor for a main resource request. May return nullptr if |
| // the request doesn't require interception. |
| std::unique_ptr<NavigationLoaderInterceptor> CreateLoaderInterceptor( |
| network::mojom::RequestMode request_mode, |
| network::mojom::CredentialsMode credentials_mode, |
| network::mojom::RedirectMode redirect_mode, |
| const std::string& integrity, |
| bool keepalive, |
| ResourceType resource_type, |
| blink::mojom::RequestContextType request_context_type, |
| scoped_refptr<network::ResourceRequestBody> body, |
| bool skip_service_worker); |
| |
| // Returns an object info representing |registration|. The object info holds a |
| // Mojo connection to the ServiceWorkerRegistrationObjectHost for the |
| // |registration| to ensure the host stays alive while the object info is |
| // alive. A new ServiceWorkerRegistrationObjectHost instance is created if one |
| // can not be found in |registration_object_hosts_|. |
| // |
| // NOTE: The registration object info should be sent over Mojo in the same |
| // task with calling this method. Otherwise, some Mojo calls to |
| // blink::mojom::ServiceWorkerRegistrationObject or |
| // blink::mojom::ServiceWorkerObject may happen before establishing the |
| // connections, and they'll end up with crashes. |
| blink::mojom::ServiceWorkerRegistrationObjectInfoPtr |
| CreateServiceWorkerRegistrationObjectInfo( |
| scoped_refptr<ServiceWorkerRegistration> registration); |
| |
| // Returns a ServiceWorkerObjectHost instance for |version| for this provider |
| // host. A new instance is created if one does not already exist. |
| // ServiceWorkerObjectHost will have an ownership of the |version|. |
| base::WeakPtr<ServiceWorkerObjectHost> GetOrCreateServiceWorkerObjectHost( |
| scoped_refptr<ServiceWorkerVersion> version); |
| |
| // Returns true if the context referred to by this host (i.e. |context_|) is |
| // still alive. |
| bool IsContextAlive(); |
| |
| // Dispatches message event to the document. |
| void PostMessageToClient(ServiceWorkerVersion* version, |
| blink::TransferableMessage message); |
| |
| // Notifies the client that its controller used a feature, for UseCounter |
| // purposes. This can only be called if IsProviderForClient() is true. |
| void CountFeature(blink::mojom::WebFeature feature); |
| |
| // |registration| claims the document to be controlled. |
| void ClaimedByRegistration( |
| scoped_refptr<ServiceWorkerRegistration> registration); |
| |
| // For service worker window clients. Called when the navigation is ready to |
| // commit in the browser process to complete the initialization for the |
| // pre-created instance. |
| void OnBeginNavigationCommit(int render_process_id, int render_frame_id); |
| |
| // For service worker execution contexts. Completes initialization of this |
| // provider host. It is called once a renderer process has been found to host |
| // the worker. |
| void CompleteStartWorkerPreparation( |
| int process_id, |
| service_manager::mojom::InterfaceProviderRequest |
| interface_provider_request); |
| |
| // Called when the shared worker main script resource has finished loading. |
| // After this is called, is_response_committed() and is_execution_ready() |
| // return true. |
| void CompleteSharedWorkerPreparation(); |
| |
| // For service worker clients. The host keeps track of all the prospective |
| // longest-matching registrations, in order to resolve .ready or respond to |
| // claim() attempts. |
| // |
| // This is subtle: it doesn't keep all registrations (e.g., from storage) in |
| // memory, but just the ones that are possibly the longest-matching one. The |
| // best match from storage is added at load time. That match can't uninstall |
| // while this host is a controllee, so all the other stored registrations can |
| // be ignored. Only a newly installed registration can claim it, and new |
| // installing registrations are added as matches. |
| void AddMatchingRegistration(ServiceWorkerRegistration* registration); |
| void RemoveMatchingRegistration(ServiceWorkerRegistration* registration); |
| |
| // An optimized implementation of [[Match Service Worker Registration]] |
| // for current document. |
| ServiceWorkerRegistration* MatchRegistration() const; |
| |
| // Removes the ServiceWorkerRegistrationObjectHost corresponding to |
| // |registration_id|. |
| void RemoveServiceWorkerRegistrationObjectHost(int64_t registration_id); |
| |
| // Removes the ServiceWorkerObjectHost corresponding to |version_id|. |
| void RemoveServiceWorkerObjectHost(int64_t version_id); |
| |
| // Calls ContentBrowserClient::AllowServiceWorker(). Returns true if content |
| // settings allows service workers to run at |scope|. If this provider is for |
| // a window client, the check involves the topmost frame url as well as |
| // |scope|, and may display tab-level UI. |
| // If non-empty, |script_url| is the script the service worker will run. |
| bool AllowServiceWorker(const GURL& scope, const GURL& script_url); |
| |
| // Called when our controller has been terminated and doomed due to an |
| // exceptional condition like it could no longer be read from the script |
| // cache. |
| void NotifyControllerLost(); |
| |
| // For service worker clients. Called when |version| is the active worker upon |
| // the main resource request for this client. Remembers |version| as needing |
| // a Soft Update. To avoid affecting page load performance, the update occurs |
| // when we get a HintToUpdateServiceWorker message from the renderer, or when |
| // |this| is destroyed before receiving that message. |
| // |
| // Corresponds to the Handle Fetch algorithm: |
| // "If request is a non-subresource request...invoke Soft Update algorithm |
| // with registration." |
| // https://w3c.github.io/ServiceWorker/#on-fetch-request-algorithm |
| // |
| // This can be called multiple times due to redirects during a main resource |
| // load. All service workers are updated. |
| void AddServiceWorkerToUpdate(scoped_refptr<ServiceWorkerVersion> version); |
| |
| // For service worker clients. |callback| is called when this client becomes |
| // execution ready or if it is destroyed first. |
| void AddExecutionReadyCallback(ExecutionReadyCallback callback); |
| |
| // For service worker clients. True if the response for the main resource load |
| // was committed to the renderer. When this is false, the client's URL may |
| // still change due to redirects. |
| bool is_response_committed() const; |
| |
| // For service worker clients. True if the client is execution ready and |
| // therefore can be exposed to JavaScript. Execution ready implies connected |
| // to renderer. |
| // https://html.spec.whatwg.org/multipage/webappapis.html#concept-environment-execution-ready-flag |
| bool is_execution_ready() const; |
| |
| private: |
| // For service worker clients. The flow is kInitial -> kResponseCommitted -> |
| // kExecutionReady. |
| // |
| // - kInitial: The initial phase. |
| // - kResponseCommitted: The response for the main resource has been |
| // committed to the renderer. This client's URL should no longer change. |
| // - kExecutionReady: This client can be exposed to JavaScript as a Client |
| // object. |
| enum class ClientPhase { kInitial, kResponseCommitted, kExecutionReady }; |
| |
| friend class LinkHeaderServiceWorkerTest; |
| friend class ServiceWorkerProviderHostTest; |
| friend class ServiceWorkerWriteToCacheJobTest; |
| friend class service_worker_controllee_request_handler_unittest:: |
| ServiceWorkerControlleeRequestHandlerTest; |
| friend class service_worker_object_host_unittest::ServiceWorkerObjectHostTest; |
| FRIEND_TEST_ALL_PREFIXES(ServiceWorkerWriteToCacheJobTest, Update_SameScript); |
| FRIEND_TEST_ALL_PREFIXES(ServiceWorkerWriteToCacheJobTest, |
| Update_SameSizeScript); |
| FRIEND_TEST_ALL_PREFIXES(ServiceWorkerWriteToCacheJobTest, |
| Update_TruncatedScript); |
| FRIEND_TEST_ALL_PREFIXES(ServiceWorkerWriteToCacheJobTest, |
| Update_ElongatedScript); |
| FRIEND_TEST_ALL_PREFIXES(ServiceWorkerWriteToCacheJobTest, |
| Update_EmptyScript); |
| FRIEND_TEST_ALL_PREFIXES(ServiceWorkerProviderHostTest, ContextSecurity); |
| FRIEND_TEST_ALL_PREFIXES(ServiceWorkerJobTest, Unregister); |
| FRIEND_TEST_ALL_PREFIXES(ServiceWorkerJobTest, RegisterDuplicateScript); |
| FRIEND_TEST_ALL_PREFIXES(ServiceWorkerUpdateJobTest, |
| RegisterWithDifferentUpdateViaCache); |
| FRIEND_TEST_ALL_PREFIXES(BackgroundSyncManagerTest, |
| RegisterWithoutLiveSWRegistration); |
| |
| static void RegisterToContextCore( |
| base::WeakPtr<ServiceWorkerContextCore> context, |
| std::unique_ptr<ServiceWorkerProviderHost> host); |
| |
| ServiceWorkerProviderHost( |
| blink::mojom::ServiceWorkerProviderType type, |
| bool is_parent_frame_secure, |
| int frame_tree_node_id, |
| blink::mojom::ServiceWorkerContainerHostAssociatedRequest host_request, |
| blink::mojom::ServiceWorkerContainerAssociatedPtrInfo client_ptr_info, |
| base::WeakPtr<ServiceWorkerContextCore> context); |
| |
| // ServiceWorkerRegistration::Listener overrides. |
| void OnVersionAttributesChanged( |
| ServiceWorkerRegistration* registration, |
| blink::mojom::ChangedServiceWorkerObjectsMaskPtr changed_mask, |
| const ServiceWorkerRegistrationInfo& info) override; |
| void OnRegistrationFailed(ServiceWorkerRegistration* registration) override; |
| void OnRegistrationFinishedUninstalling( |
| ServiceWorkerRegistration* registration) override; |
| void OnSkippedWaiting(ServiceWorkerRegistration* registration) override; |
| |
| // Sets the controller to |controller_registration_->active_version()| or null |
| // if there is no associated registration. |
| // |
| // If |notify_controllerchange| is true, instructs the renderer to dispatch a |
| // 'controller' change event. |
| void UpdateController(bool notify_controllerchange); |
| |
| // Syncs matching registrations with live registrations. |
| void SyncMatchingRegistrations(); |
| |
| #if DCHECK_IS_ON() |
| bool IsMatchingRegistration(ServiceWorkerRegistration* registration) const; |
| #endif // DCHECK_IS_ON() |
| |
| // Discards all references to matching registrations. |
| void RemoveAllMatchingRegistrations(); |
| |
| void ReturnRegistrationForReadyIfNeeded(); |
| |
| // Sends information about the controller to the providers of the service |
| // worker clients in the renderer. If |notify_controllerchange| is true, |
| // instructs the renderer to dispatch a 'controllerchange' event. |
| void SendSetControllerServiceWorker(bool notify_controllerchange); |
| |
| // For service worker clients. Returns false if it's not yet time to send the |
| // renderer information about the controller. Basically returns false if this |
| // client is still loading so due to potential redirects the initial |
| // controller has not yet been decided. |
| bool IsControllerDecided() const; |
| |
| #if DCHECK_IS_ON() |
| void CheckControllerConsistency(bool should_crash) const; |
| #endif // DCHECK_IS_ON() |
| |
| // Implements blink::mojom::ServiceWorkerContainerHost. |
| void Register(const GURL& script_url, |
| blink::mojom::ServiceWorkerRegistrationOptionsPtr options, |
| RegisterCallback callback) override; |
| void GetRegistration(const GURL& client_url, |
| GetRegistrationCallback callback) override; |
| void GetRegistrations(GetRegistrationsCallback callback) override; |
| void GetRegistrationForReady( |
| GetRegistrationForReadyCallback callback) override; |
| void EnsureControllerServiceWorker( |
| blink::mojom::ControllerServiceWorkerRequest controller_request, |
| blink::mojom::ControllerServiceWorkerPurpose purpose) override; |
| void CloneContainerHost(blink::mojom::ServiceWorkerContainerHostRequest |
| container_host_request) override; |
| void Ping(PingCallback callback) override; |
| void HintToUpdateServiceWorker() override; |
| void OnExecutionReady() override; |
| |
| // Callback for ServiceWorkerContextCore::RegisterServiceWorker(). |
| void RegistrationComplete(RegisterCallback callback, |
| int64_t trace_id, |
| mojo::ReportBadMessageCallback bad_message_callback, |
| blink::ServiceWorkerStatusCode status, |
| const std::string& status_message, |
| int64_t registration_id); |
| // Callback for ServiceWorkerStorage::FindRegistrationForDocument(). |
| void GetRegistrationComplete( |
| GetRegistrationCallback callback, |
| int64_t trace_id, |
| blink::ServiceWorkerStatusCode status, |
| scoped_refptr<ServiceWorkerRegistration> registration); |
| // Callback for ServiceWorkerStorage::GetRegistrationsForOrigin(). |
| void GetRegistrationsComplete( |
| GetRegistrationsCallback callback, |
| int64_t trace_id, |
| blink::ServiceWorkerStatusCode status, |
| const std::vector<scoped_refptr<ServiceWorkerRegistration>>& |
| registrations); |
| |
| // Callback for ServiceWorkerVersion::RunAfterStartWorker() |
| void StartControllerComplete( |
| blink::mojom::ControllerServiceWorkerRequest controller_request, |
| blink::ServiceWorkerStatusCode status); |
| |
| bool IsValidGetRegistrationMessage(const GURL& client_url, |
| std::string* out_error) const; |
| bool IsValidGetRegistrationsMessage(std::string* out_error) const; |
| bool IsValidGetRegistrationForReadyMessage(std::string* out_error) const; |
| |
| // service_manager::mojom::InterfaceProvider: |
| // For service worker execution contexts. |
| void GetInterface(const std::string& interface_name, |
| mojo::ScopedMessagePipeHandle interface_pipe) override; |
| |
| // Perform common checks that need to run before ContainerHost methods that |
| // come from a child process are handled. |
| // |scope| is checked if it is allowed to run a service worker. |
| // If non-empty, |script_url| is the script associated with the service |
| // worker. |
| // Returns true if all checks have passed. |
| // If anything looks wrong |callback| will run with an error |
| // message prefixed by |error_prefix| and |args|, and false is returned. |
| template <typename CallbackType, typename... Args> |
| bool CanServeContainerHostMethods(CallbackType* callback, |
| const GURL& scope, |
| const GURL& script_url, |
| const char* error_prefix, |
| Args... args); |
| |
| // Sets |execution_ready_| and runs execution ready callbacks. |
| void SetExecutionReady(); |
| |
| void RunExecutionReadyCallbacks(); |
| |
| void TransitionToClientPhase(ClientPhase new_phase); |
| |
| void SetRenderProcessId(int process_id); |
| |
| // Unique among all provider hosts. |
| const int provider_id_; |
| |
| const blink::mojom::ServiceWorkerProviderType type_; |
| |
| // A GUID that is web-exposed as FetchEvent.clientId. |
| std::string client_uuid_; |
| |
| // For window clients. A token used internally to identify this context in |
| // requests. Corresponds to the Fetch specification's concept of a request's |
| // associated window: https://fetch.spec.whatwg.org/#concept-request-window |
| // This gets reset on redirects, unlike |client_uuid_|. |
| // |
| // TODO(falken): Consider using this for |client_uuid_| as well. We can't |
| // right now because this gets reset on redirects, and potentially sites rely |
| // on the GUID format. |
| base::UnguessableToken fetch_request_window_id_; |
| |
| const base::TimeTicks create_time_; |
| int render_process_id_; |
| |
| // For service worker execution contexts, the id of the service worker thread |
| // or |kInvalidEmbeddedWorkerThreadId| before the service worker starts up. |
| // Otherwise, |kDocumentMainThreadId|. |
| int render_thread_id_; |
| |
| // The window's RenderFrame id, if this is a service worker window client. |
| // Otherwise, |MSG_ROUTING_NONE|. |
| int frame_id_; |
| |
| // |is_parent_frame_secure_| is false if the provider host is created for a |
| // document whose parent frame is not secure. This doesn't mean the document |
| // is necessarily an insecure context, because the document may have a URL |
| // whose scheme is granted an exception that allows bypassing the ancestor |
| // secure context check. If the provider is not created for a document, or the |
| // document does not have a parent frame, is_parent_frame_secure_| is true. |
| // TODO(leonhsl): make it be const, currently only some test code wants to |
| // change its value. |
| bool is_parent_frame_secure_; |
| |
| // FrameTreeNode id if this is a service worker window client. |
| // Otherwise, |FrameTreeNode::kFrameTreeNodeInvalidId|. |
| const int frame_tree_node_id_; |
| |
| // Only set when this object is pre-created for a navigation. It indicates the |
| // tab where the navigation occurs. Otherwise, a null callback. |
| const WebContentsGetter web_contents_getter_; |
| |
| // For service worker clients. See comments for the getter functions. |
| GURL url_; |
| GURL site_for_cookies_; |
| |
| // Keyed by registration scope URL length. |
| using ServiceWorkerRegistrationMap = |
| std::map<size_t, scoped_refptr<ServiceWorkerRegistration>>; |
| // Contains all living registrations whose scope this document's URL |
| // starts with, used for .ready and claim(). It is empty if |
| // IsContextSecureForServiceWorker() is false. See also |
| // AddMatchingRegistration(). |
| ServiceWorkerRegistrationMap matching_registrations_; |
| |
| // Contains all ServiceWorkerRegistrationObjectHost instances corresponding to |
| // the service worker registration JavaScript objects for the hosted execution |
| // context (service worker global scope or service worker client) in the |
| // renderer process. |
| std::map<int64_t /* registration_id */, |
| std::unique_ptr<ServiceWorkerRegistrationObjectHost>> |
| registration_object_hosts_; |
| |
| // Contains all ServiceWorkerObjectHost instances corresponding to |
| // the service worker JavaScript objects for the hosted execution |
| // context (service worker global scope or service worker client) in the |
| // renderer process. |
| std::map<int64_t /* version_id */, std::unique_ptr<ServiceWorkerObjectHost>> |
| service_worker_object_hosts_; |
| |
| // The ready() promise is only allowed to be created once. |
| // |get_ready_callback_| has three states: |
| // 1. |get_ready_callback_| is null when ready() has not yet been called. |
| // 2. |*get_ready_callback_| is a valid OnceCallback after ready() has been |
| // called and the callback has not yet been run. |
| // 3. |*get_ready_callback_| is a null OnceCallback after the callback has |
| // been run. |
| std::unique_ptr<GetRegistrationForReadyCallback> get_ready_callback_; |
| |
| // For service worker clients. The controller service worker (i.e., |
| // ServiceWorkerContainer#controller) and its registration. The controller is |
| // typically the same as the registration's active version, but during |
| // algorithms such as the update, skipWaiting(), and claim() steps, the active |
| // version and controller may temporarily differ. For example, to perform |
| // skipWaiting(), the registration's active version is updated first and then |
| // the provider host's controller is updated to match it. |
| scoped_refptr<ServiceWorkerVersion> controller_; |
| scoped_refptr<ServiceWorkerRegistration> controller_registration_; |
| bool allow_set_controller_registration_ = true; |
| |
| // For service worker execution contexts. The ServiceWorkerVersion of the |
| // service worker this is a provider for. |
| scoped_refptr<ServiceWorkerVersion> running_hosted_version_; |
| |
| base::WeakPtr<ServiceWorkerContextCore> context_; |
| |
| // |container_| is the Mojo endpoint to the renderer-side |
| // ServiceWorkerContainer that |this| is a ServiceWorkerContainerHost for. |
| blink::mojom::ServiceWorkerContainerAssociatedPtr container_; |
| // |binding_| is the Mojo binding that keeps the connection to the |
| // renderer-side counterpart (content::ServiceWorkerProviderContext). When the |
| // connection bound on |binding_| gets killed from the renderer side, or the |
| // bound |ServiceWorkerProviderInfoForStartWorker::host_ptr_info| is otherwise |
| // destroyed before being passed to the renderer, this |
| // content::ServiceWorkerProviderHost will be destroyed. |
| mojo::AssociatedBinding<blink::mojom::ServiceWorkerContainerHost> binding_; |
| |
| // Container host bindings other than the original |binding_|. These include |
| // bindings for container host pointers used from (dedicated or shared) worker |
| // threads, or from ServiceWorkerSubresourceLoaderFactory. |
| mojo::BindingSet<blink::mojom::ServiceWorkerContainerHost> |
| additional_bindings_; |
| |
| // For service worker execution contexts. |
| mojo::Binding<service_manager::mojom::InterfaceProvider> |
| interface_provider_binding_; |
| |
| // For service worker clients. |
| ClientPhase client_phase_ = ClientPhase::kInitial; |
| |
| // For service worker clients. Callbacks to run upon transition to |
| // kExecutionReady. |
| std::vector<ExecutionReadyCallback> execution_ready_callbacks_; |
| |
| // For service worker clients. The service workers in the chain of redirects |
| // during the main resource request for this client. These workers should be |
| // updated "soon". See AddServiceWorkerToUpdate() documentation. |
| class PendingUpdateVersion; |
| base::flat_set<PendingUpdateVersion> versions_to_update_; |
| |
| DISALLOW_COPY_AND_ASSIGN(ServiceWorkerProviderHost); |
| }; |
| |
| } // namespace content |
| |
| #endif // CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_PROVIDER_HOST_H_ |