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

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: network fallback in simple cases 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/navigation_request_info.h" 14 #include "content/browser/frame_host/navigation_request_info.h"
14 #include "content/browser/loader/navigation_resource_handler.h" 15 #include "content/browser/loader/navigation_resource_handler.h"
15 #include "content/browser/loader/navigation_resource_throttle.h" 16 #include "content/browser/loader/navigation_resource_throttle.h"
16 #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"
17 #include "content/public/browser/browser_thread.h" 24 #include "content/public/browser/browser_thread.h"
18 #include "content/public/browser/global_request_id.h" 25 #include "content/public/browser/global_request_id.h"
19 #include "content/public/browser/navigation_data.h" 26 #include "content/public/browser/navigation_data.h"
20 #include "content/public/browser/navigation_ui_data.h" 27 #include "content/public/browser/navigation_ui_data.h"
21 #include "content/public/browser/ssl_status.h" 28 #include "content/public/browser/ssl_status.h"
22 #include "content/public/browser/stream_handle.h" 29 #include "content/public/browser/stream_handle.h"
23 #include "content/public/common/referrer.h" 30 #include "content/public/common/referrer.h"
24 #include "content/public/common/service_manager_connection.h" 31 #include "content/public/common/service_manager_connection.h"
25 #include "content/public/common/service_names.mojom.h" 32 #include "content/public/common/service_names.mojom.h"
26 #include "net/base/load_flags.h" 33 #include "net/base/load_flags.h"
27 #include "net/url_request/url_request_context.h" 34 #include "net/url_request/url_request_context.h"
28 #include "services/service_manager/public/cpp/connector.h" 35 #include "services/service_manager/public/cpp/connector.h"
29 36
30 namespace content { 37 namespace content {
31 38
32 namespace { 39 namespace {
33 40
34 static base::LazyInstance<mojom::URLLoaderFactoryPtr>::Leaky 41 static base::LazyInstance<mojom::URLLoaderFactoryPtr>::Leaky
35 g_url_loader_factory = LAZY_INSTANCE_INITIALIZER; 42 g_direct_network_url_loader_factory = LAZY_INSTANCE_INITIALIZER;
36 43
37 // This function is called on the IO thread for POST/PUT requests for 44 using CompleteNavigationStart =
38 // attaching blob information to the request body. 45 base::Callback<void(mojom::URLLoaderFactoryPtrInfo,
39 void HandleRequestsWithBody( 46 std::unique_ptr<ResourceRequest>)>;
40 std::unique_ptr<ResourceRequest> request, 47
48 void NavigationStartupWorkOnIO(
49 std::unique_ptr<ResourceRequest> resource_request,
41 ResourceContext* resource_context, 50 ResourceContext* resource_context,
42 base::WeakPtr<NavigationURLLoaderNetworkService> url_loader) { 51 ServiceWorkerNavigationHandleCore* service_worker_navigation_handle_core,
52 bool skip_service_worker,
53 ResourceType resource_type,
54 RequestContextType request_context_type,
55 RequestContextFrameType frame_type,
56 bool is_parent_frame_secure,
57 scoped_refptr<ResourceRequestBodyImpl> body,
58 const base::Callback<WebContents*(void)>& web_contents_getter,
59 CompleteNavigationStart complete_request) {
43 DCHECK_CURRENTLY_ON(BrowserThread::IO); 60 DCHECK_CURRENTLY_ON(BrowserThread::IO);
44 DCHECK(request->request_body.get()); 61 DCHECK(service_worker_navigation_handle_core ||
62 resource_request->request_body.get());
45 63
46 AttachRequestBodyBlobDataHandles(request->request_body.get(), 64 mojom::URLLoaderFactoryPtrInfo url_loader_factory_ptr_info;
47 resource_context); 65 if (service_worker_navigation_handle_core) {
66 storage::BlobStorageContext* blob_storage_context = GetBlobStorageContext(
67 GetChromeBlobStorageContextForResourceContext(resource_context));
68 url_loader_factory_ptr_info =
69 ServiceWorkerRequestHandler::InitializeForNavigationNetworkService(
70 *resource_request, resource_context,
71 service_worker_navigation_handle_core, blob_storage_context,
72 skip_service_worker, resource_type, request_context_type,
73 frame_type, is_parent_frame_secure, body, web_contents_getter);
74 }
75
76 if (resource_request->request_body) {
77 AttachRequestBodyBlobDataHandles(resource_request->request_body.get(),
78 resource_context);
79 }
80
48 BrowserThread::PostTask( 81 BrowserThread::PostTask(
49 BrowserThread::UI, FROM_HERE, 82 BrowserThread::UI, FROM_HERE,
50 base::Bind(&NavigationURLLoaderNetworkService::StartURLRequest, 83 base::Bind(complete_request,
51 url_loader, base::Passed(&request))); 84 base::Passed(std::move(url_loader_factory_ptr_info)),
85 base::Passed(std::move(resource_request))));
86 }
87
88 WebContents* GetWebContentsFromFrameTreeNodeID(int frame_tree_node_id) {
89 DCHECK_CURRENTLY_ON(BrowserThread::UI);
90 FrameTreeNode* frame_tree_node =
91 FrameTreeNode::GloballyFindByID(frame_tree_node_id);
92 if (!frame_tree_node)
93 return nullptr;
94
95 return WebContentsImpl::FromFrameTreeNode(frame_tree_node);
52 } 96 }
53 97
54 } // namespace 98 } // namespace
55 99
56 NavigationURLLoaderNetworkService::NavigationURLLoaderNetworkService( 100 NavigationURLLoaderNetworkService::NavigationURLLoaderNetworkService(
57 ResourceContext* resource_context, 101 ResourceContext* resource_context,
58 StoragePartition* storage_partition, 102 StoragePartition* storage_partition,
59 std::unique_ptr<NavigationRequestInfo> request_info, 103 std::unique_ptr<NavigationRequestInfo> request_info,
60 std::unique_ptr<NavigationUIData> navigation_ui_data, 104 std::unique_ptr<NavigationUIData> navigation_ui_data,
61 ServiceWorkerNavigationHandle* service_worker_handle, 105 ServiceWorkerNavigationHandle* service_worker_navigation_handle,
62 AppCacheNavigationHandle* appcache_handle, 106 AppCacheNavigationHandle* appcache_handle,
63 NavigationURLLoaderDelegate* delegate) 107 NavigationURLLoaderDelegate* delegate)
64 : delegate_(delegate), binding_(this), weak_factory_(this) { 108 : delegate_(delegate), binding_(this), weak_factory_(this) {
65 DCHECK_CURRENTLY_ON(BrowserThread::UI); 109 DCHECK_CURRENTLY_ON(BrowserThread::UI);
66 110
67 TRACE_EVENT_ASYNC_BEGIN_WITH_TIMESTAMP1( 111 TRACE_EVENT_ASYNC_BEGIN_WITH_TIMESTAMP1(
68 "navigation", "Navigation timeToResponseStarted", this, 112 "navigation", "Navigation timeToResponseStarted", this,
69 request_info->common_params.navigation_start, "FrameTreeNode id", 113 request_info->common_params.navigation_start, "FrameTreeNode id",
70 request_info->frame_tree_node_id); 114 request_info->frame_tree_node_id);
71 115
(...skipping 19 matching lines...) Expand all
91 if (request_info->is_main_frame) 135 if (request_info->is_main_frame)
92 load_flags |= net::LOAD_MAIN_FRAME_DEPRECATED; 136 load_flags |= net::LOAD_MAIN_FRAME_DEPRECATED;
93 137
94 // Sync loads should have maximum priority and should be the only 138 // Sync loads should have maximum priority and should be the only
95 // requests that have the ignore limits flag set. 139 // requests that have the ignore limits flag set.
96 DCHECK(!(load_flags & net::LOAD_IGNORE_LIMITS)); 140 DCHECK(!(load_flags & net::LOAD_IGNORE_LIMITS));
97 141
98 new_request->load_flags = load_flags; 142 new_request->load_flags = load_flags;
99 143
100 new_request->request_body = request_info->common_params.post_data.get(); 144 new_request->request_body = request_info->common_params.post_data.get();
101 if (new_request->request_body.get()) { 145
102 // The request body may need blob handles to be added to it. This 146 ResourceType resource_type = request_info->is_main_frame
103 // functionality has to be invoked on the IO thread. 147 ? RESOURCE_TYPE_MAIN_FRAME
148 : RESOURCE_TYPE_SUB_FRAME;
149 RequestContextFrameType frame_type =
150 request_info->is_main_frame ? REQUEST_CONTEXT_FRAME_TYPE_TOP_LEVEL
151 : REQUEST_CONTEXT_FRAME_TYPE_NESTED;
152
153 // Determine where the request will be serviced. If there's work that needs to
154 // be done on the IO thread due to Service Worker or POST body, then post to
155 // the IO thread to have it do that work, and then continue on to
156 // StartURLRequest. Otherwise, handle the request directly.
157 const bool need_to_work_on_io =
158 service_worker_navigation_handle || new_request->request_body;
159 if (need_to_work_on_io) {
104 BrowserThread::PostTask( 160 BrowserThread::PostTask(
105 BrowserThread::IO, FROM_HERE, 161 BrowserThread::IO, FROM_HERE,
106 base::Bind(&HandleRequestsWithBody, 162 base::Bind(
107 base::Passed(&new_request), 163 &NavigationStartupWorkOnIO, base::Passed(std::move(new_request)),
108 resource_context, 164 resource_context,
109 weak_factory_.GetWeakPtr())); 165 service_worker_navigation_handle
166 ? service_worker_navigation_handle->core()
167 : nullptr,
168 request_info->begin_params.skip_service_worker, resource_type,
169 request_info->begin_params.request_context_type, frame_type,
170 request_info->are_ancestors_secure,
171 request_info->common_params.post_data,
172 base::Bind(&GetWebContentsFromFrameTreeNodeID,
173 request_info->frame_tree_node_id),
174 base::Bind(&NavigationURLLoaderNetworkService::StartURLRequest,
175 weak_factory_.GetWeakPtr())));
110 return; 176 return;
111 } 177 }
112 178
113 StartURLRequest(std::move(new_request)); 179 StartURLRequest(mojom::URLLoaderFactoryPtrInfo(), std::move(new_request));
114 } 180 }
115 181
116 NavigationURLLoaderNetworkService::~NavigationURLLoaderNetworkService() {} 182 NavigationURLLoaderNetworkService::~NavigationURLLoaderNetworkService() {}
117 183
118 void NavigationURLLoaderNetworkService::OverrideURLLoaderFactoryForTesting( 184 void NavigationURLLoaderNetworkService::OverrideURLLoaderFactoryForTesting(
119 mojom::URLLoaderFactoryPtr url_loader_factory) { 185 mojom::URLLoaderFactoryPtr url_loader_factory) {
120 g_url_loader_factory.Get() = std::move(url_loader_factory); 186 g_direct_network_url_loader_factory.Get() = std::move(url_loader_factory);
121 } 187 }
122 188
123 void NavigationURLLoaderNetworkService::FollowRedirect() { 189 void NavigationURLLoaderNetworkService::FollowRedirect() {
124 url_loader_associated_ptr_->FollowRedirect(); 190 url_loader_associated_ptr_->FollowRedirect();
125 } 191 }
126 192
127 void NavigationURLLoaderNetworkService::ProceedWithResponse() {} 193 void NavigationURLLoaderNetworkService::ProceedWithResponse() {}
128 194
129 void NavigationURLLoaderNetworkService::OnReceiveResponse( 195 void NavigationURLLoaderNetworkService::OnReceiveResponse(
130 const ResourceResponseHead& head, 196 const ResourceResponseHead& head,
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
186 TRACE_EVENT_ASYNC_END2("navigation", "Navigation timeToResponseStarted", 252 TRACE_EVENT_ASYNC_END2("navigation", "Navigation timeToResponseStarted",
187 this, "&NavigationURLLoaderNetworkService", this, 253 this, "&NavigationURLLoaderNetworkService", this,
188 "success", false); 254 "success", false);
189 255
190 delegate_->OnRequestFailed(completion_status.exists_in_cache, 256 delegate_->OnRequestFailed(completion_status.exists_in_cache,
191 completion_status.error_code); 257 completion_status.error_code);
192 } 258 }
193 } 259 }
194 260
195 void NavigationURLLoaderNetworkService::StartURLRequest( 261 void NavigationURLLoaderNetworkService::StartURLRequest(
262 mojom::URLLoaderFactoryPtrInfo url_loader_factory_info,
196 std::unique_ptr<ResourceRequest> request) { 263 std::unique_ptr<ResourceRequest> request) {
197 DCHECK_CURRENTLY_ON(BrowserThread::UI); 264 DCHECK_CURRENTLY_ON(BrowserThread::UI);
198 265
266 // If a URLLoaderFactory was provided, then we use that one, otherwise
267 // fall back to connecting directly to the network service.
268 if (url_loader_factory_info.is_valid()) {
269 url_loader_factory_.Bind(std::move(url_loader_factory_info));
270 } else {
271 if (!g_direct_network_url_loader_factory.Get()) {
272 ServiceManagerConnection::GetForProcess()->GetConnector()->BindInterface(
273 mojom::kNetworkServiceName,
274 &g_direct_network_url_loader_factory.Get());
275 }
276 url_loader_factory_ = std::move(g_direct_network_url_loader_factory.Get());
277 }
278
279 // Bind the URLClient implementation to this object to pass to the URLLoader.
199 mojom::URLLoaderClientPtr url_loader_client_ptr_to_pass; 280 mojom::URLLoaderClientPtr url_loader_client_ptr_to_pass;
200 binding_.Bind(&url_loader_client_ptr_to_pass); 281 binding_.Bind(&url_loader_client_ptr_to_pass);
201 282
202 GetURLLoaderFactory().CreateLoaderAndStart( 283 // Use the URLLoaderFactory to create a URLLoader that uses |binding_| as the
284 // URLLoaderClient.
285 url_loader_factory_->CreateLoaderAndStart(
203 mojo::MakeRequest(&url_loader_associated_ptr_), 0 /* routing_id? */, 286 mojo::MakeRequest(&url_loader_associated_ptr_), 0 /* routing_id? */,
204 0 /* request_id? */, mojom::kURLLoadOptionSendSSLInfo, *request, 287 0 /* request_id? */, mojom::kURLLoadOptionSendSSLInfo, *request,
205 std::move(url_loader_client_ptr_to_pass)); 288 std::move(url_loader_client_ptr_to_pass));
206 } 289 }
207 290
208 mojom::URLLoaderFactory&
209 NavigationURLLoaderNetworkService::GetURLLoaderFactory() {
210 // TODO(yzshen): We will need the ability to customize the factory per frame
211 // e.g., for appcache or service worker.
212 if (!g_url_loader_factory.Get()) {
213 ServiceManagerConnection::GetForProcess()->GetConnector()->BindInterface(
214 mojom::kNetworkServiceName, &g_url_loader_factory.Get());
215 }
216
217 return *g_url_loader_factory.Get();
218 }
219
220 } // namespace content 291 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698