Chromium Code Reviews| Index: content/browser/loader/navigation_url_loader_network_service.cc |
| diff --git a/content/browser/loader/navigation_url_loader_network_service.cc b/content/browser/loader/navigation_url_loader_network_service.cc |
| index e358cb19ec3e8e478b6e9cae5d94e20f4eb0d576..90ba3db00e9d017681ed73a09ea65d8267148a49 100644 |
| --- a/content/browser/loader/navigation_url_loader_network_service.cc |
| +++ b/content/browser/loader/navigation_url_loader_network_service.cc |
| @@ -26,8 +26,11 @@ |
| #include "content/browser/web_contents/web_contents_impl.h" |
| #include "content/browser/webui/url_data_manager_backend.h" |
| #include "content/browser/webui/web_ui_url_loader_factory.h" |
| +#include "content/common/throttling_url_loader.h" |
| +#include "content/common/url_loader_factory.mojom.h" |
| #include "content/public/browser/browser_context.h" |
| #include "content/public/browser/browser_thread.h" |
| +#include "content/public/browser/content_browser_client.h" |
| #include "content/public/browser/global_request_id.h" |
| #include "content/public/browser/navigation_data.h" |
| #include "content/public/browser/navigation_ui_data.h" |
| @@ -35,9 +38,9 @@ |
| #include "content/public/browser/stream_handle.h" |
| #include "content/public/common/referrer.h" |
| #include "content/public/common/url_constants.h" |
| -#include "mojo/public/cpp/bindings/strong_binding.h" |
| #include "net/base/load_flags.h" |
| #include "net/url_request/url_request_context.h" |
| +#include "services/service_manager/public/cpp/connector.h" |
| namespace content { |
| @@ -57,41 +60,6 @@ WebContents* GetWebContentsFromFrameTreeNodeID(int frame_tree_node_id) { |
| return WebContentsImpl::FromFrameTreeNode(frame_tree_node); |
| } |
| -class AssociatedURLLoaderWrapper final : public mojom::URLLoader { |
| - public: |
| - static void CreateLoaderAndStart(mojom::URLLoaderFactory* factory, |
| - mojom::URLLoaderRequest request, |
| - uint32_t options, |
| - const ResourceRequest& resource_request, |
| - mojom::URLLoaderClientPtr client) { |
| - mojom::URLLoaderAssociatedPtr associated_ptr; |
| - mojom::URLLoaderAssociatedRequest associated_request = |
| - mojo::MakeRequest(&associated_ptr); |
| - factory->CreateLoaderAndStart(std::move(associated_request), |
| - 0 /* routing_id */, 0 /* request_id */, |
| - options, resource_request, std::move(client)); |
| - mojo::MakeStrongBinding( |
| - base::MakeUnique<AssociatedURLLoaderWrapper>(std::move(associated_ptr)), |
| - std::move(request)); |
| - } |
| - |
| - explicit AssociatedURLLoaderWrapper( |
| - mojom::URLLoaderAssociatedPtr associated_ptr) |
| - : associated_ptr_(std::move(associated_ptr)) {} |
| - ~AssociatedURLLoaderWrapper() override {} |
| - |
| - void FollowRedirect() override { associated_ptr_->FollowRedirect(); } |
| - |
| - void SetPriority(net::RequestPriority priority, |
| - int intra_priority_value) override { |
| - associated_ptr_->SetPriority(priority, intra_priority_value); |
| - } |
| - |
| - private: |
| - mojom::URLLoaderAssociatedPtr associated_ptr_; |
| - DISALLOW_COPY_AND_ASSIGN(AssociatedURLLoaderWrapper); |
| -}; |
| - |
| } // namespace |
| // Kept around during the lifetime of the navigation request, and is |
| @@ -100,17 +68,20 @@ class AssociatedURLLoaderWrapper final : public mojom::URLLoader { |
| // of URLLoaderRequestHandler's and successively calls MaybeCreateLoader |
| // on each until the request is successfully handled. The same sequence |
| // may be performed multiple times when redirects happen. |
| -class NavigationURLLoaderNetworkService::URLLoaderRequestController { |
| +class NavigationURLLoaderNetworkService::URLLoaderRequestController |
| + : public mojom::URLLoaderClient { |
| public: |
| URLLoaderRequestController( |
| std::unique_ptr<ResourceRequest> resource_request, |
| ResourceContext* resource_context, |
| - scoped_refptr<URLLoaderFactoryGetter> url_loader_factory_getter) |
| + scoped_refptr<URLLoaderFactoryGetter> url_loader_factory_getter, |
| + const base::WeakPtr<NavigationURLLoaderNetworkService>& owner) |
| : resource_request_(std::move(resource_request)), |
| resource_context_(resource_context), |
| - url_loader_factory_getter_(url_loader_factory_getter) {} |
| + url_loader_factory_getter_(url_loader_factory_getter), |
| + owner_(owner) {} |
| - virtual ~URLLoaderRequestController() { |
| + ~URLLoaderRequestController() override { |
| DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| } |
| @@ -120,11 +91,9 @@ class NavigationURLLoaderNetworkService::URLLoaderRequestController { |
| std::unique_ptr<NavigationRequestInfo> request_info, |
| mojom::URLLoaderFactoryPtrInfo factory_for_webui, |
| const base::Callback<WebContents*(void)>& web_contents_getter, |
| - mojom::URLLoaderRequest url_loader_request, |
| - mojom::URLLoaderClientPtrInfo url_loader_client_ptr_info, |
| std::unique_ptr<service_manager::Connector> connector) { |
| DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| - url_loader_client_ptr_.Bind(std::move(url_loader_client_ptr_info)); |
| + web_contents_getter_ = web_contents_getter; |
| const ResourceType resource_type = request_info->is_main_frame |
| ? RESOURCE_TYPE_MAIN_FRAME |
| : RESOURCE_TYPE_SUB_FRAME; |
| @@ -137,12 +106,13 @@ class NavigationURLLoaderNetworkService::URLLoaderRequestController { |
| // Requests to WebUI scheme won't get redirected to/from other schemes |
| // or be intercepted, so we just let it go here. |
| if (factory_for_webui.is_valid()) { |
| - mojom::URLLoaderFactoryPtr factory_ptr; |
| - factory_ptr.Bind(std::move(factory_for_webui)); |
| - AssociatedURLLoaderWrapper::CreateLoaderAndStart( |
| - factory_ptr.get(), std::move(url_loader_request), |
| - mojom::kURLLoadOptionSendSSLInfo, *resource_request_, |
| - std::move(url_loader_client_ptr_)); |
| + webui_factory_ptr_.Bind(std::move(factory_for_webui)); |
| + url_loader_ = ThrottlingURLLoader::CreateLoaderAndStart( |
| + webui_factory_ptr_.get(), |
| + GetContentClient()->browser()->CreateURLLoaderThrottles( |
| + web_contents_getter_), |
| + 0 /* routing_id? */, 0 /* request_id? */, |
| + mojom::kURLLoadOptionSendSSLInfo, *resource_request_, this); |
| return; |
| } |
| @@ -174,25 +144,22 @@ class NavigationURLLoaderNetworkService::URLLoaderRequestController { |
| handlers_.push_back(std::move(appcache_handler)); |
| } |
| - Restart(std::move(url_loader_request), std::move(url_loader_client_ptr_)); |
| + Restart(); |
| } |
| // This could be called multiple times. |
| - void Restart(mojom::URLLoaderRequest url_loader_request, |
| - mojom::URLLoaderClientPtr url_loader_client_ptr) { |
| - url_loader_request_ = std::move(url_loader_request); |
| - url_loader_client_ptr_ = std::move(url_loader_client_ptr); |
| + void Restart() { |
| handler_index_ = 0; |
| MaybeStartLoader(StartLoaderCallback()); |
| } |
| void MaybeStartLoader(StartLoaderCallback start_loader_callback) { |
| - DCHECK(url_loader_client_ptr_.is_bound()); |
| - |
| if (start_loader_callback) { |
| - std::move(start_loader_callback) |
| - .Run(std::move(url_loader_request_), |
| - std::move(url_loader_client_ptr_)); |
| + url_loader_ = ThrottlingURLLoader::CreateLoaderAndStart( |
| + std::move(start_loader_callback), |
| + GetContentClient()->browser()->CreateURLLoaderThrottles( |
| + web_contents_getter_), |
| + *resource_request_, this); |
| return; |
| } |
| @@ -211,24 +178,82 @@ class NavigationURLLoaderNetworkService::URLLoaderRequestController { |
| } else { |
| factory = url_loader_factory_getter_->GetNetworkFactory()->get(); |
| } |
| - AssociatedURLLoaderWrapper::CreateLoaderAndStart( |
| - factory, std::move(url_loader_request_), |
| - mojom::kURLLoadOptionSendSSLInfo, *resource_request_, |
| - std::move(url_loader_client_ptr_)); |
| + url_loader_ = ThrottlingURLLoader::CreateLoaderAndStart( |
| + factory, |
| + GetContentClient()->browser()->CreateURLLoaderThrottles( |
| + web_contents_getter_), |
| + 0 /* routing_id? */, 0 /* request_id? */, |
| + mojom::kURLLoadOptionSendSSLInfo, *resource_request_, this); |
| + } |
| + |
| + void FollowRedirect() { |
| + DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| + DCHECK(url_loader_); |
| + |
| + url_loader_->FollowRedirect(); |
| } |
| private: |
| + // mojom::URLLoaderClient implementation: |
| + void OnReceiveResponse( |
| + const ResourceResponseHead& head, |
| + const base::Optional<net::SSLInfo>& ssl_info, |
| + mojom::DownloadedTempFilePtr downloaded_file) override { |
| + BrowserThread::PostTask( |
| + BrowserThread::UI, FROM_HERE, |
| + base::Bind(&NavigationURLLoaderNetworkService::OnReceiveResponse, |
| + owner_, head, ssl_info, base::Passed(&downloaded_file))); |
| + } |
| + |
| + void OnReceiveRedirect(const net::RedirectInfo& redirect_info, |
| + const ResourceResponseHead& head) override { |
| + BrowserThread::PostTask( |
| + BrowserThread::UI, FROM_HERE, |
| + base::Bind(&NavigationURLLoaderNetworkService::OnReceiveRedirect, |
| + owner_, redirect_info, head)); |
| + } |
| + |
| + void OnDataDownloaded(int64_t data_length, int64_t encoded_length) override {} |
| + |
| + void OnUploadProgress(int64_t current_position, |
| + int64_t total_size, |
| + OnUploadProgressCallback callback) override {} |
| + |
| + void OnReceiveCachedMetadata(const std::vector<uint8_t>& data) override {} |
| + |
| + void OnTransferSizeUpdated(int32_t transfer_size_diff) override {} |
| + |
| + void OnStartLoadingResponseBody( |
| + mojo::ScopedDataPipeConsumerHandle body) override { |
| + BrowserThread::PostTask( |
| + BrowserThread::UI, FROM_HERE, |
| + base::Bind( |
| + &NavigationURLLoaderNetworkService::OnStartLoadingResponseBody, |
| + owner_, base::Passed(&body))); |
| + } |
| + |
| + void OnComplete( |
| + const ResourceRequestCompletionStatus& completion_status) override { |
| + BrowserThread::PostTask( |
| + BrowserThread::UI, FROM_HERE, |
| + base::Bind(&NavigationURLLoaderNetworkService::OnComplete, owner_, |
| + completion_status)); |
| + } |
| + |
| std::vector<std::unique_ptr<URLLoaderRequestHandler>> handlers_; |
| size_t handler_index_ = 0; |
| std::unique_ptr<ResourceRequest> resource_request_; |
| ResourceContext* resource_context_; |
| + base::Callback<WebContents*()> web_contents_getter_; |
| scoped_refptr<URLLoaderFactoryGetter> url_loader_factory_getter_; |
| - // Kept around until we create a loader. |
| - mojom::URLLoaderRequest url_loader_request_; |
| - mojom::URLLoaderClientPtr url_loader_client_ptr_; |
| + mojom::URLLoaderFactoryPtr webui_factory_ptr_; |
| + |
| + std::unique_ptr<ThrottlingURLLoader> url_loader_; |
| + |
| + base::WeakPtr<NavigationURLLoaderNetworkService> owner_; |
|
kinuko
2017/06/12 12:39:19
Please comment that this is referenced only on UI
yzshen1
2017/06/12 20:12:31
Done.
|
| DISALLOW_COPY_AND_ASSIGN(URLLoaderRequestController); |
| }; |
| @@ -241,7 +266,7 @@ NavigationURLLoaderNetworkService::NavigationURLLoaderNetworkService( |
| ServiceWorkerNavigationHandle* service_worker_navigation_handle, |
| AppCacheNavigationHandle* appcache_handle, |
| NavigationURLLoaderDelegate* delegate) |
| - : delegate_(delegate), binding_(this) { |
| + : delegate_(delegate), weak_factory_(this) { |
| DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| TRACE_EVENT_ASYNC_BEGIN_WITH_TIMESTAMP1( |
| @@ -281,10 +306,6 @@ NavigationURLLoaderNetworkService::NavigationURLLoaderNetworkService( |
| int frame_tree_node_id = request_info->frame_tree_node_id; |
| - mojom::URLLoaderRequest loader_request = mojo::MakeRequest(&url_loader_ptr_); |
| - mojom::URLLoaderClientPtr url_loader_client_ptr_to_pass; |
| - binding_.Bind(mojo::MakeRequest(&url_loader_client_ptr_to_pass)); |
| - |
| // Check if a web UI scheme wants to handle this request. |
| mojom::URLLoaderFactoryPtrInfo factory_for_webui; |
| const auto& schemes = URLDataManagerBackend::GetWebUISchemes(); |
| @@ -301,7 +322,8 @@ NavigationURLLoaderNetworkService::NavigationURLLoaderNetworkService( |
| request_controller_ = base::MakeUnique<URLLoaderRequestController>( |
| std::move(new_request), resource_context, |
| static_cast<StoragePartitionImpl*>(storage_partition) |
| - ->url_loader_factory_getter()); |
| + ->url_loader_factory_getter(), |
| + weak_factory_.GetWeakPtr()); |
| BrowserThread::PostTask( |
| BrowserThread::IO, FROM_HERE, |
| base::Bind( |
| @@ -314,8 +336,6 @@ NavigationURLLoaderNetworkService::NavigationURLLoaderNetworkService( |
| base::Passed(std::move(request_info)), |
| base::Passed(std::move(factory_for_webui)), |
| base::Bind(&GetWebContentsFromFrameTreeNodeID, frame_tree_node_id), |
| - base::Passed(std::move(loader_request)), |
| - base::Passed(url_loader_client_ptr_to_pass.PassInterface()), |
| base::Passed(ServiceManagerConnection::GetForProcess() |
| ->GetConnector() |
| ->Clone()))); |
| @@ -327,7 +347,10 @@ NavigationURLLoaderNetworkService::~NavigationURLLoaderNetworkService() { |
| } |
| void NavigationURLLoaderNetworkService::FollowRedirect() { |
| - url_loader_ptr_->FollowRedirect(); |
| + BrowserThread::PostTask( |
| + BrowserThread::IO, FROM_HERE, |
| + base::Bind(&URLLoaderRequestController::FollowRedirect, |
| + base::Unretained(request_controller_.get()))); |
| } |
| void NavigationURLLoaderNetworkService::ProceedWithResponse() {} |
| @@ -356,21 +379,6 @@ void NavigationURLLoaderNetworkService::OnReceiveRedirect( |
| delegate_->OnRequestRedirected(redirect_info, response); |
| } |
| -void NavigationURLLoaderNetworkService::OnDataDownloaded( |
| - int64_t data_length, |
| - int64_t encoded_length) {} |
| - |
| -void NavigationURLLoaderNetworkService::OnUploadProgress( |
| - int64_t current_position, |
| - int64_t total_size, |
| - OnUploadProgressCallback callback) {} |
| - |
| -void NavigationURLLoaderNetworkService::OnReceiveCachedMetadata( |
| - const std::vector<uint8_t>& data) {} |
| - |
| -void NavigationURLLoaderNetworkService::OnTransferSizeUpdated( |
| - int32_t transfer_size_diff) {} |
| - |
| void NavigationURLLoaderNetworkService::OnStartLoadingResponseBody( |
| mojo::ScopedDataPipeConsumerHandle body) { |
| DCHECK(response_); |