| // Copyright 2019 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "content/renderer/service_worker/web_service_worker_network_provider_impl_for_frame.h" |
| |
| #include "content/public/common/origin_util.h" |
| #include "content/renderer/loader/request_extra_data.h" |
| #include "content/renderer/render_thread_impl.h" |
| #include "content/renderer/service_worker/service_worker_network_provider.h" |
| #include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h" |
| #include "third_party/blink/public/common/service_worker/service_worker_utils.h" |
| |
| namespace content { |
| |
| WebServiceWorkerNetworkProviderImplForFrame:: |
| WebServiceWorkerNetworkProviderImplForFrame( |
| std::unique_ptr<ServiceWorkerNetworkProvider> provider) |
| : WebServiceWorkerNetworkProviderBaseImpl(std::move(provider)) {} |
| |
| void WebServiceWorkerNetworkProviderImplForFrame::WillSendRequest( |
| blink::WebURLRequest& request) { |
| if (!request.GetExtraData()) |
| request.SetExtraData(std::make_unique<RequestExtraData>()); |
| auto* extra_data = static_cast<RequestExtraData*>(request.GetExtraData()); |
| extra_data->set_service_worker_provider_id(provider()->provider_id()); |
| |
| // If the provider does not have a controller at this point, the renderer |
| // expects the request to never be handled by a service worker, so call |
| // SetSkipServiceWorker() with true to skip service workers here. Otherwise, |
| // a service worker that is in the process of becoming the controller (i.e., |
| // via claim()) on the browser-side could handle the request and break the |
| // assumptions of the renderer. |
| if (request.GetFrameType() != |
| network::mojom::RequestContextFrameType::kTopLevel && |
| request.GetFrameType() != |
| network::mojom::RequestContextFrameType::kNested && |
| IsControlledByServiceWorker() == |
| blink::mojom::ControllerServiceWorkerMode::kNoController) { |
| request.SetSkipServiceWorker(true); |
| } |
| |
| // Inject this frame's fetch window id into the request. This is really only |
| // needed for subresource requests in S13nServiceWorker. For main resource |
| // requests or non-S13nSW case, the browser process sets the id on the |
| // request when dispatching the fetch event to the service worker. But it |
| // doesn't hurt to set it always. |
| if (provider()->context()) |
| request.SetFetchWindowId(provider()->context()->fetch_request_window_id()); |
| } |
| |
| std::unique_ptr<blink::WebURLLoader> |
| WebServiceWorkerNetworkProviderImplForFrame::CreateURLLoader( |
| const blink::WebURLRequest& request, |
| std::unique_ptr<blink::scheduler::WebResourceLoadingTaskRunnerHandle> |
| task_runner_handle) { |
| // RenderThreadImpl is nullptr in some tests. |
| if (!RenderThreadImpl::current()) |
| return nullptr; |
| |
| // S13nServiceWorker: |
| // We only install our own URLLoader if Servicification is enabled. |
| if (!blink::ServiceWorkerUtils::IsServicificationEnabled()) |
| return nullptr; |
| |
| // We need SubresourceLoaderFactory populated in order to create our own |
| // URLLoader for subresource loading. |
| if (!provider()->context() || |
| !provider()->context()->GetSubresourceLoaderFactory()) |
| return nullptr; |
| |
| // If the URL is not http(s) or otherwise whitelisted, do not intercept the |
| // request. Schemes like 'blob' and 'file' are not eligible to be intercepted |
| // by service workers. |
| // TODO(falken): Let ServiceWorkerSubresourceLoaderFactory handle the request |
| // and move this check there (i.e., for such URLs, it should use its fallback |
| // factory). |
| const GURL gurl(request.Url()); |
| if (!gurl.SchemeIsHTTPOrHTTPS() && !OriginCanAccessServiceWorkers(gurl)) |
| return nullptr; |
| |
| // If GetSkipServiceWorker() returns true, do not intercept the request. |
| if (request.GetSkipServiceWorker()) |
| return nullptr; |
| |
| // Create our own SubresourceLoader to route the request to the controller |
| // ServiceWorker. |
| // TODO(crbug.com/796425): Temporarily wrap the raw mojom::URLLoaderFactory |
| // pointer into SharedURLLoaderFactory. |
| return std::make_unique<WebURLLoaderImpl>( |
| RenderThreadImpl::current()->resource_dispatcher(), |
| std::move(task_runner_handle), |
| base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>( |
| provider()->context()->GetSubresourceLoaderFactory())); |
| } |
| |
| void WebServiceWorkerNetworkProviderImplForFrame::DispatchNetworkQuiet() { |
| provider()->DispatchNetworkQuiet(); |
| } |
| |
| } // namespace content |