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

Side by Side Diff: content/browser/loader/navigation_url_loader_network_service.cc

Issue 2843043002: network service: Create URLLoader for service worker navigation case
Patch Set: fix rebase Created 3 years, 7 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 unified diff | Download patch
OLDNEW
1 // Copyright 2017 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/browser/loader/navigation_url_loader_network_service.h" 5 #include "content/browser/loader/navigation_url_loader_network_service.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/bind_helpers.h" 8 #include "base/bind_helpers.h"
9 #include "base/lazy_instance.h" 9 #include "base/lazy_instance.h"
10 #include "base/memory/ptr_util.h" 10 #include "base/memory/ptr_util.h"
11 #include "base/trace_event/trace_event.h" 11 #include "base/trace_event/trace_event.h"
12 #include "content/browser/blob_storage/chrome_blob_storage_context.h" 12 #include "content/browser/blob_storage/chrome_blob_storage_context.h"
13 #include "content/browser/frame_host/frame_tree_node.h" 13 #include "content/browser/frame_host/frame_tree_node.h"
14 #include "content/browser/frame_host/navigation_request_info.h" 14 #include "content/browser/frame_host/navigation_request_info.h"
15 #include "content/browser/loader/navigation_resource_handler.h" 15 #include "content/browser/loader/navigation_resource_handler.h"
16 #include "content/browser/loader/navigation_resource_throttle.h" 16 #include "content/browser/loader/navigation_resource_throttle.h"
17 #include "content/browser/loader/navigation_url_loader_delegate.h" 17 #include "content/browser/loader/navigation_url_loader_delegate.h"
18 #include "content/browser/resource_context_impl.h"
19 #include "content/browser/service_worker/service_worker_context_wrapper.h"
20 #include "content/browser/service_worker/service_worker_navigation_handle.h"
21 #include "content/browser/service_worker/service_worker_navigation_handle_core.h "
22 #include "content/browser/service_worker/service_worker_request_handler.h"
23 #include "content/browser/web_contents/web_contents_impl.h"
18 #include "content/browser/webui/web_ui_url_loader_factory.h" 24 #include "content/browser/webui/web_ui_url_loader_factory.h"
19 #include "content/public/browser/browser_thread.h" 25 #include "content/public/browser/browser_thread.h"
20 #include "content/public/browser/global_request_id.h" 26 #include "content/public/browser/global_request_id.h"
21 #include "content/public/browser/navigation_data.h" 27 #include "content/public/browser/navigation_data.h"
22 #include "content/public/browser/navigation_ui_data.h" 28 #include "content/public/browser/navigation_ui_data.h"
23 #include "content/public/browser/ssl_status.h" 29 #include "content/public/browser/ssl_status.h"
24 #include "content/public/browser/stream_handle.h" 30 #include "content/public/browser/stream_handle.h"
25 #include "content/public/common/referrer.h" 31 #include "content/public/common/referrer.h"
26 #include "content/public/common/service_manager_connection.h" 32 #include "content/public/common/service_manager_connection.h"
27 #include "content/public/common/service_names.mojom.h" 33 #include "content/public/common/service_names.mojom.h"
28 #include "content/public/common/url_constants.h" 34 #include "content/public/common/url_constants.h"
29 #include "net/base/load_flags.h" 35 #include "net/base/load_flags.h"
30 #include "net/url_request/url_request_context.h" 36 #include "net/url_request/url_request_context.h"
31 #include "services/service_manager/public/cpp/connector.h" 37 #include "services/service_manager/public/cpp/connector.h"
32 38
33 namespace content { 39 namespace content {
34 40
35 namespace { 41 namespace {
36 42
37 static base::LazyInstance<mojom::URLLoaderFactoryPtr>::Leaky 43 static base::LazyInstance<mojom::URLLoaderFactoryPtr>::Leaky
38 g_url_loader_factory = LAZY_INSTANCE_INITIALIZER; 44 g_url_loader_factory = LAZY_INSTANCE_INITIALIZER;
39 45
40 // This function is called on the IO thread for POST/PUT requests for 46 using CompleteNavigationStart =
kinuko 2017/05/09 14:45:25 nit: CompleteNavigationStartCallback (preferring
scottmg 2017/05/09 22:14:10 Done.
41 // attaching blob information to the request body. 47 base::Callback<void(mojom::URLLoaderFactoryPtrInfo,
42 void HandleRequestsWithBody( 48 std::unique_ptr<ResourceRequest>)>;
43 std::unique_ptr<ResourceRequest> request, 49
50 void NavigationStartupWorkOnIO(
kinuko 2017/05/09 14:45:25 nit: maybe... PrepareNavigationStartOnIOThread
scottmg 2017/05/09 22:14:10 Done.
51 std::unique_ptr<ResourceRequest> resource_request,
44 ResourceContext* resource_context, 52 ResourceContext* resource_context,
45 base::WeakPtr<NavigationURLLoaderNetworkService> url_loader) { 53 ServiceWorkerNavigationHandleCore* service_worker_navigation_handle_core,
54 bool skip_service_worker,
55 ResourceType resource_type,
56 RequestContextType request_context_type,
57 RequestContextFrameType frame_type,
58 bool is_parent_frame_secure,
59 scoped_refptr<ResourceRequestBodyImpl> body,
60 const base::Callback<WebContents*(void)>& web_contents_getter,
61 CompleteNavigationStart complete_request) {
46 DCHECK_CURRENTLY_ON(BrowserThread::IO); 62 DCHECK_CURRENTLY_ON(BrowserThread::IO);
47 DCHECK(request->request_body.get()); 63 DCHECK(service_worker_navigation_handle_core ||
64 resource_request->request_body.get());
48 65
49 AttachRequestBodyBlobDataHandles(request->request_body.get(), 66 mojom::URLLoaderFactoryPtrInfo url_loader_factory_ptr_info;
50 resource_context); 67 if (service_worker_navigation_handle_core) {
68 storage::BlobStorageContext* blob_storage_context = GetBlobStorageContext(
69 GetChromeBlobStorageContextForResourceContext(resource_context));
70 url_loader_factory_ptr_info =
71 ServiceWorkerRequestHandler::InitializeForNavigationNetworkService(
72 *resource_request, resource_context,
73 service_worker_navigation_handle_core, blob_storage_context,
74 skip_service_worker, resource_type, request_context_type,
75 frame_type, is_parent_frame_secure, body, web_contents_getter,
76 // This is a fallback callback if the service worker handler decides
77 // later that the request should fallback to the network.
78 base::Bind(
79 complete_request,
80 base::Passed(std::move(mojom::URLLoaderFactoryPtrInfo()))));
kinuko 2017/05/09 14:45:25 I think it'd be probably nicer to have some code s
scottmg 2017/05/09 22:14:10 Yes, we'll need something like that in the full ap
81 }
82
83 if (resource_request->request_body) {
84 AttachRequestBodyBlobDataHandles(resource_request->request_body.get(),
85 resource_context);
86 }
87
51 BrowserThread::PostTask( 88 BrowserThread::PostTask(
52 BrowserThread::UI, FROM_HERE, 89 BrowserThread::UI, FROM_HERE,
53 base::Bind(&NavigationURLLoaderNetworkService::StartURLRequest, 90 base::Bind(complete_request,
54 url_loader, base::Passed(&request))); 91 base::Passed(std::move(url_loader_factory_ptr_info)),
92 base::Passed(std::move(resource_request))));
93 }
94
95 WebContents* GetWebContentsFromFrameTreeNodeID(int frame_tree_node_id) {
96 DCHECK_CURRENTLY_ON(BrowserThread::UI);
97 FrameTreeNode* frame_tree_node =
98 FrameTreeNode::GloballyFindByID(frame_tree_node_id);
99 if (!frame_tree_node)
100 return nullptr;
101
102 return WebContentsImpl::FromFrameTreeNode(frame_tree_node);
55 } 103 }
56 104
57 } // namespace 105 } // namespace
58 106
59 NavigationURLLoaderNetworkService::NavigationURLLoaderNetworkService( 107 NavigationURLLoaderNetworkService::NavigationURLLoaderNetworkService(
60 ResourceContext* resource_context, 108 ResourceContext* resource_context,
61 StoragePartition* storage_partition, 109 StoragePartition* storage_partition,
62 std::unique_ptr<NavigationRequestInfo> request_info, 110 std::unique_ptr<NavigationRequestInfo> request_info,
63 std::unique_ptr<NavigationUIData> navigation_ui_data, 111 std::unique_ptr<NavigationUIData> navigation_ui_data,
64 ServiceWorkerNavigationHandle* service_worker_handle, 112 ServiceWorkerNavigationHandle* service_worker_navigation_handle,
65 AppCacheNavigationHandle* appcache_handle, 113 AppCacheNavigationHandle* appcache_handle,
66 NavigationURLLoaderDelegate* delegate) 114 NavigationURLLoaderDelegate* delegate)
67 : delegate_(delegate), 115 : delegate_(delegate),
68 binding_(this), 116 binding_(this),
69 request_info_(std::move(request_info)), 117 request_info_(std::move(request_info)),
70 weak_factory_(this) { 118 weak_factory_(this) {
71 DCHECK_CURRENTLY_ON(BrowserThread::UI); 119 DCHECK_CURRENTLY_ON(BrowserThread::UI);
72 120
73 TRACE_EVENT_ASYNC_BEGIN_WITH_TIMESTAMP1( 121 TRACE_EVENT_ASYNC_BEGIN_WITH_TIMESTAMP1(
74 "navigation", "Navigation timeToResponseStarted", this, 122 "navigation", "Navigation timeToResponseStarted", this,
(...skipping 22 matching lines...) Expand all
97 if (request_info_->is_main_frame) 145 if (request_info_->is_main_frame)
98 load_flags |= net::LOAD_MAIN_FRAME_DEPRECATED; 146 load_flags |= net::LOAD_MAIN_FRAME_DEPRECATED;
99 147
100 // Sync loads should have maximum priority and should be the only 148 // Sync loads should have maximum priority and should be the only
101 // requests that have the ignore limits flag set. 149 // requests that have the ignore limits flag set.
102 DCHECK(!(load_flags & net::LOAD_IGNORE_LIMITS)); 150 DCHECK(!(load_flags & net::LOAD_IGNORE_LIMITS));
103 151
104 new_request->load_flags = load_flags; 152 new_request->load_flags = load_flags;
105 153
106 new_request->request_body = request_info_->common_params.post_data.get(); 154 new_request->request_body = request_info_->common_params.post_data.get();
107 if (new_request->request_body.get()) { 155
108 // The request body may need blob handles to be added to it. This 156 ResourceType resource_type = request_info_->is_main_frame
109 // functionality has to be invoked on the IO thread. 157 ? RESOURCE_TYPE_MAIN_FRAME
158 : RESOURCE_TYPE_SUB_FRAME;
159 RequestContextFrameType frame_type =
160 request_info_->is_main_frame ? REQUEST_CONTEXT_FRAME_TYPE_TOP_LEVEL
161 : REQUEST_CONTEXT_FRAME_TYPE_NESTED;
162
163 // Determine where the request will be serviced. If there's work that needs to
164 // be done on the IO thread due to Service Worker or POST body, then post to
165 // the IO thread to have it do that work, and then continue on to
166 // StartURLRequest. Otherwise, handle the request directly.
167 const bool need_to_work_on_io =
168 service_worker_navigation_handle || new_request->request_body;
169 if (need_to_work_on_io) {
110 BrowserThread::PostTask( 170 BrowserThread::PostTask(
111 BrowserThread::IO, FROM_HERE, 171 BrowserThread::IO, FROM_HERE,
112 base::Bind(&HandleRequestsWithBody, 172 base::Bind(
113 base::Passed(&new_request), 173 &NavigationStartupWorkOnIO, base::Passed(std::move(new_request)),
114 resource_context, 174 resource_context,
115 weak_factory_.GetWeakPtr())); 175 service_worker_navigation_handle
176 ? service_worker_navigation_handle->core()
177 : nullptr,
178 request_info_->begin_params.skip_service_worker, resource_type,
179 request_info_->begin_params.request_context_type, frame_type,
180 request_info_->are_ancestors_secure,
181 request_info_->common_params.post_data,
182 base::Bind(&GetWebContentsFromFrameTreeNodeID,
183 request_info_->frame_tree_node_id),
184 base::Bind(&NavigationURLLoaderNetworkService::StartURLRequest,
185 weak_factory_.GetWeakPtr())));
116 return; 186 return;
117 } 187 }
118 188
119 StartURLRequest(std::move(new_request)); 189 StartURLRequest(mojom::URLLoaderFactoryPtrInfo(), std::move(new_request));
120 } 190 }
121 191
122 NavigationURLLoaderNetworkService::~NavigationURLLoaderNetworkService() {} 192 NavigationURLLoaderNetworkService::~NavigationURLLoaderNetworkService() {}
123 193
124 void NavigationURLLoaderNetworkService::OverrideURLLoaderFactoryForTesting( 194 void NavigationURLLoaderNetworkService::OverrideURLLoaderFactoryForTesting(
125 mojom::URLLoaderFactoryPtr url_loader_factory) { 195 mojom::URLLoaderFactoryPtr url_loader_factory) {
126 g_url_loader_factory.Get() = std::move(url_loader_factory); 196 g_url_loader_factory.Get() = std::move(url_loader_factory);
127 } 197 }
128 198
129 void NavigationURLLoaderNetworkService::FollowRedirect() { 199 void NavigationURLLoaderNetworkService::FollowRedirect() {
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
192 TRACE_EVENT_ASYNC_END2("navigation", "Navigation timeToResponseStarted", 262 TRACE_EVENT_ASYNC_END2("navigation", "Navigation timeToResponseStarted",
193 this, "&NavigationURLLoaderNetworkService", this, 263 this, "&NavigationURLLoaderNetworkService", this,
194 "success", false); 264 "success", false);
195 265
196 delegate_->OnRequestFailed(completion_status.exists_in_cache, 266 delegate_->OnRequestFailed(completion_status.exists_in_cache,
197 completion_status.error_code); 267 completion_status.error_code);
198 } 268 }
199 } 269 }
200 270
201 void NavigationURLLoaderNetworkService::StartURLRequest( 271 void NavigationURLLoaderNetworkService::StartURLRequest(
272 mojom::URLLoaderFactoryPtrInfo url_loader_factory_info,
202 std::unique_ptr<ResourceRequest> request) { 273 std::unique_ptr<ResourceRequest> request) {
203 DCHECK_CURRENTLY_ON(BrowserThread::UI); 274 DCHECK_CURRENTLY_ON(BrowserThread::UI);
204 275
276 // Bind the URLClient implementation to this object to pass to the URLLoader.
277 if (binding_.is_bound())
278 binding_.Unbind();
205 mojom::URLLoaderClientPtr url_loader_client_ptr_to_pass; 279 mojom::URLLoaderClientPtr url_loader_client_ptr_to_pass;
206 binding_.Bind(&url_loader_client_ptr_to_pass); 280 binding_.Bind(&url_loader_client_ptr_to_pass);
207 281
208 mojom::URLLoaderFactory* factory = nullptr; 282 mojom::URLLoaderFactory* factory = nullptr;
209 // This |factory_ptr| will be destroyed when it goes out of scope. Because 283 // This |factory_ptr| will be destroyed when it goes out of scope. Because
210 // |url_loader_associated_ptr_| is associated with it, it will be disconnected 284 // |url_loader_associated_ptr_| is associated with it, it will be disconnected
211 // as well. That means NavigationURLLoaderNetworkService::FollowRedirect() 285 // as well. That means NavigationURLLoaderNetworkService::FollowRedirect()
212 // won't work as expected, the |url_loader_associated_ptr_| will silently drop 286 // won't work as expected, the |url_loader_associated_ptr_| will silently drop
213 // calls. 287 // calls.
214 // This is fine for now since the only user of this is WebUI which doesn't 288 // This is fine for now since the only user of this is WebUI which doesn't
215 // need this, but we'll have to fix this when other consumers come up. 289 // need this, but we'll have to fix this when other consumers come up.
216 mojom::URLLoaderFactoryPtr factory_ptr; 290 mojom::URLLoaderFactoryPtr factory_ptr;
217 if (request->url.SchemeIs(kChromeUIScheme)) { 291 if (request->url.SchemeIs(kChromeUIScheme)) {
218 FrameTreeNode* frame_tree_node = 292 FrameTreeNode* frame_tree_node =
219 FrameTreeNode::GloballyFindByID(request_info_->frame_tree_node_id); 293 FrameTreeNode::GloballyFindByID(request_info_->frame_tree_node_id);
220 factory_ptr = GetWebUIURLLoader(frame_tree_node); 294 factory_ptr = GetWebUIURLLoader(frame_tree_node);
221 factory = factory_ptr.get(); 295 factory = factory_ptr.get();
222 } 296 }
223 297
224 if (!factory) 298 if (!factory) {
225 factory = GetURLLoaderFactory(); 299 // If a URLLoaderFactory was provided, then we use that one, otherwise
300 // fall back to connecting directly to the network service.
301 if (url_loader_factory_info.is_valid()) {
302 url_loader_factory_.Bind(std::move(url_loader_factory_info));
303 factory = url_loader_factory_.get();
304 } else {
305 factory = GetURLLoaderFactory();
306 }
307 }
226 308
227 factory->CreateLoaderAndStart(mojo::MakeRequest(&url_loader_associated_ptr_), 309 factory->CreateLoaderAndStart(mojo::MakeRequest(&url_loader_associated_ptr_),
228 0 /* routing_id? */, 0 /* request_id? */, 310 0 /* routing_id? */, 0 /* request_id? */,
229 mojom::kURLLoadOptionSendSSLInfo, *request, 311 mojom::kURLLoadOptionSendSSLInfo, *request,
230 std::move(url_loader_client_ptr_to_pass)); 312 std::move(url_loader_client_ptr_to_pass));
231 } 313 }
232 314
233 mojom::URLLoaderFactory* 315 mojom::URLLoaderFactory*
234 NavigationURLLoaderNetworkService::GetURLLoaderFactory() { 316 NavigationURLLoaderNetworkService::GetURLLoaderFactory() {
235 // TODO(yzshen): We will need the ability to customize the factory per frame 317 // TODO(yzshen): We will need the ability to customize the factory per frame
236 // e.g., for appcache or service worker. 318 // e.g., for appcache or service worker.
237 if (!g_url_loader_factory.Get()) { 319 if (!g_url_loader_factory.Get()) {
238 ServiceManagerConnection::GetForProcess()->GetConnector()->BindInterface( 320 ServiceManagerConnection::GetForProcess()->GetConnector()->BindInterface(
239 mojom::kNetworkServiceName, &g_url_loader_factory.Get()); 321 mojom::kNetworkServiceName, &g_url_loader_factory.Get());
240 } 322 }
241 323
242 return g_url_loader_factory.Get().get(); 324 return g_url_loader_factory.Get().get();
243 } 325 }
244 326
245 } // namespace content 327 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698