1 // Copyright 2017 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_RENDERER_LOADER_WEB_WORKER_FETCH_CONTEXT_IMPL_H_ 6 #define CONTENT_RENDERER_LOADER_WEB_WORKER_FETCH_CONTEXT_IMPL_H_ 7 8 #include <memory> 9 #include <string> 10 11 #include "base/synchronization/waitable_event.h" 12 #include "content/common/child_process.mojom.h" 13 #include "content/common/content_export.h" 14 #include "ipc/ipc_message.h" 15 #include "mojo/public/cpp/bindings/pending_receiver.h" 16 #include "mojo/public/cpp/bindings/pending_remote.h" 17 #include "mojo/public/cpp/bindings/receiver.h" 18 #include "mojo/public/cpp/bindings/remote.h" 19 #include "mojo/public/cpp/bindings/remote_set.h" 20 #include "mojo/public/cpp/bindings/shared_remote.h" 21 #include "services/network/public/cpp/shared_url_loader_factory.h" 22 #include "services/network/public/mojom/url_loader_factory.mojom-forward.h" 23 #include "third_party/blink/public/mojom/blob/blob_registry.mojom-forward.h" 24 #include "third_party/blink/public/mojom/renderer_preference_watcher.mojom.h" 25 #include "third_party/blink/public/mojom/renderer_preferences.mojom.h" 26 #include "third_party/blink/public/mojom/service_worker/service_worker_container.mojom.h" 27 #include "third_party/blink/public/mojom/service_worker/service_worker_object.mojom-forward.h" 28 #include "third_party/blink/public/mojom/service_worker/service_worker_provider.mojom.h" 29 #include "third_party/blink/public/mojom/timing/worker_timing_container.mojom-forward.h" 30 #include "third_party/blink/public/mojom/worker/subresource_loader_updater.mojom.h" 31 #include "third_party/blink/public/platform/web_string.h" 32 #include "third_party/blink/public/platform/web_worker_fetch_context.h" 33 #include "url/gurl.h" 34 35 namespace IPC { 36 class Message; 37 } // namespace IPC 38 39 namespace content { 40 41 class FrameRequestBlocker; 42 class ResourceDispatcher; 43 class ServiceWorkerProviderContext; 44 class ThreadSafeSender; 45 class URLLoaderThrottleProvider; 46 class WebSocketHandshakeThrottleProvider; 47 struct NavigationResponseOverrideParameters; 48 49 // This class is used for fetching resource requests from workers (dedicated 50 // worker and shared worker). This class is created on the main thread and 51 // passed to the worker thread. This class is not used for service workers. For 52 // service workers, ServiceWorkerFetchContextImpl class is used instead. 53 class CONTENT_EXPORT WebWorkerFetchContextImpl 54 : public blink::WebWorkerFetchContext, 55 public blink::mojom::SubresourceLoaderUpdater, 56 public blink::mojom::ServiceWorkerWorkerClient, 57 public blink::mojom::RendererPreferenceWatcher { 58 public: 59 // Creates a new fetch context for a worker. 60 // 61 // |provider_context| is used to set up information for using service workers. 62 // It can be null if the worker is not allowed to use service workers due to 63 // security reasons like sandboxed iframes, insecure origins etc. 64 // |pending_loader_factory| is used for regular loading by the worker. 65 // 66 // If the worker is controlled by a service worker, this class makes another 67 // loader factory which sends requests to the service worker, and passes 68 // |pending_fallback_factory| to that factory to use for network fallback. 69 // 70 // |pending_loader_factory| and |pending_fallback_factory| are different 71 // because |pending_loader_factory| can possibly include a default factory 72 // like AppCache, while |pending_fallback_factory| should not have such a 73 // default factory and instead go directly to network for http(s) requests. 74 // |pending_fallback_factory| might not be simply the direct network factory, 75 // because it might additionally support non-NetworkService schemes (e.g., 76 // chrome-extension://). 77 static scoped_refptr<WebWorkerFetchContextImpl> Create( 78 ServiceWorkerProviderContext* provider_context, 79 blink::mojom::RendererPreferences renderer_preferences, 80 mojo::PendingReceiver<blink::mojom::RendererPreferenceWatcher> 81 watcher_receiver, 82 std::unique_ptr<network::PendingSharedURLLoaderFactory> 83 pending_loader_factory, 84 std::unique_ptr<network::PendingSharedURLLoaderFactory> 85 pending_fallback_factory, 86 mojo::PendingReceiver<blink::mojom::SubresourceLoaderUpdater> 87 pending_subresource_loader_updater); 88 89 // Clones this fetch context for a nested worker. 90 // For non-PlzDedicatedWorker. This will be removed once PlzDedicatedWorker is 91 // enabled by default. 92 scoped_refptr<WebWorkerFetchContextImpl> CloneForNestedWorkerDeprecated( 93 scoped_refptr<base::SingleThreadTaskRunner> task_runner); 94 // For PlzDedicatedWorker. The cloned fetch context does not inherit some 95 // fields (e.g., ServiceWorkerProviderContext) from this fetch context, and 96 // instead that takes values passed from the browser process. 97 scoped_refptr<WebWorkerFetchContextImpl> CloneForNestedWorker( 98 ServiceWorkerProviderContext* service_worker_provider_context, 99 std::unique_ptr<network::PendingSharedURLLoaderFactory> 100 pending_loader_factory, 101 std::unique_ptr<network::PendingSharedURLLoaderFactory> 102 pending_fallback_factory, 103 mojo::PendingReceiver<blink::mojom::SubresourceLoaderUpdater> 104 pending_subresource_loader_updater, 105 scoped_refptr<base::SingleThreadTaskRunner> task_runner); 106 107 // blink::WebWorkerFetchContext implementation: 108 void SetTerminateSyncLoadEvent(base::WaitableEvent*) override; 109 void InitializeOnWorkerThread(blink::AcceptLanguagesWatcher*) override; 110 blink::WebURLLoaderFactory* GetURLLoaderFactory() override; 111 std::unique_ptr<blink::WebURLLoaderFactory> WrapURLLoaderFactory( 112 mojo::ScopedMessagePipeHandle url_loader_factory_handle) override; 113 std::unique_ptr<blink::CodeCacheLoader> CreateCodeCacheLoader() override; 114 void WillSendRequest(blink::WebURLRequest&) override; 115 blink::mojom::ControllerServiceWorkerMode GetControllerServiceWorkerMode() 116 const override; 117 void SetIsOnSubframe(bool) override; 118 bool IsOnSubframe() const override; 119 net::SiteForCookies SiteForCookies() const override; 120 base::Optional<blink::WebSecurityOrigin> TopFrameOrigin() const override; 121 void DidRunContentWithCertificateErrors() override; 122 void DidDisplayContentWithCertificateErrors() override; 123 void DidRunInsecureContent(const blink::WebSecurityOrigin&, 124 const blink::WebURL& insecure_url) override; 125 void SetSubresourceFilterBuilder( 126 std::unique_ptr<blink::WebDocumentSubresourceFilter::Builder>) override; 127 std::unique_ptr<blink::WebDocumentSubresourceFilter> TakeSubresourceFilter() 128 override; 129 std::unique_ptr<blink::WebSocketHandshakeThrottle> 130 CreateWebSocketHandshakeThrottle( 131 scoped_refptr<base::SingleThreadTaskRunner> task_runner) override; 132 mojo::ScopedMessagePipeHandle TakePendingWorkerTimingReceiver( 133 int request_id) override; 134 void SetIsOfflineMode(bool is_offline_mode) override; 135 136 // blink::mojom::ServiceWorkerWorkerClient implementation: 137 void OnControllerChanged(blink::mojom::ControllerServiceWorkerMode) override; 138 139 // Sets the controller service worker mode. 140 // - For dedicated workers (non-PlzDedicatedWorker), they depend on the 141 // controller of the ancestor frame (directly for non-nested workers, or 142 // indirectly via its parent worker for nested workers), and inherit its 143 // controller mode. 144 // - For dedicated workers (PlzDedicatedWorker) and shared workers, the 145 // controller mode is passed from the browser processw when starting the 146 // worker. 147 void set_controller_service_worker_mode( 148 blink::mojom::ControllerServiceWorkerMode mode); 149 150 // Sets properties associated with frames. 151 // - For dedicated workers, the property is copied from the ancestor frame 152 // (directly for non-nested workers, or indirectly via its parent worker for 153 // nested workers). 154 // - For shared workers, there is no parent frame, so the default value, or a 155 // value calculated in some way is set. 156 // 157 // TODO(nhiroki): Add more comments about security/privacy implications to 158 // each property, for example, site_for_cookies and top_frame_origin. 159 void set_ancestor_frame_id(int id); 160 void set_frame_request_blocker( 161 scoped_refptr<FrameRequestBlocker> frame_request_blocker); 162 void set_site_for_cookies(const net::SiteForCookies& site_for_cookies); 163 void set_top_frame_origin(const blink::WebSecurityOrigin& top_frame_origin); 164 165 // Sets whether the worker context is a secure context. 166 // https://w3c.github.io/webappsec-secure-contexts/ 167 void set_origin_url(const GURL& origin_url); 168 void set_client_id(const std::string& client_id); 169 170 // PlzWorker with off-the-main-thread worker script fetch: 171 // Sets the response for the worker main script loaded by the browser process. 172 void SetResponseOverrideForMainScript( 173 std::unique_ptr<NavigationResponseOverrideParameters> response_override); 174 175 using RewriteURLFunction = blink::WebURL (*)(const std::string&, bool); 176 static void InstallRewriteURLFunction(RewriteURLFunction rewrite_url); 177 178 blink::WebString GetAcceptLanguages() const override; 179 180 // Sets up |receiver| to receive resource performance timings for the given 181 // |request_id|. This receiver will be taken later by 182 // TakePendingWorkerTimingReceiver(). 183 void AddPendingWorkerTimingReceiver( 184 int request_id, 185 mojo::PendingReceiver<blink::mojom::WorkerTimingContainer> receiver); 186 187 private: 188 class Factory; 189 using WorkerTimingContainerReceiverMap = 190 std::map<int /* request_id */, 191 mojo::PendingReceiver<blink::mojom::WorkerTimingContainer>>; 192 193 // - |service_worker_client_receiver| receives OnControllerChanged() 194 // notifications. 195 // - |service_worker_worker_client_registry| is used to register new 196 // ServiceWorkerWorkerClients, which is needed when creating a 197 // nested worker. 198 // 199 // Regarding the rest of params, see the comments on Create(). 200 WebWorkerFetchContextImpl( 201 blink::mojom::RendererPreferences renderer_preferences, 202 mojo::PendingReceiver<blink::mojom::RendererPreferenceWatcher> 203 watcher_receiver, 204 mojo::PendingReceiver<blink::mojom::ServiceWorkerWorkerClient> 205 service_worker_client_receiver, 206 mojo::PendingRemote<blink::mojom::ServiceWorkerWorkerClientRegistry> 207 service_worker_worker_client_registry, 208 mojo::PendingRemote<blink::mojom::ServiceWorkerContainerHost> 209 service_worker_container_host, 210 std::unique_ptr<network::PendingSharedURLLoaderFactory> 211 pending_loader_factory, 212 std::unique_ptr<network::PendingSharedURLLoaderFactory> 213 pending_fallback_factory, 214 mojo::PendingReceiver<blink::mojom::SubresourceLoaderUpdater> 215 pending_subresource_loader_updater, 216 std::unique_ptr<URLLoaderThrottleProvider> throttle_provider, 217 std::unique_ptr<WebSocketHandshakeThrottleProvider> 218 websocket_handshake_throttle_provider, 219 ThreadSafeSender* thread_safe_sender, 220 mojo::SharedRemote<mojom::ChildProcessHost> process_host); 221 222 ~WebWorkerFetchContextImpl() override; 223 224 scoped_refptr<WebWorkerFetchContextImpl> CloneForNestedWorkerInternal( 225 mojo::PendingReceiver<blink::mojom::ServiceWorkerWorkerClient> 226 service_worker_client_receiver, 227 mojo::PendingRemote<blink::mojom::ServiceWorkerWorkerClientRegistry> 228 service_worker_worker_client_registry, 229 mojo::PendingRemote<blink::mojom::ServiceWorkerContainerHost> 230 service_worker_container_host, 231 std::unique_ptr<network::PendingSharedURLLoaderFactory> 232 pending_loader_factory, 233 std::unique_ptr<network::PendingSharedURLLoaderFactory> 234 pending_fallback_factory, 235 mojo::PendingReceiver<blink::mojom::SubresourceLoaderUpdater> 236 pending_subresource_loader_updater, 237 scoped_refptr<base::SingleThreadTaskRunner> task_runner); 238 239 bool Send(IPC::Message* message); 240 241 // Resets the service worker url loader factory of a URLLoaderFactoryImpl 242 // which was passed to Blink. The url loader factory is connected to the 243 // controller service worker. Sets nullptr if the worker context is not 244 // controlled by a service worker. 245 void ResetServiceWorkerURLLoaderFactory(); 246 247 // Implements blink::mojom::SubresourceLoaderUpdater. 248 void UpdateSubresourceLoaderFactories( 249 std::unique_ptr<blink::PendingURLLoaderFactoryBundle> 250 subresource_loader_factories) override; 251 252 // Implements blink::mojom::RendererPreferenceWatcher. 253 void NotifyUpdate(blink::mojom::RendererPreferencesPtr new_prefs) override; 254 255 // |receiver_| and |service_worker_worker_client_registry_| may be null if 256 // this context can't use service workers. See comments for Create(). 257 mojo::Receiver<blink::mojom::ServiceWorkerWorkerClient> receiver_{this}; 258 mojo::Remote<blink::mojom::ServiceWorkerWorkerClientRegistry> 259 service_worker_worker_client_registry_; 260 261 // Bound to |this| on the worker thread. 262 mojo::PendingReceiver<blink::mojom::ServiceWorkerWorkerClient> 263 service_worker_client_receiver_; 264 // Consumed on the worker thread to create 265 // |service_worker_worker_client_registry_|. 266 mojo::PendingRemote<blink::mojom::ServiceWorkerWorkerClientRegistry> 267 pending_service_worker_worker_client_registry_; 268 // Consumed on the worker thread to create |service_worker_container_host_|. 269 mojo::PendingRemote<blink::mojom::ServiceWorkerContainerHost> 270 pending_service_worker_container_host_; 271 // Consumed on the worker thread to create |loader_factory_|. 272 std::unique_ptr<network::PendingSharedURLLoaderFactory> 273 pending_loader_factory_; 274 // Consumed on the worker thread to create |fallback_factory_|. 275 std::unique_ptr<network::PendingSharedURLLoaderFactory> 276 pending_fallback_factory_; 277 278 blink::mojom::ControllerServiceWorkerMode controller_service_worker_mode_ = 279 blink::mojom::ControllerServiceWorkerMode::kNoController; 280 281 // Initialized on the worker thread when InitializeOnWorkerThread() is called. 282 // This can be null if the |provider_context| passed to Create() was null or 283 // already being destructed (see 284 // ServiceWorkerProviderContext::OnNetworkProviderDestroyed()). 285 mojo::Remote<blink::mojom::ServiceWorkerContainerHost> 286 service_worker_container_host_; 287 288 // The Client#id value of the shared worker or dedicated worker (since 289 // dedicated workers are not yet service worker clients, it is the parent 290 // document's id in that case). Passed to ControllerServiceWorkerConnector. 291 std::string client_id_; 292 293 // Initialized on the worker thread when InitializeOnWorkerThread() is called. 294 std::unique_ptr<ResourceDispatcher> resource_dispatcher_; 295 296 // Initialized on the worker thread when InitializeOnWorkerThread() is called. 297 // |loader_factory_| is used for regular loading by the worker. In 298 // If the worker is controlled by a service worker, it creates a 299 // ServiceWorkerSubresourceLoaderFactory instead. 300 scoped_refptr<network::SharedURLLoaderFactory> loader_factory_; 301 302 // Initialized on the worker thread when InitializeOnWorkerThread() is called. 303 // If the worker is controlled by a service worker, it passes this factory to 304 // ServiceWorkerSubresourceLoaderFactory to use for network fallback. 305 scoped_refptr<network::SharedURLLoaderFactory> fallback_factory_; 306 307 // Initialized on the worker thread when InitializeOnWorkerThread() is called. 308 // Used to reconnect to the Network Service after the Network Service crash. 309 // This is only used for dedicated workers when PlzDedicatedWorker is enabled. 310 // When PlzDedicatedWorker is disabled, the ancestor render frame updates the 311 // loaders via Host/TrackedChildURLLoaderFactoryBundle. For shared workers, 312 // the renderer process detects the crash, and terminates the worker instead 313 // of recovery. 314 mojo::PendingReceiver<blink::mojom::SubresourceLoaderUpdater> 315 pending_subresource_loader_updater_; 316 mojo::Receiver<blink::mojom::SubresourceLoaderUpdater> 317 subresource_loader_updater_{this}; 318 319 // Initialized on the worker thread when InitializeOnWorkerThread() is called. 320 scoped_refptr<base::RefCountedData<mojo::Remote<blink::mojom::BlobRegistry>>> 321 blob_registry_; 322 323 scoped_refptr<ThreadSafeSender> thread_safe_sender_; 324 std::unique_ptr<blink::WebDocumentSubresourceFilter::Builder> 325 subresource_filter_builder_; 326 // For dedicated workers, this is the ancestor frame (the parent frame for 327 // non-nested workers, the closest ancestor for nested workers). For shared 328 // workers, this is the shadow page. 329 bool is_on_sub_frame_ = false; 330 int ancestor_frame_id_ = MSG_ROUTING_NONE; 331 // Set to non-null if the ancestor frame has an associated RequestBlocker, 332 // which blocks requests from this worker too when the ancestor frame is 333 // blocked. 334 scoped_refptr<FrameRequestBlocker> frame_request_blocker_; 335 net::SiteForCookies site_for_cookies_; 336 base::Optional<url::Origin> top_frame_origin_; 337 GURL origin_url_; 338 339 blink::mojom::RendererPreferences renderer_preferences_; 340 341 // |preference_watcher_receiver_| and |child_preference_watchers_| are for 342 // keeping track of updates in the renderer preferences. 343 mojo::Receiver<blink::mojom::RendererPreferenceWatcher> 344 preference_watcher_receiver_{this}; 345 // Kept while staring up the worker thread. Valid until 346 // InitializeOnWorkerThread(). 347 mojo::PendingReceiver<blink::mojom::RendererPreferenceWatcher> 348 preference_watcher_pending_receiver_; 349 mojo::RemoteSet<blink::mojom::RendererPreferenceWatcher> 350 child_preference_watchers_; 351 352 // This is owned by ThreadedMessagingProxyBase on the main thread. 353 base::WaitableEvent* terminate_sync_load_event_ = nullptr; 354 355 // The blink::WebURLLoaderFactory which was created and passed to 356 // Blink by GetURLLoaderFactory(). 357 std::unique_ptr<Factory> web_loader_factory_; 358 359 std::unique_ptr<URLLoaderThrottleProvider> throttle_provider_; 360 std::unique_ptr<WebSocketHandshakeThrottleProvider> 361 websocket_handshake_throttle_provider_; 362 363 mojo::SharedRemote<mojom::ChildProcessHost> process_host_; 364 365 std::unique_ptr<NavigationResponseOverrideParameters> response_override_; 366 367 blink::AcceptLanguagesWatcher* accept_languages_watcher_ = nullptr; 368 369 // Contains pending receivers whose corresponding requests are still 370 // in-flight. The pending receivers are taken by 371 // TakePendingWorkerTimingReceiver() when the request is completed. 372 WorkerTimingContainerReceiverMap worker_timing_container_receivers_; 373 374 base::WeakPtrFactory<WebWorkerFetchContextImpl> weak_factory_{this}; 375 }; 376 377 } // namespace content 378 379 #endif // CONTENT_RENDERER_LOADER_WEB_WORKER_FETCH_CONTEXT_IMPL_H_ 380