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