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

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

Issue 2982363002: Add support for fallback content for the frame. This includes main and subframes. (Closed)
Patch Set: Remove newline Created 3 years, 4 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/memory/ptr_util.h" 9 #include "base/memory/ptr_util.h"
10 #include "base/trace_event/trace_event.h" 10 #include "base/trace_event/trace_event.h"
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
98 : public mojom::URLLoaderClient { 98 : public mojom::URLLoaderClient {
99 public: 99 public:
100 URLLoaderRequestController( 100 URLLoaderRequestController(
101 std::unique_ptr<ResourceRequest> resource_request, 101 std::unique_ptr<ResourceRequest> resource_request,
102 ResourceContext* resource_context, 102 ResourceContext* resource_context,
103 scoped_refptr<URLLoaderFactoryGetter> default_url_loader_factory_getter, 103 scoped_refptr<URLLoaderFactoryGetter> default_url_loader_factory_getter,
104 const base::WeakPtr<NavigationURLLoaderNetworkService>& owner) 104 const base::WeakPtr<NavigationURLLoaderNetworkService>& owner)
105 : resource_request_(std::move(resource_request)), 105 : resource_request_(std::move(resource_request)),
106 resource_context_(resource_context), 106 resource_context_(resource_context),
107 default_url_loader_factory_getter_(default_url_loader_factory_getter), 107 default_url_loader_factory_getter_(default_url_loader_factory_getter),
108 owner_(owner) {} 108 owner_(owner),
109 response_loader_binding_(this) {}
109 110
110 ~URLLoaderRequestController() override { 111 ~URLLoaderRequestController() override {
111 DCHECK_CURRENTLY_ON(BrowserThread::IO); 112 DCHECK_CURRENTLY_ON(BrowserThread::IO);
112 } 113 }
113 114
114 void Start( 115 void Start(
115 ServiceWorkerNavigationHandleCore* service_worker_navigation_handle_core, 116 ServiceWorkerNavigationHandleCore* service_worker_navigation_handle_core,
116 AppCacheNavigationHandleCore* appcache_handle_core, 117 AppCacheNavigationHandleCore* appcache_handle_core,
117 std::unique_ptr<NavigationRequestInfo> request_info, 118 std::unique_ptr<NavigationRequestInfo> request_info,
118 mojom::URLLoaderFactoryPtrInfo factory_for_webui, 119 mojom::URLLoaderFactoryPtrInfo factory_for_webui,
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
206 base::Unretained(this))); 207 base::Unretained(this)));
207 return; 208 return;
208 } 209 }
209 210
210 mojom::URLLoaderFactory* factory = nullptr; 211 mojom::URLLoaderFactory* factory = nullptr;
211 DCHECK_EQ(handlers_.size(), handler_index_); 212 DCHECK_EQ(handlers_.size(), handler_index_);
212 if (resource_request_->url.SchemeIs(url::kBlobScheme)) { 213 if (resource_request_->url.SchemeIs(url::kBlobScheme)) {
213 factory = default_url_loader_factory_getter_->GetBlobFactory()->get(); 214 factory = default_url_loader_factory_getter_->GetBlobFactory()->get();
214 } else { 215 } else {
215 factory = default_url_loader_factory_getter_->GetNetworkFactory()->get(); 216 factory = default_url_loader_factory_getter_->GetNetworkFactory()->get();
217 default_loader_used_ = true;
216 } 218 }
217 url_loader_ = ThrottlingURLLoader::CreateLoaderAndStart( 219 url_loader_ = ThrottlingURLLoader::CreateLoaderAndStart(
218 factory, 220 factory,
219 GetContentClient()->browser()->CreateURLLoaderThrottles( 221 GetContentClient()->browser()->CreateURLLoaderThrottles(
220 web_contents_getter_), 222 web_contents_getter_),
221 0 /* routing_id? */, 0 /* request_id? */, 223 0 /* routing_id? */, 0 /* request_id? */,
222 mojom::kURLLoadOptionSendSSLInfo | mojom::kURLLoadOptionSniffMimeType, 224 mojom::kURLLoadOptionSendSSLInfo | mojom::kURLLoadOptionSniffMimeType,
223 *resource_request_, this, kTrafficAnnotation); 225 *resource_request_, this, kTrafficAnnotation);
224 } 226 }
225 227
226 void FollowRedirect() { 228 void FollowRedirect() {
227 DCHECK_CURRENTLY_ON(BrowserThread::IO); 229 DCHECK_CURRENTLY_ON(BrowserThread::IO);
228 DCHECK(url_loader_); 230 DCHECK(url_loader_);
229 231
230 url_loader_->FollowRedirect(); 232 url_loader_->FollowRedirect();
kinuko 2017/07/28 09:50:29 It doesn't seem to happen in the current appcache
ananta 2017/07/28 22:59:22 Thanks. Done
231 } 233 }
232 234
233 // Ownership of the URLLoaderFactoryPtrInfo instance is transferred to the 235 // Ownership of the URLLoaderFactoryPtrInfo instance is transferred to the
234 // caller. 236 // caller.
235 mojom::URLLoaderFactoryPtrInfo GetSubresourceURLLoaderFactory() { 237 mojom::URLLoaderFactoryPtrInfo GetSubresourceURLLoaderFactory() {
236 return std::move(subresource_url_loader_factory_ptr_info_); 238 return std::move(subresource_url_loader_factory_ptr_info_);
237 } 239 }
238 240
239 private: 241 private:
240 // mojom::URLLoaderClient implementation: 242 // mojom::URLLoaderClient implementation:
241 void OnReceiveResponse( 243 void OnReceiveResponse(
242 const ResourceResponseHead& head, 244 const ResourceResponseHead& head,
243 const base::Optional<net::SSLInfo>& ssl_info, 245 const base::Optional<net::SSLInfo>& ssl_info,
244 mojom::DownloadedTempFilePtr downloaded_file) override { 246 mojom::DownloadedTempFilePtr downloaded_file) override {
247 response_ = head;
248 // If the default loader (network) was used to handle the URL load request
249 // we need to see if the handlers want to potentially create a new loader
250 // for the response. e.g. AppCache.
251 if (MaybeCreateLoaderForResponse(head))
252 return;
253
245 BrowserThread::PostTask( 254 BrowserThread::PostTask(
246 BrowserThread::UI, FROM_HERE, 255 BrowserThread::UI, FROM_HERE,
247 base::Bind(&NavigationURLLoaderNetworkService::OnReceiveResponse, 256 base::Bind(&NavigationURLLoaderNetworkService::OnReceiveResponse,
248 owner_, head, ssl_info, base::Passed(&downloaded_file))); 257 owner_, head, ssl_info, base::Passed(&downloaded_file)));
249 } 258 }
250 259
251 void OnReceiveRedirect(const net::RedirectInfo& redirect_info, 260 void OnReceiveRedirect(const net::RedirectInfo& redirect_info,
252 const ResourceResponseHead& head) override { 261 const ResourceResponseHead& head) override {
262 response_ = head;
263
253 BrowserThread::PostTask( 264 BrowserThread::PostTask(
254 BrowserThread::UI, FROM_HERE, 265 BrowserThread::UI, FROM_HERE,
255 base::Bind(&NavigationURLLoaderNetworkService::OnReceiveRedirect, 266 base::Bind(&NavigationURLLoaderNetworkService::OnReceiveRedirect,
256 owner_, redirect_info, head)); 267 owner_, redirect_info, head));
257 } 268 }
258 269
259 void OnDataDownloaded(int64_t data_length, int64_t encoded_length) override {} 270 void OnDataDownloaded(int64_t data_length, int64_t encoded_length) override {}
260 271
261 void OnUploadProgress(int64_t current_position, 272 void OnUploadProgress(int64_t current_position,
262 int64_t total_size, 273 int64_t total_size,
263 OnUploadProgressCallback callback) override {} 274 OnUploadProgressCallback callback) override {}
264 275
265 void OnReceiveCachedMetadata(const std::vector<uint8_t>& data) override {} 276 void OnReceiveCachedMetadata(const std::vector<uint8_t>& data) override {}
266 277
267 void OnTransferSizeUpdated(int32_t transfer_size_diff) override {} 278 void OnTransferSizeUpdated(int32_t transfer_size_diff) override {}
268 279
269 void OnStartLoadingResponseBody( 280 void OnStartLoadingResponseBody(
270 mojo::ScopedDataPipeConsumerHandle body) override { 281 mojo::ScopedDataPipeConsumerHandle body) override {
271 BrowserThread::PostTask( 282 BrowserThread::PostTask(
272 BrowserThread::UI, FROM_HERE, 283 BrowserThread::UI, FROM_HERE,
273 base::Bind( 284 base::Bind(
274 &NavigationURLLoaderNetworkService::OnStartLoadingResponseBody, 285 &NavigationURLLoaderNetworkService::OnStartLoadingResponseBody,
275 owner_, base::Passed(&body))); 286 owner_, base::Passed(&body)));
276 } 287 }
277 288
278 void OnComplete( 289 void OnComplete(
279 const ResourceRequestCompletionStatus& completion_status) override { 290 const ResourceRequestCompletionStatus& completion_status) override {
291 // If the default loader (network) was used to handle the URL load request
292 // we need to see if the handlers want to potentially create a new loader
293 // for the response. e.g. AppCache.
294 if (MaybeCreateLoaderForResponse(response_))
michaeln 2017/07/28 19:11:02 I think we should only call MaybeCreateLoaderForRe
ananta 2017/07/28 22:59:22 Thanks. I added a received_response_ flag which de
295 return;
296
280 BrowserThread::PostTask( 297 BrowserThread::PostTask(
281 BrowserThread::UI, FROM_HERE, 298 BrowserThread::UI, FROM_HERE,
282 base::Bind(&NavigationURLLoaderNetworkService::OnComplete, owner_, 299 base::Bind(&NavigationURLLoaderNetworkService::OnComplete, owner_,
283 completion_status)); 300 completion_status));
284 } 301 }
285 302
303 // Returns true if a handler wants to handle the response, i.e. return a
304 // different response. For e.g. AppCache may have fallback content to be
305 // returned for a TLD.
306 bool MaybeCreateLoaderForResponse(const ResourceResponseHead& response) {
307 if (!default_loader_used_)
308 return false;
309
310 for (size_t index = 0; index < handlers_.size(); ++index) {
311 if (handlers_[index]->MaybeCreateLoaderForResponse(
312 response, &response_url_loader_, &response_client_request_)) {
313 OnResponseHandlerFound();
314 return true;
315 }
316 }
317 return false;
318 }
319
320 // Called if we find a handler who delivers different content for the URL.
321 void OnResponseHandlerFound() {
322 response_loader_binding_.Bind(std::move(response_client_request_));
323 // We reset this flag as we expect a new response from the handler.
324 default_loader_used_ = false;
325 // Disconnect from the network loader to stop receiving further data
326 // or notifications for the URL.
327 url_loader_->DisconnectClient();
328 }
329
286 std::vector<std::unique_ptr<URLLoaderRequestHandler>> handlers_; 330 std::vector<std::unique_ptr<URLLoaderRequestHandler>> handlers_;
287 size_t handler_index_ = 0; 331 size_t handler_index_ = 0;
288 332
289 std::unique_ptr<ResourceRequest> resource_request_; 333 std::unique_ptr<ResourceRequest> resource_request_;
290 ResourceContext* resource_context_; 334 ResourceContext* resource_context_;
291 base::Callback<WebContents*()> web_contents_getter_; 335 base::Callback<WebContents*()> web_contents_getter_;
292 336
293 scoped_refptr<URLLoaderFactoryGetter> default_url_loader_factory_getter_; 337 scoped_refptr<URLLoaderFactoryGetter> default_url_loader_factory_getter_;
294 338
295 mojom::URLLoaderFactoryPtr webui_factory_ptr_; 339 mojom::URLLoaderFactoryPtr webui_factory_ptr_;
296 340
297 std::unique_ptr<ThrottlingURLLoader> url_loader_; 341 std::unique_ptr<ThrottlingURLLoader> url_loader_;
298 342
299 BlobHandles blob_handles_; 343 BlobHandles blob_handles_;
300 344
301 // Currently used by the AppCache loader to pass its factory to the 345 // Currently used by the AppCache loader to pass its factory to the
302 // renderer which enables it to handle subresources. 346 // renderer which enables it to handle subresources.
303 mojom::URLLoaderFactoryPtrInfo subresource_url_loader_factory_ptr_info_; 347 mojom::URLLoaderFactoryPtrInfo subresource_url_loader_factory_ptr_info_;
304 348
305 // This is referenced only on the UI thread. 349 // This is referenced only on the UI thread.
306 base::WeakPtr<NavigationURLLoaderNetworkService> owner_; 350 base::WeakPtr<NavigationURLLoaderNetworkService> owner_;
307 351
352 // Set to true if the default URLLoader (network service) was used for the
353 // current navigation.
354 bool default_loader_used_ = false;
355
356 // Contains a copy of the response.
357 ResourceResponseHead response_;
358
359 // URLLoaderClient binding for loaders created for responses received from the
360 // network loader.
361 mojo::Binding<mojom::URLLoaderClient> response_loader_binding_;
362
363 // URLLoader instance for response loaders, i.e loaders created for handing
364 // responses received from the network URLLoader.
365 mojom::URLLoaderPtr response_url_loader_;
366
367 // URLLoaderClient request pointer for response loaders, i.e loaders created
368 // for handing responses received from the network URLLoader.
369 mojom::URLLoaderClientRequest response_client_request_;
kinuko 2017/07/28 09:50:29 Does this need to be kept in this field? Can we j
ananta 2017/07/28 22:59:22 Done.
370
308 DISALLOW_COPY_AND_ASSIGN(URLLoaderRequestController); 371 DISALLOW_COPY_AND_ASSIGN(URLLoaderRequestController);
309 }; 372 };
310 373
311 NavigationURLLoaderNetworkService::NavigationURLLoaderNetworkService( 374 NavigationURLLoaderNetworkService::NavigationURLLoaderNetworkService(
312 ResourceContext* resource_context, 375 ResourceContext* resource_context,
313 StoragePartition* storage_partition, 376 StoragePartition* storage_partition,
314 std::unique_ptr<NavigationRequestInfo> request_info, 377 std::unique_ptr<NavigationRequestInfo> request_info,
315 std::unique_ptr<NavigationUIData> navigation_ui_data, 378 std::unique_ptr<NavigationUIData> navigation_ui_data,
316 ServiceWorkerNavigationHandle* service_worker_navigation_handle, 379 ServiceWorkerNavigationHandle* service_worker_navigation_handle,
317 AppCacheNavigationHandle* appcache_handle, 380 AppCacheNavigationHandle* appcache_handle,
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after
453 TRACE_EVENT_ASYNC_END2("navigation", "Navigation timeToResponseStarted", 516 TRACE_EVENT_ASYNC_END2("navigation", "Navigation timeToResponseStarted",
454 this, "&NavigationURLLoaderNetworkService", this, 517 this, "&NavigationURLLoaderNetworkService", this,
455 "success", false); 518 "success", false);
456 519
457 delegate_->OnRequestFailed(completion_status.exists_in_cache, 520 delegate_->OnRequestFailed(completion_status.exists_in_cache,
458 completion_status.error_code); 521 completion_status.error_code);
459 } 522 }
460 } 523 }
461 524
462 } // namespace content 525 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698