Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 Loading... | |
| 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(); |
| 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_)) | |
| 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; | |
|
kinuko
2017/07/28 03:34:51
One question- do we need to keep this here or can
ananta
2017/07/28 22:59:21
I always assumed that fallback was for network req
ananta
2017/07/29 01:21:45
We had talked about it couple weeks back. AppCache
| |
| 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_; | |
| 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 Loading... | |
| 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 |
| OLD | NEW |