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