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 fallback_response_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 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 207 base::Unretained(this))); | 208 base::Unretained(this))); |
| 208 return; | 209 return; |
| 209 } | 210 } |
| 210 | 211 |
| 211 mojom::URLLoaderFactory* factory = nullptr; | 212 mojom::URLLoaderFactory* factory = nullptr; |
| 212 DCHECK_EQ(handlers_.size(), handler_index_); | 213 DCHECK_EQ(handlers_.size(), handler_index_); |
| 213 if (resource_request_->url.SchemeIs(url::kBlobScheme)) { | 214 if (resource_request_->url.SchemeIs(url::kBlobScheme)) { |
| 214 factory = default_url_loader_factory_getter_->GetBlobFactory()->get(); | 215 factory = default_url_loader_factory_getter_->GetBlobFactory()->get(); |
| 215 } else { | 216 } else { |
| 216 factory = default_url_loader_factory_getter_->GetNetworkFactory()->get(); | 217 factory = default_url_loader_factory_getter_->GetNetworkFactory()->get(); |
| 218 default_loader_used_ = true; | |
| 217 } | 219 } |
| 218 url_loader_ = ThrottlingURLLoader::CreateLoaderAndStart( | 220 url_loader_ = ThrottlingURLLoader::CreateLoaderAndStart( |
| 219 factory, | 221 factory, |
| 220 GetContentClient()->browser()->CreateURLLoaderThrottles( | 222 GetContentClient()->browser()->CreateURLLoaderThrottles( |
| 221 web_contents_getter_), | 223 web_contents_getter_), |
| 222 0 /* routing_id? */, 0 /* request_id? */, | 224 0 /* routing_id? */, 0 /* request_id? */, |
| 223 mojom::kURLLoadOptionSendSSLInfo, *resource_request_, this, | 225 mojom::kURLLoadOptionSendSSLInfo, *resource_request_, this, |
| 224 kTrafficAnnotation); | 226 kTrafficAnnotation); |
| 225 } | 227 } |
| 226 | 228 |
| 227 void FollowRedirect() { | 229 void FollowRedirect() { |
| 228 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 230 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 229 DCHECK(url_loader_); | 231 DCHECK(url_loader_); |
| 230 | 232 |
| 231 url_loader_->FollowRedirect(); | 233 url_loader_->FollowRedirect(); |
| 232 } | 234 } |
| 233 | 235 |
| 234 // Ownership of the URLLoaderFactoryPtrInfo instance is transferred to the | 236 // Ownership of the URLLoaderFactoryPtrInfo instance is transferred to the |
| 235 // caller. | 237 // caller. |
| 236 mojom::URLLoaderFactoryPtrInfo GetSubresourceURLLoaderFactory() { | 238 mojom::URLLoaderFactoryPtrInfo GetSubresourceURLLoaderFactory() { |
| 237 return std::move(subresource_url_loader_factory_ptr_info_); | 239 return std::move(subresource_url_loader_factory_ptr_info_); |
| 238 } | 240 } |
| 239 | 241 |
| 240 private: | 242 private: |
| 241 // mojom::URLLoaderClient implementation: | 243 // mojom::URLLoaderClient implementation: |
| 242 void OnReceiveResponse( | 244 void OnReceiveResponse( |
| 243 const ResourceResponseHead& head, | 245 const ResourceResponseHead& head, |
| 244 const base::Optional<net::SSLInfo>& ssl_info, | 246 const base::Optional<net::SSLInfo>& ssl_info, |
| 245 mojom::DownloadedTempFilePtr downloaded_file) override { | 247 mojom::DownloadedTempFilePtr downloaded_file) override { |
| 248 response_ = head; | |
| 249 // If the default loader (network) was used to handle the URL load request | |
| 250 // we need to see if the handlers want to load a fallback for the response. | |
| 251 if (MaybeLoadFallbackForResponse(head)) | |
| 252 return; | |
| 253 | |
| 246 BrowserThread::PostTask( | 254 BrowserThread::PostTask( |
| 247 BrowserThread::UI, FROM_HERE, | 255 BrowserThread::UI, FROM_HERE, |
| 248 base::Bind(&NavigationURLLoaderNetworkService::OnReceiveResponse, | 256 base::Bind(&NavigationURLLoaderNetworkService::OnReceiveResponse, |
| 249 owner_, head, ssl_info, base::Passed(&downloaded_file))); | 257 owner_, head, ssl_info, base::Passed(&downloaded_file))); |
| 250 } | 258 } |
| 251 | 259 |
| 252 void OnReceiveRedirect(const net::RedirectInfo& redirect_info, | 260 void OnReceiveRedirect(const net::RedirectInfo& redirect_info, |
| 253 const ResourceResponseHead& head) override { | 261 const ResourceResponseHead& head) override { |
| 262 response_ = head; | |
| 263 | |
| 264 // If the default loader (network) was used to handle the URL load request | |
| 265 // we need to see if the handlers want to load a fallback for the response. | |
| 266 if (MaybeLoadFallbackForRedirect(head, redirect_info)) | |
| 267 return; | |
|
kinuko
2017/07/25 07:12:05
In my understanding we don't need this code at lea
ananta
2017/07/25 22:33:00
I think we need this code for same origin redirect
kinuko
2017/07/25 23:23:14
I was looking into this code where it seems we're
michaeln
2017/07/26 23:08:41
Right! We don't need redirect fallback handling fo
| |
| 268 | |
| 254 BrowserThread::PostTask( | 269 BrowserThread::PostTask( |
| 255 BrowserThread::UI, FROM_HERE, | 270 BrowserThread::UI, FROM_HERE, |
| 256 base::Bind(&NavigationURLLoaderNetworkService::OnReceiveRedirect, | 271 base::Bind(&NavigationURLLoaderNetworkService::OnReceiveRedirect, |
| 257 owner_, redirect_info, head)); | 272 owner_, redirect_info, head)); |
| 258 } | 273 } |
| 259 | 274 |
| 260 void OnDataDownloaded(int64_t data_length, int64_t encoded_length) override {} | 275 void OnDataDownloaded(int64_t data_length, int64_t encoded_length) override {} |
| 261 | 276 |
| 262 void OnUploadProgress(int64_t current_position, | 277 void OnUploadProgress(int64_t current_position, |
| 263 int64_t total_size, | 278 int64_t total_size, |
| 264 OnUploadProgressCallback callback) override {} | 279 OnUploadProgressCallback callback) override {} |
| 265 | 280 |
| 266 void OnReceiveCachedMetadata(const std::vector<uint8_t>& data) override {} | 281 void OnReceiveCachedMetadata(const std::vector<uint8_t>& data) override {} |
| 267 | 282 |
| 268 void OnTransferSizeUpdated(int32_t transfer_size_diff) override {} | 283 void OnTransferSizeUpdated(int32_t transfer_size_diff) override {} |
| 269 | 284 |
| 270 void OnStartLoadingResponseBody( | 285 void OnStartLoadingResponseBody( |
| 271 mojo::ScopedDataPipeConsumerHandle body) override { | 286 mojo::ScopedDataPipeConsumerHandle body) override { |
| 272 BrowserThread::PostTask( | 287 BrowserThread::PostTask( |
| 273 BrowserThread::UI, FROM_HERE, | 288 BrowserThread::UI, FROM_HERE, |
| 274 base::Bind( | 289 base::Bind( |
| 275 &NavigationURLLoaderNetworkService::OnStartLoadingResponseBody, | 290 &NavigationURLLoaderNetworkService::OnStartLoadingResponseBody, |
| 276 owner_, base::Passed(&body))); | 291 owner_, base::Passed(&body))); |
| 277 } | 292 } |
| 278 | 293 |
| 279 void OnComplete( | 294 void OnComplete( |
| 280 const ResourceRequestCompletionStatus& completion_status) override { | 295 const ResourceRequestCompletionStatus& completion_status) override { |
| 296 // If the default loader (network) was used to handle the URL load request | |
| 297 // we need to see if the handlers want to load a fallback for the response. | |
| 298 if (MaybeLoadFallbackForResponse(response_)) | |
| 299 return; | |
| 300 | |
| 281 BrowserThread::PostTask( | 301 BrowserThread::PostTask( |
| 282 BrowserThread::UI, FROM_HERE, | 302 BrowserThread::UI, FROM_HERE, |
| 283 base::Bind(&NavigationURLLoaderNetworkService::OnComplete, owner_, | 303 base::Bind(&NavigationURLLoaderNetworkService::OnComplete, owner_, |
| 284 completion_status)); | 304 completion_status)); |
| 285 } | 305 } |
| 286 | 306 |
| 307 // Returns true if a handler returns a fallback response. | |
| 308 bool MaybeLoadFallbackForResponse(const ResourceResponseHead& response) { | |
| 309 mojom::URLLoaderClientPtr fallback_client; | |
| 310 mojom::URLLoaderRequest fallback_request; | |
| 311 if (!CreateFallbackClientAndRequest(&fallback_client, &fallback_request)) | |
| 312 return false; | |
| 313 | |
| 314 for (size_t index = 0; index < handlers_.size(); ++index) { | |
| 315 if (handlers_[index]->MaybeGetFallbackForResponse( | |
| 316 response, &fallback_client, &fallback_request)) { | |
|
kinuko
2017/07/25 07:12:05
Hmm. Sorry I think I'm repeating the same comment
kinuko
2017/07/25 07:28:42
Or we could probably make MaybeCreateLoader take a
jam
2017/07/25 18:14:15
Yep this is what I meant :) it's a change from the
ananta
2017/07/25 22:33:00
I am not sure if transparently proxying to the n/w
ananta
2017/07/25 22:33:00
Perhaps I am missing something here. Seems like it
kinuko
2017/07/25 23:23:13
Hm, it sounds like a good point.
jam
2017/07/26 01:40:51
Can you expand on why it's desirable that the appc
kinuko
2017/07/26 01:59:14
One of the cases that come to my mind is like:
- a
michaeln
2017/07/26 23:08:41
I think its easier to reason about too if the appc
| |
| 317 OnFallbackHandlerFound(); | |
| 318 return true; | |
| 319 } | |
| 320 } | |
| 321 return false; | |
| 322 } | |
| 323 | |
| 324 // Returns true if a handler returns a fallback response for the redirect. | |
| 325 bool MaybeLoadFallbackForRedirect(const ResourceResponseHead& response, | |
| 326 const net::RedirectInfo& redirect_info) { | |
| 327 mojom::URLLoaderClientPtr fallback_client; | |
| 328 mojom::URLLoaderRequest fallback_request; | |
| 329 if (!CreateFallbackClientAndRequest(&fallback_client, &fallback_request)) | |
| 330 return false; | |
| 331 | |
| 332 for (size_t index = 0; index < handlers_.size(); ++index) { | |
| 333 if (handlers_[index]->MaybeGetFallbackForRedirect( | |
| 334 response, redirect_info, &fallback_client, &fallback_request)) { | |
| 335 OnFallbackHandlerFound(); | |
| 336 return true; | |
| 337 } | |
| 338 } | |
| 339 return false; | |
| 340 } | |
| 341 | |
| 342 // Creates an instance of the URLLoaderClient interface which can be bound | |
| 343 // to a handler for receiving fallback responses. | |
| 344 // Returns true on success. | |
| 345 bool CreateFallbackClientAndRequest(mojom::URLLoaderClientPtr* client, | |
| 346 mojom::URLLoaderRequest* request) { | |
| 347 // Ignore requests which were not sent to the network loader. | |
| 348 if (!default_loader_used_) | |
| 349 return false; | |
| 350 fallback_response_binding_.Bind(mojo::MakeRequest(client)); | |
| 351 *request = mojo::MakeRequest(&fallback_url_loader_); | |
| 352 return true; | |
| 353 } | |
| 354 | |
| 355 // Called if we find a handler who delivers fallback content for the URL. | |
| 356 void OnFallbackHandlerFound() { | |
| 357 // We reset this flag as we expect a response from the fallback handler. | |
| 358 default_loader_used_ = false; | |
| 359 // Disconnect from the network loader to stop receiving further data | |
| 360 // or notifications for the URL. | |
| 361 url_loader_->DisconnectClient(); | |
| 362 } | |
| 363 | |
| 287 std::vector<std::unique_ptr<URLLoaderRequestHandler>> handlers_; | 364 std::vector<std::unique_ptr<URLLoaderRequestHandler>> handlers_; |
| 288 size_t handler_index_ = 0; | 365 size_t handler_index_ = 0; |
| 289 | 366 |
| 290 std::unique_ptr<ResourceRequest> resource_request_; | 367 std::unique_ptr<ResourceRequest> resource_request_; |
| 291 ResourceContext* resource_context_; | 368 ResourceContext* resource_context_; |
| 292 base::Callback<WebContents*()> web_contents_getter_; | 369 base::Callback<WebContents*()> web_contents_getter_; |
| 293 | 370 |
| 294 scoped_refptr<URLLoaderFactoryGetter> default_url_loader_factory_getter_; | 371 scoped_refptr<URLLoaderFactoryGetter> default_url_loader_factory_getter_; |
| 295 | 372 |
| 296 mojom::URLLoaderFactoryPtr webui_factory_ptr_; | 373 mojom::URLLoaderFactoryPtr webui_factory_ptr_; |
| 297 | 374 |
| 298 std::unique_ptr<ThrottlingURLLoader> url_loader_; | 375 std::unique_ptr<ThrottlingURLLoader> url_loader_; |
| 299 | 376 |
| 300 BlobHandles blob_handles_; | 377 BlobHandles blob_handles_; |
| 301 | 378 |
| 302 // Currently used by the AppCache loader to pass its factory to the | 379 // Currently used by the AppCache loader to pass its factory to the |
| 303 // renderer which enables it to handle subresources. | 380 // renderer which enables it to handle subresources. |
| 304 mojom::URLLoaderFactoryPtrInfo subresource_url_loader_factory_ptr_info_; | 381 mojom::URLLoaderFactoryPtrInfo subresource_url_loader_factory_ptr_info_; |
| 305 | 382 |
| 306 // This is referenced only on the UI thread. | 383 // This is referenced only on the UI thread. |
| 307 base::WeakPtr<NavigationURLLoaderNetworkService> owner_; | 384 base::WeakPtr<NavigationURLLoaderNetworkService> owner_; |
| 308 | 385 |
| 386 // Set to true if the default URLLoader (network service) was used for the | |
| 387 // current navigation. | |
| 388 bool default_loader_used_ = false; | |
| 389 | |
| 390 // Contains a copy of the response. | |
| 391 ResourceResponseHead response_; | |
| 392 | |
| 393 // URLLoaderClient binding for handling fallback responses. | |
| 394 mojo::Binding<mojom::URLLoaderClient> fallback_response_binding_; | |
| 395 | |
| 396 // URLLoader instance for fallback responses. | |
| 397 mojom::URLLoaderPtr fallback_url_loader_; | |
| 398 | |
| 309 DISALLOW_COPY_AND_ASSIGN(URLLoaderRequestController); | 399 DISALLOW_COPY_AND_ASSIGN(URLLoaderRequestController); |
| 310 }; | 400 }; |
| 311 | 401 |
| 312 NavigationURLLoaderNetworkService::NavigationURLLoaderNetworkService( | 402 NavigationURLLoaderNetworkService::NavigationURLLoaderNetworkService( |
| 313 ResourceContext* resource_context, | 403 ResourceContext* resource_context, |
| 314 StoragePartition* storage_partition, | 404 StoragePartition* storage_partition, |
| 315 std::unique_ptr<NavigationRequestInfo> request_info, | 405 std::unique_ptr<NavigationRequestInfo> request_info, |
| 316 std::unique_ptr<NavigationUIData> navigation_ui_data, | 406 std::unique_ptr<NavigationUIData> navigation_ui_data, |
| 317 ServiceWorkerNavigationHandle* service_worker_navigation_handle, | 407 ServiceWorkerNavigationHandle* service_worker_navigation_handle, |
| 318 AppCacheNavigationHandle* appcache_handle, | 408 AppCacheNavigationHandle* appcache_handle, |
| (...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 454 TRACE_EVENT_ASYNC_END2("navigation", "Navigation timeToResponseStarted", | 544 TRACE_EVENT_ASYNC_END2("navigation", "Navigation timeToResponseStarted", |
| 455 this, "&NavigationURLLoaderNetworkService", this, | 545 this, "&NavigationURLLoaderNetworkService", this, |
| 456 "success", false); | 546 "success", false); |
| 457 | 547 |
| 458 delegate_->OnRequestFailed(completion_status.exists_in_cache, | 548 delegate_->OnRequestFailed(completion_status.exists_in_cache, |
| 459 completion_status.error_code); | 549 completion_status.error_code); |
| 460 } | 550 } |
| 461 } | 551 } |
| 462 | 552 |
| 463 } // namespace content | 553 } // namespace content |
| OLD | NEW |