Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(55)

Unified Diff: content/browser/service_worker/service_worker_url_loader_factory_creation.cc

Issue 2843043002: network service: Create URLLoader for service worker navigation case
Patch Set: . Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: content/browser/service_worker/service_worker_url_loader_factory_creation.cc
diff --git a/content/browser/service_worker/service_worker_url_loader_factory_creation.cc b/content/browser/service_worker/service_worker_url_loader_factory_creation.cc
new file mode 100644
index 0000000000000000000000000000000000000000..0f6c3dc8fe6ca63088c7ffe7d317275af4b5cb5a
--- /dev/null
+++ b/content/browser/service_worker/service_worker_url_loader_factory_creation.cc
@@ -0,0 +1,198 @@
+// Copyright 2017 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/browser/service_worker/service_worker_url_loader_factory_creation.h"
+
+#include "content/browser/service_worker/service_worker_context_wrapper.h"
+#include "content/browser/service_worker/service_worker_navigation_handle_core.h"
+#include "content/browser/service_worker/service_worker_provider_host.h"
+#include "content/common/service_worker/service_worker_utils.h"
+#include "content/common/url_loader.mojom.h"
+#include "content/public/browser/browser_thread.h"
+#include "content/public/common/origin_util.h"
+#include "content/public/common/service_manager_connection.h"
+#include "content/public/common/service_names.mojom.h"
+#include "mojo/public/cpp/bindings/strong_binding.h"
+#include "net/base/url_util.h"
+#include "services/service_manager/public/cpp/connector.h"
+
+namespace content {
+
+namespace {
+
+std::unique_ptr<service_manager::Connector> GetConnector() {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ return ServiceManagerConnection::GetForProcess()->GetConnector()->Clone();
+}
+
+// A URLLoader implementation created by ControlleeHandlerFactory, used to serve
+// requests to the document that's using a service worker. Currently simply
+// proxies to the network service, rather than issuing the fetch request to the
+// context provider host.
+class ControlleeURLLoaderImpl : public mojom::URLLoader,
+ public mojom::URLLoaderClient {
+ public:
+ ControlleeURLLoaderImpl(mojom::URLLoaderAssociatedRequest loader,
kinuko 2017/05/01 15:07:57 Someone needs to own this?
+ uint32_t options,
+ const ResourceRequest& request,
+ mojom::URLLoaderClientPtr client,
+ ServiceWorkerProviderHost* provider_host)
+ : binding_(this), client_(std::move(client)), weak_ptr_factory_(this) {
+ // The corresponding provider_host may already have associated a
+ // registration in redirect case, unassociate it now.
+ provider_host->DisassociateRegistration();
+
+ // Also prevent a register job for establishing an association to a new
+ // registration while we're finding an existing registration.
+ provider_host->SetAllowAssociation(false);
+
+ GURL stripped_url = net::SimplifyUrlForRequest(request.url);
+ provider_host->SetDocumentUrl(stripped_url);
+ provider_host->SetTopmostFrameUrl(request.first_party_for_cookies);
+
+ // TODO(scottmg): As an intermediate step, all requests are forwarded to the
+ // network service. Acquire a connector that can be used on the IO thread by
+ // posting to the UI thread here.
+ BrowserThread::PostTaskAndReplyWithResult(
+ BrowserThread::UI, FROM_HERE, base::Bind(&GetConnector),
+ base::Bind(&ControlleeURLLoaderImpl::ContinueAfterGettingConnector,
+ weak_ptr_factory_.GetWeakPtr(), request));
+ }
+
+ // mojom::URLLoader implementation:
+ void FollowRedirect() override {}
+ void SetPriority(net::RequestPriority priority,
+ int32_t intra_priority_value) override {}
+
+ // mojom::URLLoaderClient implementation. This implementation is only required
+ // temporarily while this is a simple forwarder to the real network service,
+ // but can be removed.
+ void OnReceiveResponse(
+ const ResourceResponseHead& head,
+ const base::Optional<net::SSLInfo>& ssl_info,
+ mojom::DownloadedTempFilePtr downloaded_file) override {
+ client_->OnReceiveResponse(head, ssl_info, std::move(downloaded_file));
+ }
+ void OnReceiveRedirect(const net::RedirectInfo& redirect_info,
+ const ResourceResponseHead& head) override {}
+ void OnDataDownloaded(int64_t data_length, int64_t encoded_length) override {}
+ void OnUploadProgress(int64_t current_position,
+ int64_t total_size,
+ OnUploadProgressCallback callback) override {}
+ void OnReceiveCachedMetadata(const std::vector<uint8_t>& data) override {}
+ void OnTransferSizeUpdated(int32_t transfer_size_diff) override {}
+ void OnStartLoadingResponseBody(
+ mojo::ScopedDataPipeConsumerHandle body) override {
+ client_->OnStartLoadingResponseBody(std::move(body));
+ }
+ void OnComplete(
+ const ResourceRequestCompletionStatus& completion_status) override {
+ client_->OnComplete(completion_status);
+ }
+
+ private:
+ void ContinueAfterGettingConnector(
+ const ResourceRequest& request,
+ std::unique_ptr<service_manager::Connector> connector) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ connector->BindInterface(mojom::kNetworkServiceName,
+ &network_url_loader_factory_);
+
+ mojom::URLLoaderClientPtr url_loader_client_ptr_to_pass;
+ binding_.Bind(&url_loader_client_ptr_to_pass);
+
+ network_url_loader_factory_->CreateLoaderAndStart(
+ mojo::MakeRequest(&url_loader_associated_ptr_), 0 /* routing_id? */,
+ 0 /* request_id? */, mojom::kURLLoadOptionSendSSLInfo, request,
+ std::move(url_loader_client_ptr_to_pass));
+ }
+
+ mojom::URLLoaderFactoryPtr network_url_loader_factory_;
+ mojom::URLLoaderAssociatedPtr url_loader_associated_ptr_;
+ mojo::Binding<mojom::URLLoaderClient> binding_;
+ mojom::URLLoaderClientPtr client_;
+
+ std::unique_ptr<base::WeakPtrFactory<ControlleeURLLoaderImpl>>
+ weak_ptr_factory_ui_;
+ base::WeakPtrFactory<ControlleeURLLoaderImpl> weak_ptr_factory_;
+
+ DISALLOW_COPY_AND_ASSIGN(ControlleeURLLoaderImpl);
+};
+
+// URLLoaderFactory implementation for the document side.
+class ControlleeHandlerFactory : public mojom::URLLoaderFactory {
+ public:
+ ControlleeHandlerFactory(ServiceWorkerProviderHost* provider_host)
kinuko 2017/05/01 02:06:24 explicit
+ : provider_host_(provider_host) {}
+ ~ControlleeHandlerFactory() override {}
+
+ void CreateLoaderAndStart(mojom::URLLoaderAssociatedRequest loader,
+ int32_t routing_id,
+ int32_t request_id,
+ uint32_t options,
+ const ResourceRequest& request,
+ mojom::URLLoaderClientPtr client) override {
+ new ControlleeURLLoaderImpl(std::move(loader), options, request,
+ std::move(client), provider_host_);
+ }
+
+ void SyncLoad(int32_t routing_id,
+ int32_t request_id,
+ const ResourceRequest& request,
+ SyncLoadCallback callback) override {
+ NOTREACHED();
+ }
+
+ private:
+ ServiceWorkerProviderHost* provider_host_;
+
+ DISALLOW_COPY_AND_ASSIGN(ControlleeHandlerFactory);
+};
+
+} // namespace
+
+// static
+mojom::URLLoaderFactoryPtrInfo
+ServiceWorkerURLLoaderFactoryCreation::InitializeForNavigation(
kinuko 2017/05/01 02:06:24 would be good if we could reuse some of the code i
+ const NavigationFactoryCreationData& creation_data) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+
+ if (!creation_data.navigation_handle ||
+ (!creation_data.request->url.SchemeIsHTTPOrHTTPS() &&
+ !OriginCanAccessServiceWorkers(creation_data.request->url))) {
+ return mojom::URLLoaderFactoryPtrInfo();
+ }
+
+ std::unique_ptr<ServiceWorkerProviderHost> provider_host =
+ ServiceWorkerProviderHost::PreCreateNavigationHost(
+ creation_data.navigation_handle->context_wrapper()
+ ->context()
+ ->AsWeakPtr(),
+ creation_data.is_parent_frame_secure,
+ creation_data.web_contents_getter);
+
+ // TODO(scottmg): For the time being, we always connect through our handler.
+ // In the future this will check if there's a SW active for this request
+ if (ServiceWorkerUtils::IsMainResourceType(creation_data.resource_type) ||
+ provider_host->controlling_version()) {
+ mojom::URLLoaderFactoryPtr controllee;
+ mojo::MakeStrongBinding(
+ base::MakeUnique<ControlleeHandlerFactory>(provider_host.get()),
+ mojo::MakeRequest(&controllee));
kinuko 2017/05/01 15:07:57 I'm still not fully sure why we need this proxy cl
+
+ // Transfer ownership to the ServiceWorkerNavigationHandleCore.
+ // In the case of a successful navigation, the SWProviderHost will be
+ // transferred to its "final" destination in the OnProviderCreated handler.
+ // If the navigation fails, it will be destroyed along with the
+ // ServiceWorkerNavigationHandleCore.
+ creation_data.navigation_handle->DidPreCreateProviderHost(
+ std::move(provider_host));
+
+ return controllee.PassInterface();
+ }
+
+ return mojom::URLLoaderFactoryPtrInfo();
+}
+
+} // namespace content

Powered by Google App Engine
This is Rietveld 408576698