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 #include "content/renderer/loader/web_worker_fetch_context_impl.h"
6 
7 #include <utility>
8 
9 #include "base/bind.h"
10 #include "base/single_thread_task_runner.h"
11 #include "base/task/post_task.h"
12 #include "base/task/thread_pool.h"
13 #include "base/threading/sequenced_task_runner_handle.h"
14 #include "content/child/child_thread_impl.h"
15 #include "content/child/thread_safe_sender.h"
16 #include "content/common/content_constants_internal.h"
17 #include "content/common/frame_messages.h"
18 #include "content/public/common/content_client.h"
19 #include "content/public/common/origin_util.h"
20 #include "content/public/common/service_names.mojom.h"
21 #include "content/public/renderer/content_renderer_client.h"
22 #include "content/public/renderer/url_loader_throttle_provider.h"
23 #include "content/public/renderer/websocket_handshake_throttle_provider.h"
24 #include "content/renderer/loader/child_url_loader_factory_bundle.h"
25 #include "content/renderer/loader/code_cache_loader_impl.h"
26 #include "content/renderer/loader/frame_request_blocker.h"
27 #include "content/renderer/loader/request_extra_data.h"
28 #include "content/renderer/loader/resource_dispatcher.h"
29 #include "content/renderer/loader/web_url_loader_impl.h"
30 #include "content/renderer/loader/web_url_request_util.h"
31 #include "content/renderer/service_worker/controller_service_worker_connector.h"
32 #include "content/renderer/service_worker/service_worker_provider_context.h"
33 #include "content/renderer/service_worker/service_worker_subresource_loader.h"
34 #include "services/network/public/cpp/wrapper_shared_url_loader_factory.h"
35 #include "third_party/blink/public/common/features.h"
36 #include "third_party/blink/public/mojom/service_worker/service_worker_object.mojom.h"
37 #include "third_party/blink/public/mojom/service_worker/service_worker_provider.mojom.h"
38 #include "third_party/blink/public/platform/web_security_origin.h"
39 
40 namespace content {
41 
42 WebWorkerFetchContextImpl::RewriteURLFunction g_rewrite_url = nullptr;
43 
44 namespace {
45 
46 // Runs on a background thread created in ResetServiceWorkerURLLoaderFactory().
CreateServiceWorkerSubresourceLoaderFactory(mojo::PendingRemote<blink::mojom::ServiceWorkerContainerHost> remote_container_host,const std::string & client_id,std::unique_ptr<network::PendingSharedURLLoaderFactory> fallback_factory,mojo::PendingReceiver<network::mojom::URLLoaderFactory> receiver,scoped_refptr<base::SequencedTaskRunner> task_runner,scoped_refptr<base::SequencedTaskRunner> worker_timing_callback_task_runner,base::RepeatingCallback<void (int,mojo::PendingReceiver<blink::mojom::WorkerTimingContainer>)> worker_timing_callback)47 void CreateServiceWorkerSubresourceLoaderFactory(
48     mojo::PendingRemote<blink::mojom::ServiceWorkerContainerHost>
49         remote_container_host,
50     const std::string& client_id,
51     std::unique_ptr<network::PendingSharedURLLoaderFactory> fallback_factory,
52     mojo::PendingReceiver<network::mojom::URLLoaderFactory> receiver,
53     scoped_refptr<base::SequencedTaskRunner> task_runner,
54     scoped_refptr<base::SequencedTaskRunner> worker_timing_callback_task_runner,
55     base::RepeatingCallback<
56         void(int, mojo::PendingReceiver<blink::mojom::WorkerTimingContainer>)>
57         worker_timing_callback) {
58   ServiceWorkerSubresourceLoaderFactory::Create(
59       base::MakeRefCounted<ControllerServiceWorkerConnector>(
60           std::move(remote_container_host),
61           mojo::NullRemote() /* remote_controller */, client_id),
62       network::SharedURLLoaderFactory::Create(std::move(fallback_factory)),
63       std::move(receiver), std::move(task_runner),
64       std::move(worker_timing_callback_task_runner),
65       std::move(worker_timing_callback));
66 }
67 
68 }  // namespace
69 
70 // static
InstallRewriteURLFunction(RewriteURLFunction rewrite_url)71 void WebWorkerFetchContextImpl::InstallRewriteURLFunction(
72     RewriteURLFunction rewrite_url) {
73   CHECK(!g_rewrite_url);
74   g_rewrite_url = rewrite_url;
75 }
76 
77 // An implementation of WebURLLoaderFactory that is aware of service workers. In
78 // the usual case, it creates a loader that uses |loader_factory_|. But if the
79 // worker fetch context is controlled by a service worker, it creates a loader
80 // that uses |service_worker_loader_factory_| for requests that should be
81 // intercepted by the service worker.
82 class WebWorkerFetchContextImpl::Factory : public blink::WebURLLoaderFactory {
83  public:
Factory(base::WeakPtr<ResourceDispatcher> resource_dispatcher,scoped_refptr<network::SharedURLLoaderFactory> loader_factory)84   Factory(base::WeakPtr<ResourceDispatcher> resource_dispatcher,
85           scoped_refptr<network::SharedURLLoaderFactory> loader_factory)
86       : resource_dispatcher_(std::move(resource_dispatcher)),
87         loader_factory_(std::move(loader_factory)) {}
88   ~Factory() override = default;
89 
CreateURLLoader(const blink::WebURLRequest & request,std::unique_ptr<blink::scheduler::WebResourceLoadingTaskRunnerHandle> task_runner_handle)90   std::unique_ptr<blink::WebURLLoader> CreateURLLoader(
91       const blink::WebURLRequest& request,
92       std::unique_ptr<blink::scheduler::WebResourceLoadingTaskRunnerHandle>
93           task_runner_handle) override {
94     DCHECK(task_runner_handle);
95     DCHECK(resource_dispatcher_);
96 
97     // KeepAlive is not yet supported in web workers.
98     mojo::PendingRemote<mojom::KeepAliveHandle> keep_alive_handle =
99         mojo::NullRemote();
100 
101     if (CanCreateServiceWorkerURLLoader(request)) {
102       // Create our own URLLoader to route the request to the controller service
103       // worker.
104       return std::make_unique<WebURLLoaderImpl>(
105           resource_dispatcher_.get(), std::move(task_runner_handle),
106           service_worker_loader_factory_, std::move(keep_alive_handle));
107     }
108 
109     return std::make_unique<WebURLLoaderImpl>(
110         resource_dispatcher_.get(), std::move(task_runner_handle),
111         loader_factory_, std::move(keep_alive_handle));
112   }
113 
SetServiceWorkerURLLoaderFactory(mojo::PendingRemote<network::mojom::URLLoaderFactory> service_worker_loader_factory)114   void SetServiceWorkerURLLoaderFactory(
115       mojo::PendingRemote<network::mojom::URLLoaderFactory>
116           service_worker_loader_factory) {
117     if (!service_worker_loader_factory) {
118       service_worker_loader_factory_ = nullptr;
119       return;
120     }
121     service_worker_loader_factory_ =
122         base::MakeRefCounted<network::WrapperSharedURLLoaderFactory>(
123             std::move(service_worker_loader_factory));
124   }
125 
GetWeakPtr()126   base::WeakPtr<Factory> GetWeakPtr() { return weak_ptr_factory_.GetWeakPtr(); }
127 
128  private:
CanCreateServiceWorkerURLLoader(const blink::WebURLRequest & request)129   bool CanCreateServiceWorkerURLLoader(const blink::WebURLRequest& request) {
130     // TODO(horo): Unify this code path with
131     // ServiceWorkerNetworkProviderForFrame::CreateURLLoader that is used
132     // for document cases.
133 
134     // We need the service worker loader factory populated in order to create
135     // our own URLLoader for subresource loading via a service worker.
136     if (!service_worker_loader_factory_)
137       return false;
138 
139     // If the URL is not http(s) or otherwise whitelisted, do not intercept the
140     // request. Schemes like 'blob' and 'file' are not eligible to be
141     // intercepted by service workers.
142     // TODO(falken): Let ServiceWorkerSubresourceLoaderFactory handle the
143     // request and move this check there (i.e., for such URLs, it should use
144     // its fallback factory).
145     if (!GURL(request.Url()).SchemeIsHTTPOrHTTPS() &&
146         !OriginCanAccessServiceWorkers(request.Url())) {
147       return false;
148     }
149 
150     // If GetSkipServiceWorker() returns true, no need to intercept the request.
151     if (request.GetSkipServiceWorker())
152       return false;
153 
154     return true;
155   }
156 
157   base::WeakPtr<ResourceDispatcher> resource_dispatcher_;
158   scoped_refptr<network::SharedURLLoaderFactory> loader_factory_;
159   scoped_refptr<network::SharedURLLoaderFactory> service_worker_loader_factory_;
160   base::WeakPtrFactory<Factory> weak_ptr_factory_{this};
161   DISALLOW_COPY_AND_ASSIGN(Factory);
162 };
163 
Create(ServiceWorkerProviderContext * provider_context,blink::mojom::RendererPreferences renderer_preferences,mojo::PendingReceiver<blink::mojom::RendererPreferenceWatcher> watcher_receiver,std::unique_ptr<network::PendingSharedURLLoaderFactory> pending_loader_factory,std::unique_ptr<network::PendingSharedURLLoaderFactory> pending_fallback_factory,mojo::PendingReceiver<blink::mojom::SubresourceLoaderUpdater> pending_subresource_loader_updater)164 scoped_refptr<WebWorkerFetchContextImpl> WebWorkerFetchContextImpl::Create(
165     ServiceWorkerProviderContext* provider_context,
166     blink::mojom::RendererPreferences renderer_preferences,
167     mojo::PendingReceiver<blink::mojom::RendererPreferenceWatcher>
168         watcher_receiver,
169     std::unique_ptr<network::PendingSharedURLLoaderFactory>
170         pending_loader_factory,
171     std::unique_ptr<network::PendingSharedURLLoaderFactory>
172         pending_fallback_factory,
173     mojo::PendingReceiver<blink::mojom::SubresourceLoaderUpdater>
174         pending_subresource_loader_updater) {
175   mojo::PendingReceiver<blink::mojom::ServiceWorkerWorkerClient>
176       service_worker_client_receiver;
177   mojo::PendingRemote<blink::mojom::ServiceWorkerWorkerClientRegistry>
178       service_worker_worker_client_registry;
179   mojo::PendingRemote<blink::mojom::ServiceWorkerContainerHost>
180       service_worker_container_host;
181 
182   // Some sandboxed iframes are not allowed to use service worker so don't have
183   // a real service worker provider, so the provider context is null.
184   if (provider_context) {
185     provider_context->CloneWorkerClientRegistry(
186         service_worker_worker_client_registry.InitWithNewPipeAndPassReceiver());
187 
188     mojo::PendingRemote<blink::mojom::ServiceWorkerWorkerClient> worker_client;
189     service_worker_client_receiver =
190         worker_client.InitWithNewPipeAndPassReceiver();
191     provider_context->RegisterWorkerClient(std::move(worker_client));
192 
193     service_worker_container_host =
194         provider_context->CloneRemoteContainerHost();
195   }
196 
197   scoped_refptr<WebWorkerFetchContextImpl> worker_fetch_context =
198       base::AdoptRef(new WebWorkerFetchContextImpl(
199           std::move(renderer_preferences), std::move(watcher_receiver),
200           std::move(service_worker_client_receiver),
201           std::move(service_worker_worker_client_registry),
202           std::move(service_worker_container_host),
203           std::move(pending_loader_factory),
204           std::move(pending_fallback_factory),
205           std::move(pending_subresource_loader_updater),
206           GetContentClient()->renderer()->CreateURLLoaderThrottleProvider(
207               URLLoaderThrottleProviderType::kWorker),
208           GetContentClient()
209               ->renderer()
210               ->CreateWebSocketHandshakeThrottleProvider(),
211           ChildThreadImpl::current()->thread_safe_sender(),
212           ChildThreadImpl::current()->child_process_host()));
213   if (provider_context) {
214     worker_fetch_context->set_controller_service_worker_mode(
215         provider_context->GetControllerServiceWorkerMode());
216     worker_fetch_context->set_client_id(provider_context->client_id());
217   } else {
218     worker_fetch_context->set_controller_service_worker_mode(
219         blink::mojom::ControllerServiceWorkerMode::kNoController);
220   }
221   return worker_fetch_context;
222 }
223 
WebWorkerFetchContextImpl(blink::mojom::RendererPreferences renderer_preferences,mojo::PendingReceiver<blink::mojom::RendererPreferenceWatcher> preference_watcher_receiver,mojo::PendingReceiver<blink::mojom::ServiceWorkerWorkerClient> service_worker_client_receiver,mojo::PendingRemote<blink::mojom::ServiceWorkerWorkerClientRegistry> pending_service_worker_worker_client_registry,mojo::PendingRemote<blink::mojom::ServiceWorkerContainerHost> service_worker_container_host,std::unique_ptr<network::PendingSharedURLLoaderFactory> pending_loader_factory,std::unique_ptr<network::PendingSharedURLLoaderFactory> pending_fallback_factory,mojo::PendingReceiver<blink::mojom::SubresourceLoaderUpdater> pending_subresource_loader_updater,std::unique_ptr<URLLoaderThrottleProvider> throttle_provider,std::unique_ptr<WebSocketHandshakeThrottleProvider> websocket_handshake_throttle_provider,ThreadSafeSender * thread_safe_sender,mojo::SharedRemote<mojom::ChildProcessHost> process_host)224 WebWorkerFetchContextImpl::WebWorkerFetchContextImpl(
225     blink::mojom::RendererPreferences renderer_preferences,
226     mojo::PendingReceiver<blink::mojom::RendererPreferenceWatcher>
227         preference_watcher_receiver,
228     mojo::PendingReceiver<blink::mojom::ServiceWorkerWorkerClient>
229         service_worker_client_receiver,
230     mojo::PendingRemote<blink::mojom::ServiceWorkerWorkerClientRegistry>
231         pending_service_worker_worker_client_registry,
232     mojo::PendingRemote<blink::mojom::ServiceWorkerContainerHost>
233         service_worker_container_host,
234     std::unique_ptr<network::PendingSharedURLLoaderFactory>
235         pending_loader_factory,
236     std::unique_ptr<network::PendingSharedURLLoaderFactory>
237         pending_fallback_factory,
238     mojo::PendingReceiver<blink::mojom::SubresourceLoaderUpdater>
239         pending_subresource_loader_updater,
240     std::unique_ptr<URLLoaderThrottleProvider> throttle_provider,
241     std::unique_ptr<WebSocketHandshakeThrottleProvider>
242         websocket_handshake_throttle_provider,
243     ThreadSafeSender* thread_safe_sender,
244     mojo::SharedRemote<mojom::ChildProcessHost> process_host)
245     : service_worker_client_receiver_(
246           std::move(service_worker_client_receiver)),
247       pending_service_worker_worker_client_registry_(
248           std::move(pending_service_worker_worker_client_registry)),
249       pending_service_worker_container_host_(
250           std::move(service_worker_container_host)),
251       pending_loader_factory_(std::move(pending_loader_factory)),
252       pending_fallback_factory_(std::move(pending_fallback_factory)),
253       pending_subresource_loader_updater_(
254           std::move(pending_subresource_loader_updater)),
255       thread_safe_sender_(thread_safe_sender),
256       renderer_preferences_(std::move(renderer_preferences)),
257       preference_watcher_pending_receiver_(
258           std::move(preference_watcher_receiver)),
259       throttle_provider_(std::move(throttle_provider)),
260       websocket_handshake_throttle_provider_(
261           std::move(websocket_handshake_throttle_provider)),
262       process_host_(std::move(process_host)) {}
263 
~WebWorkerFetchContextImpl()264 WebWorkerFetchContextImpl::~WebWorkerFetchContextImpl() {}
265 
SetTerminateSyncLoadEvent(base::WaitableEvent * terminate_sync_load_event)266 void WebWorkerFetchContextImpl::SetTerminateSyncLoadEvent(
267     base::WaitableEvent* terminate_sync_load_event) {
268   DCHECK(!terminate_sync_load_event_);
269   terminate_sync_load_event_ = terminate_sync_load_event;
270 }
271 
272 scoped_refptr<WebWorkerFetchContextImpl>
CloneForNestedWorkerDeprecated(scoped_refptr<base::SingleThreadTaskRunner> task_runner)273 WebWorkerFetchContextImpl::CloneForNestedWorkerDeprecated(
274     scoped_refptr<base::SingleThreadTaskRunner> task_runner) {
275   DCHECK(!base::FeatureList::IsEnabled(blink::features::kPlzDedicatedWorker));
276 
277   mojo::PendingReceiver<blink::mojom::ServiceWorkerWorkerClient>
278       service_worker_client_receiver;
279   mojo::PendingRemote<blink::mojom::ServiceWorkerWorkerClientRegistry>
280       service_worker_worker_client_registry;
281   if (service_worker_worker_client_registry_) {
282     mojo::PendingRemote<blink::mojom::ServiceWorkerWorkerClient>
283         service_worker_client;
284     service_worker_client_receiver =
285         service_worker_client.InitWithNewPipeAndPassReceiver();
286     service_worker_worker_client_registry_->RegisterWorkerClient(
287         std::move(service_worker_client));
288     service_worker_worker_client_registry_->CloneWorkerClientRegistry(
289         service_worker_worker_client_registry.InitWithNewPipeAndPassReceiver());
290   }
291 
292   mojo::PendingRemote<blink::mojom::ServiceWorkerContainerHost>
293       service_worker_container_host;
294   if (service_worker_container_host_) {
295     service_worker_container_host_->CloneContainerHost(
296         service_worker_container_host.InitWithNewPipeAndPassReceiver());
297   }
298 
299   // |pending_subresource_loader_updater| is not used for
300   // non-PlzDedicatedWorker.
301   scoped_refptr<WebWorkerFetchContextImpl> new_context =
302       CloneForNestedWorkerInternal(
303           std::move(service_worker_client_receiver),
304           std::move(service_worker_worker_client_registry),
305           std::move(service_worker_container_host), loader_factory_->Clone(),
306           fallback_factory_->Clone(),
307           /*pending_subresource_loader_updater=*/mojo::NullReceiver(),
308           std::move(task_runner));
309   new_context->controller_service_worker_mode_ =
310       controller_service_worker_mode_;
311 
312   return new_context;
313 }
314 
315 scoped_refptr<WebWorkerFetchContextImpl>
CloneForNestedWorker(ServiceWorkerProviderContext * service_worker_provider_context,std::unique_ptr<network::PendingSharedURLLoaderFactory> pending_loader_factory,std::unique_ptr<network::PendingSharedURLLoaderFactory> pending_fallback_factory,mojo::PendingReceiver<blink::mojom::SubresourceLoaderUpdater> pending_subresource_loader_updater,scoped_refptr<base::SingleThreadTaskRunner> task_runner)316 WebWorkerFetchContextImpl::CloneForNestedWorker(
317     ServiceWorkerProviderContext* service_worker_provider_context,
318     std::unique_ptr<network::PendingSharedURLLoaderFactory>
319         pending_loader_factory,
320     std::unique_ptr<network::PendingSharedURLLoaderFactory>
321         pending_fallback_factory,
322     mojo::PendingReceiver<blink::mojom::SubresourceLoaderUpdater>
323         pending_subresource_loader_updater,
324     scoped_refptr<base::SingleThreadTaskRunner> task_runner) {
325   DCHECK(base::FeatureList::IsEnabled(blink::features::kPlzDedicatedWorker));
326   DCHECK(pending_loader_factory);
327   DCHECK(pending_fallback_factory);
328   DCHECK(task_runner);
329 
330   if (!service_worker_provider_context) {
331     return CloneForNestedWorkerInternal(
332         /*service_worker_client_receiver=*/mojo::NullReceiver(),
333         /*service_worker_worker_client_registry=*/mojo::NullRemote(),
334         /*container_host=*/mojo::NullRemote(),
335         std::move(pending_loader_factory), std::move(pending_fallback_factory),
336         std::move(pending_subresource_loader_updater), std::move(task_runner));
337   }
338 
339   mojo::PendingRemote<blink::mojom::ServiceWorkerWorkerClientRegistry>
340       service_worker_worker_client_registry;
341   service_worker_provider_context->CloneWorkerClientRegistry(
342       service_worker_worker_client_registry.InitWithNewPipeAndPassReceiver());
343 
344   mojo::PendingRemote<blink::mojom::ServiceWorkerWorkerClient> worker_client;
345   mojo::PendingReceiver<blink::mojom::ServiceWorkerWorkerClient>
346       service_worker_client_receiver =
347           worker_client.InitWithNewPipeAndPassReceiver();
348   service_worker_provider_context->RegisterWorkerClient(
349       std::move(worker_client));
350 
351   mojo::PendingRemote<blink::mojom::ServiceWorkerContainerHost>
352       service_worker_container_host =
353           service_worker_provider_context->CloneRemoteContainerHost();
354 
355   scoped_refptr<WebWorkerFetchContextImpl> new_context =
356       CloneForNestedWorkerInternal(
357           std::move(service_worker_client_receiver),
358           std::move(service_worker_worker_client_registry),
359           std::move(service_worker_container_host),
360           std::move(pending_loader_factory),
361           std::move(pending_fallback_factory),
362           std::move(pending_subresource_loader_updater),
363           std::move(task_runner));
364   new_context->controller_service_worker_mode_ =
365       service_worker_provider_context->GetControllerServiceWorkerMode();
366 
367   return new_context;
368 }
369 
InitializeOnWorkerThread(blink::AcceptLanguagesWatcher * watcher)370 void WebWorkerFetchContextImpl::InitializeOnWorkerThread(
371     blink::AcceptLanguagesWatcher* watcher) {
372   DCHECK(!resource_dispatcher_);
373   DCHECK(!receiver_.is_bound());
374   DCHECK(!preference_watcher_receiver_.is_bound());
375   resource_dispatcher_ = std::make_unique<ResourceDispatcher>();
376   resource_dispatcher_->set_terminate_sync_load_event(
377       terminate_sync_load_event_);
378 
379   loader_factory_ = network::SharedURLLoaderFactory::Create(
380       std::move(pending_loader_factory_));
381   fallback_factory_ = network::SharedURLLoaderFactory::Create(
382       std::move(pending_fallback_factory_));
383   subresource_loader_updater_.Bind(
384       std::move(pending_subresource_loader_updater_));
385 
386   if (service_worker_client_receiver_.is_valid())
387     receiver_.Bind(std::move(service_worker_client_receiver_));
388 
389   if (pending_service_worker_worker_client_registry_) {
390     service_worker_worker_client_registry_.Bind(
391         std::move(pending_service_worker_worker_client_registry_));
392   }
393 
394   if (preference_watcher_pending_receiver_.is_valid()) {
395     preference_watcher_receiver_.Bind(
396         std::move(preference_watcher_pending_receiver_));
397   }
398 
399   if (pending_service_worker_container_host_) {
400     service_worker_container_host_.Bind(
401         std::move(pending_service_worker_container_host_));
402   }
403 
404   mojo::Remote<blink::mojom::BlobRegistry> blob_registry_remote;
405   process_host_->BindHostReceiver(
406       blob_registry_remote.BindNewPipeAndPassReceiver());
407   blob_registry_ = base::MakeRefCounted<
408       base::RefCountedData<mojo::Remote<blink::mojom::BlobRegistry>>>(
409       std::move(blob_registry_remote));
410 
411   accept_languages_watcher_ = watcher;
412 
413   DCHECK(loader_factory_);
414   DCHECK(!web_loader_factory_);
415   web_loader_factory_ = std::make_unique<Factory>(
416       resource_dispatcher_->GetWeakPtr(), loader_factory_);
417 
418   ResetServiceWorkerURLLoaderFactory();
419 }
420 
GetURLLoaderFactory()421 blink::WebURLLoaderFactory* WebWorkerFetchContextImpl::GetURLLoaderFactory() {
422   return web_loader_factory_.get();
423 }
424 
425 std::unique_ptr<blink::WebURLLoaderFactory>
WrapURLLoaderFactory(mojo::ScopedMessagePipeHandle url_loader_factory_handle)426 WebWorkerFetchContextImpl::WrapURLLoaderFactory(
427     mojo::ScopedMessagePipeHandle url_loader_factory_handle) {
428   return std::make_unique<WebURLLoaderFactoryImpl>(
429       resource_dispatcher_->GetWeakPtr(),
430       base::MakeRefCounted<network::WrapperSharedURLLoaderFactory>(
431           mojo::PendingRemote<network::mojom::URLLoaderFactory>(
432               std::move(url_loader_factory_handle),
433               network::mojom::URLLoaderFactory::Version_)));
434 }
435 
436 std::unique_ptr<blink::CodeCacheLoader>
CreateCodeCacheLoader()437 WebWorkerFetchContextImpl::CreateCodeCacheLoader() {
438   return std::make_unique<CodeCacheLoaderImpl>(terminate_sync_load_event_);
439 }
440 
WillSendRequest(blink::WebURLRequest & request)441 void WebWorkerFetchContextImpl::WillSendRequest(blink::WebURLRequest& request) {
442   if (renderer_preferences_.enable_do_not_track) {
443     request.SetHttpHeaderField(blink::WebString::FromUTF8(kDoNotTrackHeader),
444                                "1");
445   }
446 
447   auto extra_data = base::MakeRefCounted<RequestExtraData>();
448   extra_data->set_render_frame_id(ancestor_frame_id_);
449   extra_data->set_frame_request_blocker(frame_request_blocker_);
450   if (throttle_provider_) {
451     extra_data->set_url_loader_throttles(
452         throttle_provider_->CreateThrottles(ancestor_frame_id_, request));
453   }
454   if (response_override_) {
455     using RequestContextType = blink::mojom::RequestContextType;
456     DCHECK(
457         (base::FeatureList::IsEnabled(blink::features::kPlzDedicatedWorker) &&
458          request.GetRequestContext() == RequestContextType::WORKER) ||
459         request.GetRequestContext() == RequestContextType::SHARED_WORKER)
460         << request.GetRequestContext();
461     extra_data->set_navigation_response_override(std::move(response_override_));
462   }
463   request.SetExtraData(std::move(extra_data));
464 
465   if (g_rewrite_url)
466     request.SetUrl(g_rewrite_url(request.Url().GetString().Utf8(), false));
467 
468   if (!renderer_preferences_.enable_referrers) {
469     request.SetReferrerString(blink::WebString());
470     request.SetReferrerPolicy(network::mojom::ReferrerPolicy::kNever);
471   }
472 }
473 
474 blink::mojom::ControllerServiceWorkerMode
GetControllerServiceWorkerMode() const475 WebWorkerFetchContextImpl::GetControllerServiceWorkerMode() const {
476   return controller_service_worker_mode_;
477 }
478 
SetIsOnSubframe(bool is_on_sub_frame)479 void WebWorkerFetchContextImpl::SetIsOnSubframe(bool is_on_sub_frame) {
480   is_on_sub_frame_ = is_on_sub_frame;
481 }
482 
IsOnSubframe() const483 bool WebWorkerFetchContextImpl::IsOnSubframe() const {
484   return is_on_sub_frame_;
485 }
486 
SiteForCookies() const487 net::SiteForCookies WebWorkerFetchContextImpl::SiteForCookies() const {
488   return site_for_cookies_;
489 }
490 
491 base::Optional<blink::WebSecurityOrigin>
TopFrameOrigin() const492 WebWorkerFetchContextImpl::TopFrameOrigin() const {
493   // TODO(jkarlin): set_top_frame_origin is only called for dedicated workers.
494   // Determine the top-frame-origin of a shared worker as well. See
495   // https://crbug.com/918868.
496   return top_frame_origin_;
497 }
498 
DidRunContentWithCertificateErrors()499 void WebWorkerFetchContextImpl::DidRunContentWithCertificateErrors() {
500   Send(new FrameHostMsg_DidRunContentWithCertificateErrors(ancestor_frame_id_));
501 }
502 
DidDisplayContentWithCertificateErrors()503 void WebWorkerFetchContextImpl::DidDisplayContentWithCertificateErrors() {
504   Send(new FrameHostMsg_DidDisplayContentWithCertificateErrors(
505       ancestor_frame_id_));
506 }
507 
DidRunInsecureContent(const blink::WebSecurityOrigin & origin,const blink::WebURL & url)508 void WebWorkerFetchContextImpl::DidRunInsecureContent(
509     const blink::WebSecurityOrigin& origin,
510     const blink::WebURL& url) {
511   Send(new FrameHostMsg_DidRunInsecureContent(
512       ancestor_frame_id_, GURL(origin.ToString().Utf8()), url));
513 }
514 
SetSubresourceFilterBuilder(std::unique_ptr<blink::WebDocumentSubresourceFilter::Builder> subresource_filter_builder)515 void WebWorkerFetchContextImpl::SetSubresourceFilterBuilder(
516     std::unique_ptr<blink::WebDocumentSubresourceFilter::Builder>
517         subresource_filter_builder) {
518   subresource_filter_builder_ = std::move(subresource_filter_builder);
519 }
520 
521 std::unique_ptr<blink::WebDocumentSubresourceFilter>
TakeSubresourceFilter()522 WebWorkerFetchContextImpl::TakeSubresourceFilter() {
523   if (!subresource_filter_builder_)
524     return nullptr;
525   return std::move(subresource_filter_builder_)->Build();
526 }
527 
528 std::unique_ptr<blink::WebSocketHandshakeThrottle>
CreateWebSocketHandshakeThrottle(scoped_refptr<base::SingleThreadTaskRunner> task_runner)529 WebWorkerFetchContextImpl::CreateWebSocketHandshakeThrottle(
530     scoped_refptr<base::SingleThreadTaskRunner> task_runner) {
531   if (!websocket_handshake_throttle_provider_)
532     return nullptr;
533   return websocket_handshake_throttle_provider_->CreateThrottle(
534       ancestor_frame_id_, std::move(task_runner));
535 }
536 
537 mojo::ScopedMessagePipeHandle
TakePendingWorkerTimingReceiver(int request_id)538 WebWorkerFetchContextImpl::TakePendingWorkerTimingReceiver(int request_id) {
539   auto iter = worker_timing_container_receivers_.find(request_id);
540   if (iter == worker_timing_container_receivers_.end()) {
541     return {};
542   }
543   auto receiver = std::move(iter->second);
544   worker_timing_container_receivers_.erase(iter);
545   return receiver.PassPipe();
546 }
547 
SetIsOfflineMode(bool is_offline_mode)548 void WebWorkerFetchContextImpl::SetIsOfflineMode(bool is_offline_mode) {
549   // Worker doesn't support offline mode. There should be no callers.
550   NOTREACHED();
551 }
552 
set_controller_service_worker_mode(blink::mojom::ControllerServiceWorkerMode mode)553 void WebWorkerFetchContextImpl::set_controller_service_worker_mode(
554     blink::mojom::ControllerServiceWorkerMode mode) {
555   controller_service_worker_mode_ = mode;
556 }
557 
set_ancestor_frame_id(int id)558 void WebWorkerFetchContextImpl::set_ancestor_frame_id(int id) {
559   ancestor_frame_id_ = id;
560 }
561 
set_frame_request_blocker(scoped_refptr<FrameRequestBlocker> frame_request_blocker)562 void WebWorkerFetchContextImpl::set_frame_request_blocker(
563     scoped_refptr<FrameRequestBlocker> frame_request_blocker) {
564   frame_request_blocker_ = frame_request_blocker;
565 }
566 
set_site_for_cookies(const net::SiteForCookies & site_for_cookies)567 void WebWorkerFetchContextImpl::set_site_for_cookies(
568     const net::SiteForCookies& site_for_cookies) {
569   site_for_cookies_ = site_for_cookies;
570 }
571 
set_top_frame_origin(const blink::WebSecurityOrigin & top_frame_origin)572 void WebWorkerFetchContextImpl::set_top_frame_origin(
573     const blink::WebSecurityOrigin& top_frame_origin) {
574   top_frame_origin_ = top_frame_origin;
575 }
576 
set_origin_url(const GURL & origin_url)577 void WebWorkerFetchContextImpl::set_origin_url(const GURL& origin_url) {
578   origin_url_ = origin_url;
579 }
580 
set_client_id(const std::string & client_id)581 void WebWorkerFetchContextImpl::set_client_id(const std::string& client_id) {
582   client_id_ = client_id;
583 }
584 
SetResponseOverrideForMainScript(std::unique_ptr<NavigationResponseOverrideParameters> response_override)585 void WebWorkerFetchContextImpl::SetResponseOverrideForMainScript(
586     std::unique_ptr<NavigationResponseOverrideParameters> response_override) {
587   DCHECK(!response_override_);
588   response_override_ = std::move(response_override);
589 }
590 
OnControllerChanged(blink::mojom::ControllerServiceWorkerMode mode)591 void WebWorkerFetchContextImpl::OnControllerChanged(
592     blink::mojom::ControllerServiceWorkerMode mode) {
593   set_controller_service_worker_mode(mode);
594   ResetServiceWorkerURLLoaderFactory();
595 }
596 
597 scoped_refptr<WebWorkerFetchContextImpl>
CloneForNestedWorkerInternal(mojo::PendingReceiver<blink::mojom::ServiceWorkerWorkerClient> service_worker_client_receiver,mojo::PendingRemote<blink::mojom::ServiceWorkerWorkerClientRegistry> service_worker_worker_client_registry,mojo::PendingRemote<blink::mojom::ServiceWorkerContainerHost> service_worker_container_host,std::unique_ptr<network::PendingSharedURLLoaderFactory> pending_loader_factory,std::unique_ptr<network::PendingSharedURLLoaderFactory> pending_fallback_factory,mojo::PendingReceiver<blink::mojom::SubresourceLoaderUpdater> pending_subresource_loader_updater,scoped_refptr<base::SingleThreadTaskRunner> task_runner)598 WebWorkerFetchContextImpl::CloneForNestedWorkerInternal(
599     mojo::PendingReceiver<blink::mojom::ServiceWorkerWorkerClient>
600         service_worker_client_receiver,
601     mojo::PendingRemote<blink::mojom::ServiceWorkerWorkerClientRegistry>
602         service_worker_worker_client_registry,
603     mojo::PendingRemote<blink::mojom::ServiceWorkerContainerHost>
604         service_worker_container_host,
605     std::unique_ptr<network::PendingSharedURLLoaderFactory>
606         pending_loader_factory,
607     std::unique_ptr<network::PendingSharedURLLoaderFactory>
608         pending_fallback_factory,
609     mojo::PendingReceiver<blink::mojom::SubresourceLoaderUpdater>
610         pending_subresource_loader_updater,
611     scoped_refptr<base::SingleThreadTaskRunner> task_runner) {
612   mojo::PendingRemote<blink::mojom::RendererPreferenceWatcher>
613       preference_watcher;
614   auto new_context = base::AdoptRef(new WebWorkerFetchContextImpl(
615       renderer_preferences_,
616       preference_watcher.InitWithNewPipeAndPassReceiver(),
617       std::move(service_worker_client_receiver),
618       std::move(service_worker_worker_client_registry),
619       std::move(service_worker_container_host),
620       std::move(pending_loader_factory), std::move(pending_fallback_factory),
621       std::move(pending_subresource_loader_updater),
622       throttle_provider_ ? throttle_provider_->Clone() : nullptr,
623       websocket_handshake_throttle_provider_
624           ? websocket_handshake_throttle_provider_->Clone(
625                 std::move(task_runner))
626           : nullptr,
627       thread_safe_sender_.get(), process_host_));
628   new_context->is_on_sub_frame_ = is_on_sub_frame_;
629   new_context->ancestor_frame_id_ = ancestor_frame_id_;
630   new_context->frame_request_blocker_ = frame_request_blocker_;
631   new_context->site_for_cookies_ = site_for_cookies_;
632   new_context->top_frame_origin_ = top_frame_origin_;
633   child_preference_watchers_.Add(std::move(preference_watcher));
634   return new_context;
635 }
636 
Send(IPC::Message * message)637 bool WebWorkerFetchContextImpl::Send(IPC::Message* message) {
638   return thread_safe_sender_->Send(message);
639 }
640 
ResetServiceWorkerURLLoaderFactory()641 void WebWorkerFetchContextImpl::ResetServiceWorkerURLLoaderFactory() {
642   if (!web_loader_factory_)
643     return;
644   if (GetControllerServiceWorkerMode() !=
645       blink::mojom::ControllerServiceWorkerMode::kControlled) {
646     web_loader_factory_->SetServiceWorkerURLLoaderFactory(mojo::NullRemote());
647     return;
648   }
649   if (!service_worker_container_host_)
650     return;
651 
652   mojo::PendingRemote<network::mojom::URLLoaderFactory>
653       service_worker_url_loader_factory;
654   mojo::PendingRemote<blink::mojom::ServiceWorkerContainerHost>
655       service_worker_container_host;
656   service_worker_container_host_->CloneContainerHost(
657       service_worker_container_host.InitWithNewPipeAndPassReceiver());
658   // To avoid potential dead-lock while synchronous loading, create the
659   // SubresourceLoaderFactory on a background thread.
660   auto task_runner = base::ThreadPool::CreateSequencedTaskRunner(
661       {base::MayBlock(), base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN});
662   task_runner->PostTask(
663       FROM_HERE,
664       base::BindOnce(
665           &CreateServiceWorkerSubresourceLoaderFactory,
666           std::move(service_worker_container_host), client_id_,
667           fallback_factory_->Clone(),
668           service_worker_url_loader_factory.InitWithNewPipeAndPassReceiver(),
669           task_runner, base::SequencedTaskRunnerHandle::Get(),
670           base::BindRepeating(
671               &WebWorkerFetchContextImpl::AddPendingWorkerTimingReceiver,
672               weak_factory_.GetWeakPtr())));
673   web_loader_factory_->SetServiceWorkerURLLoaderFactory(
674       std::move(service_worker_url_loader_factory));
675 }
676 
UpdateSubresourceLoaderFactories(std::unique_ptr<blink::PendingURLLoaderFactoryBundle> subresource_loader_factories)677 void WebWorkerFetchContextImpl::UpdateSubresourceLoaderFactories(
678     std::unique_ptr<blink::PendingURLLoaderFactoryBundle>
679         subresource_loader_factories) {
680   auto subresource_loader_factory_bundle =
681       base::MakeRefCounted<ChildURLLoaderFactoryBundle>(
682           std::make_unique<ChildPendingURLLoaderFactoryBundle>(
683               std::move(subresource_loader_factories)));
684   loader_factory_ = network::SharedURLLoaderFactory::Create(
685       subresource_loader_factory_bundle->Clone());
686   fallback_factory_ = network::SharedURLLoaderFactory::Create(
687       subresource_loader_factory_bundle->CloneWithoutAppCacheFactory());
688   web_loader_factory_ = std::make_unique<Factory>(
689       resource_dispatcher_->GetWeakPtr(), loader_factory_);
690   ResetServiceWorkerURLLoaderFactory();
691 }
692 
NotifyUpdate(blink::mojom::RendererPreferencesPtr new_prefs)693 void WebWorkerFetchContextImpl::NotifyUpdate(
694     blink::mojom::RendererPreferencesPtr new_prefs) {
695   if (accept_languages_watcher_ &&
696       renderer_preferences_.accept_languages != new_prefs->accept_languages)
697     accept_languages_watcher_->NotifyUpdate();
698   renderer_preferences_ = *new_prefs;
699   for (auto& watcher : child_preference_watchers_)
700     watcher->NotifyUpdate(new_prefs.Clone());
701 }
702 
GetAcceptLanguages() const703 blink::WebString WebWorkerFetchContextImpl::GetAcceptLanguages() const {
704   return blink::WebString::FromUTF8(renderer_preferences_.accept_languages);
705 }
706 
AddPendingWorkerTimingReceiver(int request_id,mojo::PendingReceiver<blink::mojom::WorkerTimingContainer> receiver)707 void WebWorkerFetchContextImpl::AddPendingWorkerTimingReceiver(
708     int request_id,
709     mojo::PendingReceiver<blink::mojom::WorkerTimingContainer> receiver) {
710   // TODO(https://crbug.com/900700): Handle redirects properly. Currently on
711   // redirect, the receiver is replaced with a new one, discarding the timings
712   // before the redirect.
713   worker_timing_container_receivers_[request_id] = std::move(receiver);
714 }
715 
716 }  // namespace content
717