1 // Copyright 2019 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_CONTAINER_HOST_H_ 6 #define CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_CONTAINER_HOST_H_ 7 8 #include <map> 9 #include <memory> 10 11 #include "base/memory/ref_counted.h" 12 #include "base/memory/weak_ptr.h" 13 #include "base/time/time.h" 14 #include "content/browser/frame_host/back_forward_cache_metrics.h" 15 #include "content/browser/service_worker/service_worker_registration.h" 16 #include "content/common/content_export.h" 17 #include "content/public/common/child_process_host.h" 18 #include "mojo/public/cpp/bindings/associated_remote.h" 19 #include "mojo/public/cpp/bindings/receiver_set.h" 20 #include "mojo/public/cpp/bindings/remote.h" 21 #include "net/cookies/site_for_cookies.h" 22 #include "third_party/blink/public/common/service_worker/service_worker_status_code.h" 23 #include "third_party/blink/public/mojom/service_worker/service_worker_client.mojom.h" 24 #include "third_party/blink/public/mojom/service_worker/service_worker_container.mojom.h" 25 #include "third_party/blink/public/mojom/service_worker/service_worker_container_type.mojom.h" 26 #include "third_party/blink/public/mojom/service_worker/service_worker_registration.mojom.h" 27 28 namespace network { 29 struct CrossOriginEmbedderPolicy; 30 } 31 32 namespace content { 33 34 namespace service_worker_object_host_unittest { 35 class ServiceWorkerObjectHostTest; 36 } 37 38 class ServiceWorkerContextCore; 39 class ServiceWorkerObjectHost; 40 class ServiceWorkerProviderHost; 41 class ServiceWorkerRegistrationObjectHost; 42 class ServiceWorkerVersion; 43 class WebContents; 44 struct ServiceWorkerRegistrationInfo; 45 46 // ServiceWorkerContainerHost is the host of a service worker client (a window, 47 // dedicated worker, or shared worker) or service worker execution context in 48 // the renderer process. 49 // 50 // Most of its functionality helps implement the web-exposed 51 // ServiceWorkerContainer interface (navigator.serviceWorker). The long-term 52 // goal is for it to be the host of ServiceWorkerContainer in the renderer, 53 // although currently only windows support ServiceWorkerContainers (see 54 // https://crbug.com/371690). 55 // 56 // ServiceWorkerContainerHost is also responsible for handling service worker 57 // related things in the execution context where the container lives. For 58 // example, the container host manages service worker (registration) JavaScript 59 // object hosts, delivers messages to/from the service worker, and dispatches 60 // events on the container. 61 // 62 // Ownership model and responsibilities of ServiceWorkerContainerHost are 63 // slightly different based on the type of the execution context that the 64 // container host serves: 65 // 66 // For service worker clients, ServiceWorkerContainerHost is owned by 67 // ServiceWorkerContextCore. The container host has a Mojo connection to the 68 // container in the renderer, and destruction of the container host happens upon 69 // disconnection of the Mojo pipe. 70 // 71 // For service worker clients, the container host works as a source of truth of 72 // a service worker client. 73 // 74 // Example: 75 // When a new service worker registration is created, the browser process 76 // iterates over all ServiceWorkerContainerHosts to find clients (frames, 77 // dedicated workers if PlzDedicatedWorker is enabled, and shared workers) with 78 // a URL inside the registration's scope, and has the container host watch the 79 // registration in order to resolve navigator.serviceWorker.ready once the 80 // registration settles, if need. 81 // 82 // For service worker execution contexts, ServiceWorkerContainerHost is owned 83 // by ServiceWorkerProviderHost, which in turn is owned by ServiceWorkerVersion. 84 // The container host and provider host are destructed when the service worker 85 // is stopped. 86 class CONTENT_EXPORT ServiceWorkerContainerHost final 87 : public blink::mojom::ServiceWorkerContainerHost, 88 public ServiceWorkerRegistration::Listener { 89 public: 90 using ExecutionReadyCallback = base::OnceClosure; 91 using WebContentsGetter = base::RepeatingCallback<WebContents*()>; 92 93 // Used to create a ServiceWorkerContainerHost for a window during a 94 // navigation. |are_ancestors_secure| should be true for main frames. 95 // Otherwise it is true iff all ancestor frames of this frame have a secure 96 // origin. |frame_tree_node_id| is FrameTreeNode id. |web_contents_getter| 97 // indicates the tab where the navigation is occurring. 98 static base::WeakPtr<ServiceWorkerContainerHost> CreateForWindow( 99 base::WeakPtr<ServiceWorkerContextCore> context, 100 bool are_ancestors_secure, 101 int frame_tree_node_id, 102 mojo::PendingAssociatedReceiver<blink::mojom::ServiceWorkerContainerHost> 103 host_receiver, 104 mojo::PendingAssociatedRemote<blink::mojom::ServiceWorkerContainer> 105 container_remote); 106 107 // Used for starting a web worker (dedicated worker or shared worker). Returns 108 // a container host for the worker. 109 static base::WeakPtr<ServiceWorkerContainerHost> CreateForWebWorker( 110 base::WeakPtr<ServiceWorkerContextCore> context, 111 int process_id, 112 blink::mojom::ServiceWorkerContainerType container_type, 113 mojo::PendingAssociatedReceiver<blink::mojom::ServiceWorkerContainerHost> 114 host_receiver, 115 mojo::PendingAssociatedRemote<blink::mojom::ServiceWorkerContainer> 116 container_remote); 117 118 ServiceWorkerContainerHost( 119 blink::mojom::ServiceWorkerContainerType type, 120 bool is_parent_frame_secure, 121 int frame_tree_node_id, 122 mojo::PendingAssociatedReceiver<blink::mojom::ServiceWorkerContainerHost> 123 host_receiver, 124 mojo::PendingAssociatedRemote<blink::mojom::ServiceWorkerContainer> 125 container_remote, 126 base::WeakPtr<ServiceWorkerContextCore> context); 127 ~ServiceWorkerContainerHost() override; 128 129 ServiceWorkerContainerHost(const ServiceWorkerContainerHost& other) = delete; 130 ServiceWorkerContainerHost& operator=( 131 const ServiceWorkerContainerHost& other) = delete; 132 ServiceWorkerContainerHost(ServiceWorkerContainerHost&& other) = delete; 133 ServiceWorkerContainerHost& operator=(ServiceWorkerContainerHost&& other) = 134 delete; 135 136 // Implements blink::mojom::ServiceWorkerContainerHost. 137 void Register(const GURL& script_url, 138 blink::mojom::ServiceWorkerRegistrationOptionsPtr options, 139 blink::mojom::FetchClientSettingsObjectPtr 140 outside_fetch_client_settings_object, 141 RegisterCallback callback) override; 142 void GetRegistration(const GURL& client_url, 143 GetRegistrationCallback callback) override; 144 void GetRegistrations(GetRegistrationsCallback callback) override; 145 void GetRegistrationForReady( 146 GetRegistrationForReadyCallback callback) override; 147 void EnsureControllerServiceWorker( 148 mojo::PendingReceiver<blink::mojom::ControllerServiceWorker> receiver, 149 blink::mojom::ControllerServiceWorkerPurpose purpose) override; 150 void CloneContainerHost( 151 mojo::PendingReceiver<blink::mojom::ServiceWorkerContainerHost> receiver) 152 override; 153 void HintToUpdateServiceWorker() override; 154 void EnsureFileAccess(const std::vector<base::FilePath>& file_paths, 155 EnsureFileAccessCallback callback) override; 156 void OnExecutionReady() override; 157 158 // ServiceWorkerRegistration::Listener overrides. 159 void OnVersionAttributesChanged( 160 ServiceWorkerRegistration* registration, 161 blink::mojom::ChangedServiceWorkerObjectsMaskPtr changed_mask, 162 const ServiceWorkerRegistrationInfo& info) override; 163 void OnRegistrationFailed(ServiceWorkerRegistration* registration) override; 164 void OnRegistrationFinishedUninstalling( 165 ServiceWorkerRegistration* registration) override; 166 void OnSkippedWaiting(ServiceWorkerRegistration* registration) override; 167 168 // For service worker clients. The host keeps track of all the prospective 169 // longest-matching registrations, in order to resolve .ready or respond to 170 // claim() attempts. 171 // 172 // This is subtle: it doesn't keep all registrations (e.g., from storage) in 173 // memory, but just the ones that are possibly the longest-matching one. The 174 // best match from storage is added at load time. That match can't uninstall 175 // while this host is a controllee, so all the other stored registrations can 176 // be ignored. Only a newly installed registration can claim it, and new 177 // installing registrations are added as matches. 178 void AddMatchingRegistration(ServiceWorkerRegistration* registration); 179 void RemoveMatchingRegistration(ServiceWorkerRegistration* registration); 180 181 // An optimized implementation of [[Match Service Worker Registration]] 182 // for the current client. 183 ServiceWorkerRegistration* MatchRegistration() const; 184 185 // For service worker clients. Called when |version| is the active worker upon 186 // the main resource request for this client. Remembers |version| as needing 187 // a Soft Update. To avoid affecting page load performance, the update occurs 188 // when we get a HintToUpdateServiceWorker message from the renderer, or when 189 // |this| is destroyed before receiving that message. 190 // 191 // Corresponds to the Handle Fetch algorithm: 192 // "If request is a non-subresource request...invoke Soft Update algorithm 193 // with registration." 194 // https://w3c.github.io/ServiceWorker/#on-fetch-request-algorithm 195 // 196 // This can be called multiple times due to redirects during a main resource 197 // load. All service workers are updated. 198 void AddServiceWorkerToUpdate(scoped_refptr<ServiceWorkerVersion> version); 199 200 // Dispatches message event to the client (document, dedicated worker when 201 // PlzDedicatedWorker is enabled, or shared worker). 202 void PostMessageToClient(ServiceWorkerVersion* version, 203 blink::TransferableMessage message); 204 205 // Notifies the client that its controller used a feature, for UseCounter 206 // purposes. This can only be called if IsContainerForClient() is true. 207 void CountFeature(blink::mojom::WebFeature feature); 208 209 // Sends information about the controller to the container of the service 210 // worker clients in the renderer. If |notify_controllerchange| is true, 211 // instructs the renderer to dispatch a 'controllerchange' event. 212 void SendSetControllerServiceWorker(bool notify_controllerchange); 213 214 // Called when this container host's controller has been terminated and doomed 215 // due to an exceptional condition like it could no longer be read from the 216 // script cache. 217 void NotifyControllerLost(); 218 219 // Returns an object info representing |registration|. The object info holds a 220 // Mojo connection to the ServiceWorkerRegistrationObjectHost for the 221 // |registration| to ensure the host stays alive while the object info is 222 // alive. A new ServiceWorkerRegistrationObjectHost instance is created if one 223 // can not be found in |registration_object_hosts_|. 224 // 225 // NOTE: The registration object info should be sent over Mojo in the same 226 // task with calling this method. Otherwise, some Mojo calls to 227 // blink::mojom::ServiceWorkerRegistrationObject or 228 // blink::mojom::ServiceWorkerObject may happen before establishing the 229 // connections, and they'll end up with crashes. 230 blink::mojom::ServiceWorkerRegistrationObjectInfoPtr 231 CreateServiceWorkerRegistrationObjectInfo( 232 scoped_refptr<ServiceWorkerRegistration> registration); 233 234 // Removes the ServiceWorkerRegistrationObjectHost corresponding to 235 // |registration_id|. 236 void RemoveServiceWorkerRegistrationObjectHost(int64_t registration_id); 237 238 // For service worker execution contexts. 239 // Returns an object info representing |self.serviceWorker|. The object 240 // info holds a Mojo connection to the ServiceWorkerObjectHost for the 241 // |serviceWorker| to ensure the host stays alive while the object info is 242 // alive. See documentation. 243 blink::mojom::ServiceWorkerObjectInfoPtr CreateServiceWorkerObjectInfoToSend( 244 scoped_refptr<ServiceWorkerVersion> version); 245 246 // Returns a ServiceWorkerObjectHost instance for |version| for this provider 247 // host. A new instance is created if one does not already exist. 248 // ServiceWorkerObjectHost will have an ownership of the |version|. 249 base::WeakPtr<ServiceWorkerObjectHost> GetOrCreateServiceWorkerObjectHost( 250 scoped_refptr<ServiceWorkerVersion> version); 251 252 // Removes the ServiceWorkerObjectHost corresponding to |version_id|. 253 void RemoveServiceWorkerObjectHost(int64_t version_id); 254 255 bool IsContainerForServiceWorker() const; 256 bool IsContainerForClient() const; 257 type()258 blink::mojom::ServiceWorkerContainerType type() const { return type_; } 259 260 // Can only be called when IsContainerForClient() is true. 261 blink::mojom::ServiceWorkerClientType client_type() const; 262 263 // For service worker window clients. Called when the navigation is ready to 264 // commit. Updates this host with information about the frame committed to. 265 // After this is called, is_response_committed() and is_execution_ready() 266 // return true. 267 void OnBeginNavigationCommit( 268 int container_process_id, 269 int container_frame_id, 270 const network::CrossOriginEmbedderPolicy& cross_origin_embedder_policy, 271 mojo::PendingRemote<network::mojom::CrossOriginEmbedderPolicyReporter> 272 coep_reporter); 273 274 // For service worker clients that are shared workers or dedicated workers. 275 // Called when the web worker main script resource has finished loading. 276 // Updates this host with information about the worker. 277 // After this is called, is_response_committed() and is_execution_ready() 278 // return true. 279 void CompleteWebWorkerPreparation( 280 const network::CrossOriginEmbedderPolicy& cross_origin_embedder_policy); 281 282 // Sets |url_|, |site_for_cookies_| and |top_frame_origin_|. For service 283 // worker clients, updates the client uuid if it's a cross-origin transition. 284 void UpdateUrls(const GURL& url, 285 const net::SiteForCookies& site_for_cookies, 286 const base::Optional<url::Origin>& top_frame_origin); 287 288 // For service worker clients. Makes this client be controlled by 289 // |registration|'s active worker, or makes this client be not 290 // controlled if |registration| is null. If |notify_controllerchange| is true, 291 // instructs the renderer to dispatch a 'controllerchange' event. 292 void SetControllerRegistration( 293 scoped_refptr<ServiceWorkerRegistration> controller_registration, 294 bool notify_controllerchange); 295 296 // For service worker clients. Similar to EnsureControllerServiceWorker, but 297 // this returns a bound Mojo ptr which is supposed to be sent to clients. The 298 // controller ptr passed to the clients will be used to intercept requests 299 // from them. 300 // It is invalid to call this when controller_ is null. 301 // 302 // This method can be called in one of the following cases: 303 // 304 // - During navigation, right after a request handler for the main resource 305 // has found the matching registration and has started the worker. 306 // - When a controller is updated by UpdateController() (e.g. 307 // by OnSkippedWaiting() or SetControllerRegistration()). 308 // In some cases the controller worker may not be started yet. 309 // 310 // This may return nullptr if the controller service worker does not have a 311 // fetch handler, i.e. when the renderer does not need the controller ptr. 312 // 313 // WARNING: 314 // Unlike EnsureControllerServiceWorker, this method doesn't guarantee that 315 // the controller worker is running because this method can be called in some 316 // situations where the worker isn't running yet. When the returned ptr is 317 // stored somewhere and intended to use later, clients need to make sure 318 // that the worker is eventually started to use the ptr. 319 // Currently all the callsites do this, i.e. they start the worker before 320 // or after calling this, but there's no mechanism to prevent future breakage. 321 // TODO(crbug.com/827935): Figure out a way to prevent misuse of this method. 322 // TODO(crbug.com/827935): Make sure the connection error handler fires in 323 // ControllerServiceWorkerConnector (so that it can correctly call 324 // EnsureControllerServiceWorker later) if the worker gets killed before 325 // events are dispatched. 326 // 327 // TODO(kinuko): revisit this if we start to use the ControllerServiceWorker 328 // for posting messages. 329 // TODO(hayato): Return PendingRemote, instead of Remote. Binding to Remote 330 // as late as possible is more idiomatic for new Mojo types. 331 mojo::Remote<blink::mojom::ControllerServiceWorker> 332 GetRemoteControllerServiceWorker(); 333 334 // |registration| claims the client (document, dedicated worker when 335 // PlzDedicatedWorker is enabled, or shared worker) to be controlled. 336 void ClaimedByRegistration( 337 scoped_refptr<ServiceWorkerRegistration> registration); 338 339 // The URL of this context. For service worker clients, this is the document 340 // URL (for documents) or script URL (for workers). For service worker 341 // execution contexts, this is the script URL. 342 // 343 // For clients, url() may be empty if loading has not started, or our custom 344 // loading handler didn't see the load (because e.g. another handler did 345 // first, or the initial request URL was such that 346 // OriginCanAccessServiceWorkers returned false). 347 // 348 // The URL may also change on redirects during loading. Once 349 // is_response_committed() is true, the URL should no longer change. url()350 const GURL& url() const { return url_; } 351 352 // Representing the first party for cookies, if any, for this context. See 353 // |URLRequest::site_for_cookies()| for details. 354 // For service worker execution contexts, site_for_cookies() always 355 // corresponds to the service worker script URL. site_for_cookies()356 const net::SiteForCookies& site_for_cookies() const { 357 return site_for_cookies_; 358 } 359 360 // The URL representing the first-party site for this context. 361 // For service worker execution contexts, top_frame_origin() always 362 // returns the origin of the service worker script URL. 363 // For shared worker it is the origin of the document that created the worker. 364 // For dedicated worker it is the top-frame origin of the document that owns 365 // the worker. top_frame_origin()366 base::Optional<url::Origin> top_frame_origin() const { 367 return top_frame_origin_; 368 } 369 370 // Calls ContentBrowserClient::AllowServiceWorker(). Returns true if content 371 // settings allows service workers to run at |scope|. If this container is for 372 // a window client, the check involves the topmost frame url as well as 373 // |scope|, and may display tab-level UI. 374 // If non-empty, |script_url| is the script the service worker will run. 375 bool AllowServiceWorker(const GURL& scope, const GURL& script_url); 376 377 // Returns whether this provider host is secure enough to have a service 378 // worker controller. 379 // Analogous to Blink's Document::IsSecureContext. Because of how service 380 // worker intercepts main resource requests, this check must be done 381 // browser-side once the URL is known (see comments in 382 // ServiceWorkerNetworkProviderForFrame::Create). This function uses 383 // |url_| and |is_parent_frame_secure_| to determine context security, so they 384 // must be set properly before calling this function. 385 bool IsContextSecureForServiceWorker() const; 386 387 // For service worker clients. True if the response for the main resource load 388 // was committed to the renderer. When this is false, the client's URL may 389 // still change due to redirects. 390 bool is_response_committed() const; 391 392 // For service worker clients. |callback| is called when this client becomes 393 // execution ready or if it is destroyed first. 394 void AddExecutionReadyCallback(ExecutionReadyCallback callback); 395 396 // For service worker clients. True if the client is execution ready and 397 // therefore can be exposed to JavaScript. Execution ready implies response 398 // committed. 399 // https://html.spec.whatwg.org/multipage/webappapis.html#concept-environment-execution-ready-flag 400 bool is_execution_ready() const; 401 fetch_request_window_id()402 const base::UnguessableToken& fetch_request_window_id() const { 403 return fetch_request_window_id_; 404 } 405 406 void SetContainerProcessId(int process_id); 407 create_time()408 base::TimeTicks create_time() const { return create_time_; } process_id()409 int process_id() const { return process_id_; } frame_id()410 int frame_id() const { return frame_id_; } frame_tree_node_id()411 int frame_tree_node_id() const { return frame_tree_node_id_; } 412 web_contents_getter()413 const WebContentsGetter& web_contents_getter() const { 414 return web_contents_getter_; 415 } 416 417 // For service worker clients. 418 const std::string& client_uuid() const; 419 420 // For service worker clients. Describes whether the client has a controller 421 // and if it has a fetch event handler. 422 blink::mojom::ControllerServiceWorkerMode GetControllerMode() const; 423 424 // For service worker clients. Returns this client's controller. 425 ServiceWorkerVersion* controller() const; 426 427 // For service worker clients. Returns this client's controller's 428 // registration. 429 ServiceWorkerRegistration* controller_registration() const; 430 431 // For service worker execution contexts. 432 void set_service_worker_host(ServiceWorkerProviderHost* service_worker_host); 433 ServiceWorkerProviderHost* service_worker_host(); 434 435 // BackForwardCache: 436 // For service worker clients that are windows. 437 bool IsInBackForwardCache() const; 438 void EvictFromBackForwardCache( 439 BackForwardCacheMetrics::NotRestoredReason reason); 440 // Called when this container host's frame goes into BackForwardCache. 441 void OnEnterBackForwardCache(); 442 // Called when a frame gets restored from BackForwardCache. Note that a 443 // BackForwardCached frame can be deleted while in the cache but in this case 444 // OnRestoreFromBackForwardCache will not be called. 445 void OnRestoreFromBackForwardCache(); 446 EnterBackForwardCacheForTesting()447 void EnterBackForwardCacheForTesting() { is_in_back_forward_cache_ = true; } LeaveBackForwardCacheForTesting()448 void LeaveBackForwardCacheForTesting() { is_in_back_forward_cache_ = false; } 449 450 base::WeakPtr<ServiceWorkerContainerHost> GetWeakPtr(); 451 452 private: 453 friend class ServiceWorkerProviderHostTest; 454 friend class service_worker_object_host_unittest::ServiceWorkerObjectHostTest; 455 FRIEND_TEST_ALL_PREFIXES(ServiceWorkerJobTest, Unregister); 456 FRIEND_TEST_ALL_PREFIXES(ServiceWorkerJobTest, RegisterDuplicateScript); 457 FRIEND_TEST_ALL_PREFIXES(ServiceWorkerUpdateJobTest, 458 RegisterWithDifferentUpdateViaCache); 459 FRIEND_TEST_ALL_PREFIXES(BackgroundSyncManagerTest, 460 RegisterWithoutLiveSWRegistration); 461 462 // Syncs matching registrations with live registrations. 463 void SyncMatchingRegistrations(); 464 465 #if DCHECK_IS_ON() 466 bool IsMatchingRegistration(ServiceWorkerRegistration* registration) const; 467 #endif // DCHECK_IS_ON() 468 469 // Discards all references to matching registrations. 470 void RemoveAllMatchingRegistrations(); 471 472 void ReturnRegistrationForReadyIfNeeded(); 473 474 // Sets |execution_ready_| and runs execution ready callbacks. 475 void SetExecutionReady(); 476 477 void RunExecutionReadyCallbacks(); 478 479 // For service worker clients. The flow is kInitial -> kResponseCommitted -> 480 // kExecutionReady. 481 // 482 // - kInitial: The initial phase. 483 // - kResponseCommitted: The response for the main resource has been 484 // committed to the renderer. This client's URL should no longer change. 485 // - kExecutionReady: This client can be exposed to JavaScript as a Client 486 // object. 487 enum class ClientPhase { kInitial, kResponseCommitted, kExecutionReady }; 488 void TransitionToClientPhase(ClientPhase new_phase); 489 490 // Sets the controller to |controller_registration_->active_version()| or null 491 // if there is no associated registration. 492 // 493 // If |notify_controllerchange| is true, instructs the renderer to dispatch a 494 // 'controller' change event. 495 void UpdateController(bool notify_controllerchange); 496 497 #if DCHECK_IS_ON() 498 void CheckControllerConsistency(bool should_crash) const; 499 #endif // DCHECK_IS_ON() 500 501 // Callback for ServiceWorkerVersion::RunAfterStartWorker() 502 void StartControllerComplete( 503 mojo::PendingReceiver<blink::mojom::ControllerServiceWorker> receiver, 504 blink::ServiceWorkerStatusCode status); 505 506 // Callback for ServiceWorkerContextCore::RegisterServiceWorker(). 507 void RegistrationComplete(const GURL& script_url, 508 const GURL& scope, 509 RegisterCallback callback, 510 int64_t trace_id, 511 mojo::ReportBadMessageCallback bad_message_callback, 512 blink::ServiceWorkerStatusCode status, 513 const std::string& status_message, 514 int64_t registration_id); 515 // Callback for ServiceWorkerRegistry::FindRegistrationForClientUrl(). 516 void GetRegistrationComplete( 517 GetRegistrationCallback callback, 518 int64_t trace_id, 519 blink::ServiceWorkerStatusCode status, 520 scoped_refptr<ServiceWorkerRegistration> registration); 521 // Callback for ServiceWorkerStorage::GetRegistrationsForOrigin(). 522 void GetRegistrationsComplete( 523 GetRegistrationsCallback callback, 524 int64_t trace_id, 525 blink::ServiceWorkerStatusCode status, 526 const std::vector<scoped_refptr<ServiceWorkerRegistration>>& 527 registrations); 528 529 bool IsValidGetRegistrationMessage(const GURL& client_url, 530 std::string* out_error) const; 531 bool IsValidGetRegistrationsMessage(std::string* out_error) const; 532 bool IsValidGetRegistrationForReadyMessage(std::string* out_error) const; 533 534 // Perform common checks that need to run before ContainerHost methods that 535 // come from a child process are handled. 536 // |scope| is checked if it is allowed to run a service worker. 537 // If non-empty, |script_url| is the script associated with the service 538 // worker. 539 // Returns true if all checks have passed. 540 // If anything looks wrong |callback| will run with an error 541 // message prefixed by |error_prefix| and |args|, and false is returned. 542 template <typename CallbackType, typename... Args> 543 bool CanServeContainerHostMethods(CallbackType* callback, 544 const GURL& scope, 545 const GURL& script_url, 546 const char* error_prefix, 547 Args... args); 548 549 const blink::mojom::ServiceWorkerContainerType type_; 550 551 // See comments for the getter functions. 552 GURL url_; 553 net::SiteForCookies site_for_cookies_; 554 base::Optional<url::Origin> top_frame_origin_; 555 556 // For window clients. A token used internally to identify this context in 557 // requests. Corresponds to the Fetch specification's concept of a request's 558 // associated window: https://fetch.spec.whatwg.org/#concept-request-window 559 // This gets reset on redirects, unlike |client_uuid_|. 560 // 561 // TODO(falken): Consider using this for |client_uuid_| as well. We can't 562 // right now because this gets reset on redirects, and potentially sites rely 563 // on the GUID format. 564 base::UnguessableToken fetch_request_window_id_; 565 566 // The time when the container host is created. 567 const base::TimeTicks create_time_; 568 569 // The identifier of the process where the container lives. 570 int process_id_ = ChildProcessHost::kInvalidUniqueID; 571 572 // The window's RenderFrame id, if this is a service worker window client. 573 // Otherwise, |MSG_ROUTING_NONE|. 574 int frame_id_ = MSG_ROUTING_NONE; 575 576 // |is_parent_frame_secure_| is false if the container host is created for a 577 // document whose parent frame is not secure. This doesn't mean the document 578 // is necessarily an insecure context, because the document may have a URL 579 // whose scheme is granted an exception that allows bypassing the ancestor 580 // secure context check. If the container is not created for a document, or 581 // the document does not have a parent frame, is_parent_frame_secure_| is 582 // true. 583 const bool is_parent_frame_secure_; 584 585 // FrameTreeNode id if this is a service worker window client. 586 // Otherwise, |FrameTreeNode::kFrameTreeNodeInvalidId|. 587 const int frame_tree_node_id_; 588 589 // Only set when this object is pre-created for a navigation. It indicates the 590 // tab where the navigation occurs. Otherwise, a null callback. 591 const WebContentsGetter web_contents_getter_; 592 593 // For service worker clients. A GUID that is web-exposed as 594 // FetchEvent.clientId. 595 std::string client_uuid_; 596 597 // For service worker clients. 598 ClientPhase client_phase_ = ClientPhase::kInitial; 599 600 // For service worker clients. The embedder policy of the client. Set on 601 // response commit. 602 base::Optional<network::CrossOriginEmbedderPolicy> 603 cross_origin_embedder_policy_; 604 // An endpoint connected to the COEP reporter. A clone of this connection is 605 // passed to the service worker. 606 mojo::Remote<network::mojom::CrossOriginEmbedderPolicyReporter> 607 coep_reporter_; 608 609 // TODO(yuzus): This bit will be unnecessary once ServiceWorkerContainerHost 610 // and RenderFrameHost have the same lifetime. 611 bool is_in_back_forward_cache_ = false; 612 613 // For service worker clients. Callbacks to run upon transition to 614 // kExecutionReady. 615 std::vector<ExecutionReadyCallback> execution_ready_callbacks_; 616 617 // The ready() promise is only allowed to be created once. 618 // |get_ready_callback_| has three states: 619 // 1. |get_ready_callback_| is null when ready() has not yet been called. 620 // 2. |*get_ready_callback_| is a valid OnceCallback after ready() has been 621 // called and the callback has not yet been run. 622 // 3. |*get_ready_callback_| is a null OnceCallback after the callback has 623 // been run. 624 std::unique_ptr<GetRegistrationForReadyCallback> get_ready_callback_; 625 626 // For service worker clients. The controller service worker (i.e., 627 // ServiceWorkerContainer#controller) and its registration. The controller is 628 // typically the same as the registration's active version, but during 629 // algorithms such as the update, skipWaiting(), and claim() steps, the active 630 // version and controller may temporarily differ. For example, to perform 631 // skipWaiting(), the registration's active version is updated first and then 632 // the container host's controller is updated to match it. 633 scoped_refptr<ServiceWorkerVersion> controller_; 634 scoped_refptr<ServiceWorkerRegistration> controller_registration_; 635 636 // Keyed by registration scope URL length. 637 using ServiceWorkerRegistrationMap = 638 std::map<size_t, scoped_refptr<ServiceWorkerRegistration>>; 639 // Contains all living registrations whose scope this client's URL starts 640 // with, used for .ready and claim(). It is empty if 641 // IsContextSecureForServiceWorker() is false. See also 642 // AddMatchingRegistration(). 643 ServiceWorkerRegistrationMap matching_registrations_; 644 645 // For service worker clients. The service workers in the chain of redirects 646 // during the main resource request for this client. These workers should be 647 // updated "soon". See AddServiceWorkerToUpdate() documentation. 648 class PendingUpdateVersion; 649 base::flat_set<PendingUpdateVersion> versions_to_update_; 650 651 // Contains all ServiceWorkerRegistrationObjectHost instances corresponding to 652 // the service worker registration JavaScript objects for the hosted execution 653 // context (service worker global scope or service worker client) in the 654 // renderer process. 655 std::map<int64_t /* registration_id */, 656 std::unique_ptr<ServiceWorkerRegistrationObjectHost>> 657 registration_object_hosts_; 658 659 // Contains all ServiceWorkerObjectHost instances corresponding to 660 // the service worker JavaScript objects for the hosted execution 661 // context (service worker global scope or service worker client) in the 662 // renderer process. 663 std::map<int64_t /* version_id */, std::unique_ptr<ServiceWorkerObjectHost>> 664 service_worker_object_hosts_; 665 666 // Mojo endpoint which will be be sent to the service worker just before 667 // the response is committed, where |cross_origin_embedder_policy_| is ready. 668 // We need to store this here because navigation code depends on having a 669 // mojo::Remote<ControllerServiceWorker> for making a SubresourceLoaderParams, 670 // which is created before the response header is ready. 671 mojo::PendingReceiver<blink::mojom::ControllerServiceWorker> 672 pending_controller_receiver_; 673 674 // |receiver_| keeps the connection to the renderer-side counterpart 675 // (content::ServiceWorkerProviderContext). When the connection bound on 676 // |receiver_| gets killed from the renderer side, or the bound 677 // |ServiceWorkerProviderInfoForStartWorker::host_remote| is otherwise 678 // destroyed before being passed to the renderer, this 679 // content::ServiceWorkerContainerHost will be destroyed. 680 mojo::AssociatedReceiver<blink::mojom::ServiceWorkerContainerHost> receiver_{ 681 this}; 682 683 // Container host receivers other than the original |receiver_|. These include 684 // receivers used from (dedicated or shared) worker threads, or from 685 // ServiceWorkerSubresourceLoaderFactory. 686 mojo::ReceiverSet<blink::mojom::ServiceWorkerContainerHost> 687 additional_receivers_; 688 689 // |container_| is the remote renderer-side ServiceWorkerContainer that |this| 690 // is hosting. 691 mojo::AssociatedRemote<blink::mojom::ServiceWorkerContainer> container_; 692 693 // For service worker execution contexts. This provider host owns |this|. 694 ServiceWorkerProviderHost* service_worker_host_ = nullptr; 695 696 base::WeakPtr<ServiceWorkerContextCore> context_; 697 698 base::WeakPtrFactory<ServiceWorkerContainerHost> weak_factory_{this}; 699 }; 700 701 } // namespace content 702 703 #endif // CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_CONTAINER_HOST_H_ 704