OLD | NEW |
---|---|
(Empty) | |
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/browser/service_worker/service_worker_url_loader_factory_creat ion.h" | |
6 | |
7 #include "content/browser/service_worker/service_worker_context_wrapper.h" | |
8 #include "content/browser/service_worker/service_worker_navigation_handle_core.h " | |
9 #include "content/browser/service_worker/service_worker_provider_host.h" | |
10 #include "content/common/service_worker/service_worker_utils.h" | |
11 #include "content/common/url_loader.mojom.h" | |
12 #include "content/public/browser/browser_thread.h" | |
13 #include "content/public/common/origin_util.h" | |
14 #include "content/public/common/service_manager_connection.h" | |
15 #include "content/public/common/service_names.mojom.h" | |
16 #include "mojo/public/cpp/bindings/strong_binding.h" | |
17 #include "net/base/url_util.h" | |
18 #include "services/service_manager/public/cpp/connector.h" | |
19 | |
20 namespace content { | |
21 | |
22 namespace { | |
23 | |
24 std::unique_ptr<service_manager::Connector> GetConnector() { | |
25 DCHECK_CURRENTLY_ON(BrowserThread::UI); | |
26 return ServiceManagerConnection::GetForProcess()->GetConnector()->Clone(); | |
27 } | |
28 | |
29 // A URLLoader implementation created by ControlleeHandlerFactory, used to serve | |
30 // requests to the document that's using a service worker. Currently simply | |
31 // proxies to the network service, rather than issuing the fetch request to the | |
32 // context provider host. | |
33 class ControlleeURLLoaderImpl : public mojom::URLLoader, | |
34 public mojom::URLLoaderClient { | |
35 public: | |
36 ControlleeURLLoaderImpl(mojom::URLLoaderAssociatedRequest loader, | |
kinuko
2017/05/01 15:07:57
Someone needs to own this?
| |
37 uint32_t options, | |
38 const ResourceRequest& request, | |
39 mojom::URLLoaderClientPtr client, | |
40 ServiceWorkerProviderHost* provider_host) | |
41 : binding_(this), client_(std::move(client)), weak_ptr_factory_(this) { | |
42 // The corresponding provider_host may already have associated a | |
43 // registration in redirect case, unassociate it now. | |
44 provider_host->DisassociateRegistration(); | |
45 | |
46 // Also prevent a register job for establishing an association to a new | |
47 // registration while we're finding an existing registration. | |
48 provider_host->SetAllowAssociation(false); | |
49 | |
50 GURL stripped_url = net::SimplifyUrlForRequest(request.url); | |
51 provider_host->SetDocumentUrl(stripped_url); | |
52 provider_host->SetTopmostFrameUrl(request.first_party_for_cookies); | |
53 | |
54 // TODO(scottmg): As an intermediate step, all requests are forwarded to the | |
55 // network service. Acquire a connector that can be used on the IO thread by | |
56 // posting to the UI thread here. | |
57 BrowserThread::PostTaskAndReplyWithResult( | |
58 BrowserThread::UI, FROM_HERE, base::Bind(&GetConnector), | |
59 base::Bind(&ControlleeURLLoaderImpl::ContinueAfterGettingConnector, | |
60 weak_ptr_factory_.GetWeakPtr(), request)); | |
61 } | |
62 | |
63 // mojom::URLLoader implementation: | |
64 void FollowRedirect() override {} | |
65 void SetPriority(net::RequestPriority priority, | |
66 int32_t intra_priority_value) override {} | |
67 | |
68 // mojom::URLLoaderClient implementation. This implementation is only required | |
69 // temporarily while this is a simple forwarder to the real network service, | |
70 // but can be removed. | |
71 void OnReceiveResponse( | |
72 const ResourceResponseHead& head, | |
73 const base::Optional<net::SSLInfo>& ssl_info, | |
74 mojom::DownloadedTempFilePtr downloaded_file) override { | |
75 client_->OnReceiveResponse(head, ssl_info, std::move(downloaded_file)); | |
76 } | |
77 void OnReceiveRedirect(const net::RedirectInfo& redirect_info, | |
78 const ResourceResponseHead& head) override {} | |
79 void OnDataDownloaded(int64_t data_length, int64_t encoded_length) override {} | |
80 void OnUploadProgress(int64_t current_position, | |
81 int64_t total_size, | |
82 OnUploadProgressCallback callback) override {} | |
83 void OnReceiveCachedMetadata(const std::vector<uint8_t>& data) override {} | |
84 void OnTransferSizeUpdated(int32_t transfer_size_diff) override {} | |
85 void OnStartLoadingResponseBody( | |
86 mojo::ScopedDataPipeConsumerHandle body) override { | |
87 client_->OnStartLoadingResponseBody(std::move(body)); | |
88 } | |
89 void OnComplete( | |
90 const ResourceRequestCompletionStatus& completion_status) override { | |
91 client_->OnComplete(completion_status); | |
92 } | |
93 | |
94 private: | |
95 void ContinueAfterGettingConnector( | |
96 const ResourceRequest& request, | |
97 std::unique_ptr<service_manager::Connector> connector) { | |
98 DCHECK_CURRENTLY_ON(BrowserThread::IO); | |
99 connector->BindInterface(mojom::kNetworkServiceName, | |
100 &network_url_loader_factory_); | |
101 | |
102 mojom::URLLoaderClientPtr url_loader_client_ptr_to_pass; | |
103 binding_.Bind(&url_loader_client_ptr_to_pass); | |
104 | |
105 network_url_loader_factory_->CreateLoaderAndStart( | |
106 mojo::MakeRequest(&url_loader_associated_ptr_), 0 /* routing_id? */, | |
107 0 /* request_id? */, mojom::kURLLoadOptionSendSSLInfo, request, | |
108 std::move(url_loader_client_ptr_to_pass)); | |
109 } | |
110 | |
111 mojom::URLLoaderFactoryPtr network_url_loader_factory_; | |
112 mojom::URLLoaderAssociatedPtr url_loader_associated_ptr_; | |
113 mojo::Binding<mojom::URLLoaderClient> binding_; | |
114 mojom::URLLoaderClientPtr client_; | |
115 | |
116 std::unique_ptr<base::WeakPtrFactory<ControlleeURLLoaderImpl>> | |
117 weak_ptr_factory_ui_; | |
118 base::WeakPtrFactory<ControlleeURLLoaderImpl> weak_ptr_factory_; | |
119 | |
120 DISALLOW_COPY_AND_ASSIGN(ControlleeURLLoaderImpl); | |
121 }; | |
122 | |
123 // URLLoaderFactory implementation for the document side. | |
124 class ControlleeHandlerFactory : public mojom::URLLoaderFactory { | |
125 public: | |
126 ControlleeHandlerFactory(ServiceWorkerProviderHost* provider_host) | |
kinuko
2017/05/01 02:06:24
explicit
| |
127 : provider_host_(provider_host) {} | |
128 ~ControlleeHandlerFactory() override {} | |
129 | |
130 void CreateLoaderAndStart(mojom::URLLoaderAssociatedRequest loader, | |
131 int32_t routing_id, | |
132 int32_t request_id, | |
133 uint32_t options, | |
134 const ResourceRequest& request, | |
135 mojom::URLLoaderClientPtr client) override { | |
136 new ControlleeURLLoaderImpl(std::move(loader), options, request, | |
137 std::move(client), provider_host_); | |
138 } | |
139 | |
140 void SyncLoad(int32_t routing_id, | |
141 int32_t request_id, | |
142 const ResourceRequest& request, | |
143 SyncLoadCallback callback) override { | |
144 NOTREACHED(); | |
145 } | |
146 | |
147 private: | |
148 ServiceWorkerProviderHost* provider_host_; | |
149 | |
150 DISALLOW_COPY_AND_ASSIGN(ControlleeHandlerFactory); | |
151 }; | |
152 | |
153 } // namespace | |
154 | |
155 // static | |
156 mojom::URLLoaderFactoryPtrInfo | |
157 ServiceWorkerURLLoaderFactoryCreation::InitializeForNavigation( | |
kinuko
2017/05/01 02:06:24
would be good if we could reuse some of the code i
| |
158 const NavigationFactoryCreationData& creation_data) { | |
159 DCHECK_CURRENTLY_ON(BrowserThread::IO); | |
160 | |
161 if (!creation_data.navigation_handle || | |
162 (!creation_data.request->url.SchemeIsHTTPOrHTTPS() && | |
163 !OriginCanAccessServiceWorkers(creation_data.request->url))) { | |
164 return mojom::URLLoaderFactoryPtrInfo(); | |
165 } | |
166 | |
167 std::unique_ptr<ServiceWorkerProviderHost> provider_host = | |
168 ServiceWorkerProviderHost::PreCreateNavigationHost( | |
169 creation_data.navigation_handle->context_wrapper() | |
170 ->context() | |
171 ->AsWeakPtr(), | |
172 creation_data.is_parent_frame_secure, | |
173 creation_data.web_contents_getter); | |
174 | |
175 // TODO(scottmg): For the time being, we always connect through our handler. | |
176 // In the future this will check if there's a SW active for this request | |
177 if (ServiceWorkerUtils::IsMainResourceType(creation_data.resource_type) || | |
178 provider_host->controlling_version()) { | |
179 mojom::URLLoaderFactoryPtr controllee; | |
180 mojo::MakeStrongBinding( | |
181 base::MakeUnique<ControlleeHandlerFactory>(provider_host.get()), | |
182 mojo::MakeRequest(&controllee)); | |
kinuko
2017/05/01 15:07:57
I'm still not fully sure why we need this proxy cl
| |
183 | |
184 // Transfer ownership to the ServiceWorkerNavigationHandleCore. | |
185 // In the case of a successful navigation, the SWProviderHost will be | |
186 // transferred to its "final" destination in the OnProviderCreated handler. | |
187 // If the navigation fails, it will be destroyed along with the | |
188 // ServiceWorkerNavigationHandleCore. | |
189 creation_data.navigation_handle->DidPreCreateProviderHost( | |
190 std::move(provider_host)); | |
191 | |
192 return controllee.PassInterface(); | |
193 } | |
194 | |
195 return mojom::URLLoaderFactoryPtrInfo(); | |
196 } | |
197 | |
198 } // namespace content | |
OLD | NEW |