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 f6f5ba882512d4f27e875c51cbfcbddd355fe704..1670d89047818de7d899af6eee007272fb85bb44 100644 |
| --- a/content/browser/loader/navigation_url_loader_network_service.cc |
| +++ b/content/browser/loader/navigation_url_loader_network_service.cc |
| @@ -8,10 +8,18 @@ |
| #include "base/bind_helpers.h" |
| #include "base/memory/ptr_util.h" |
| #include "content/browser/blob_storage/chrome_blob_storage_context.h" |
| +#include "content/browser/frame_host/frame_tree_node.h" |
| #include "content/browser/frame_host/navigation_request_info.h" |
| +#include "content/browser/loader/navigation_factory_creation_data.h" |
| #include "content/browser/loader/navigation_resource_handler.h" |
| #include "content/browser/loader/navigation_resource_throttle.h" |
| #include "content/browser/loader/navigation_url_loader_delegate.h" |
| +#include "content/browser/service_worker/service_worker_context_wrapper.h" |
| +#include "content/browser/service_worker/service_worker_navigation_handle.h" |
| +#include "content/browser/service_worker/service_worker_navigation_handle_core.h" |
| +#include "content/browser/service_worker/service_worker_url_loader_factory_creation.h" |
| +#include "content/browser/web_contents/web_contents_impl.h" |
| +#include "content/common/url_loader_factory.mojom.h" |
| #include "content/public/browser/browser_thread.h" |
| #include "content/public/browser/global_request_id.h" |
| #include "content/public/browser/navigation_data.h" |
| @@ -27,39 +35,61 @@ |
| namespace content { |
| -// This function is called on the IO thread for POST/PUT requests for |
| -// attaching blob information to the request body. |
| -void HandleRequestsWithBody( |
| - std::unique_ptr<ResourceRequest> request, |
| - ResourceContext* resource_context, |
| - base::WeakPtr<NavigationURLLoaderNetworkService> url_loader) { |
| +namespace { |
| + |
| +using CompleteNavigationStart = |
| + base::Callback<void(mojom::URLLoaderFactoryPtrInfo, |
| + std::unique_ptr<ResourceRequest>)>; |
| + |
| +void NavigationStartupWorkOnIO( |
| + std::unique_ptr<NavigationFactoryCreationData> creation_data, |
| + CompleteNavigationStart complete_request) { |
| DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| - DCHECK(request->request_body.get()); |
| + DCHECK(creation_data->navigation_handle || |
| + creation_data->request->request_body.get()); |
| + |
| + mojom::URLLoaderFactoryPtrInfo url_loader_factory_ptr_info; |
| + if (creation_data->navigation_handle) { |
| + url_loader_factory_ptr_info = |
| + ServiceWorkerURLLoaderFactoryCreation::InitializeForNavigation( |
| + *creation_data); |
| + } |
| + |
| + if (creation_data->request->request_body) { |
| + AttachRequestBodyBlobDataHandles(creation_data->request->request_body.get(), |
| + creation_data->resource_context); |
| + } |
| - AttachRequestBodyBlobDataHandles(request->request_body.get(), |
| - resource_context); |
| BrowserThread::PostTask( |
| BrowserThread::UI, FROM_HERE, |
| - base::Bind(&NavigationURLLoaderNetworkService::StartURLRequest, |
| - url_loader, base::Passed(&request))); |
| + base::Bind(complete_request, |
| + base::Passed(std::move(url_loader_factory_ptr_info)), |
| + base::Passed(std::move(creation_data->request)))); |
| +} |
| + |
| +WebContents* GetWebContentsFromFrameTreeNodeID(int frame_tree_node_id) { |
| + DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| + FrameTreeNode* frame_tree_node = |
| + FrameTreeNode::GloballyFindByID(frame_tree_node_id); |
| + if (!frame_tree_node) |
| + return nullptr; |
| + |
| + return WebContentsImpl::FromFrameTreeNode(frame_tree_node); |
| } |
| +} // namespace |
| + |
| NavigationURLLoaderNetworkService::NavigationURLLoaderNetworkService( |
| ResourceContext* resource_context, |
| StoragePartition* storage_partition, |
| std::unique_ptr<NavigationRequestInfo> request_info, |
| std::unique_ptr<NavigationUIData> navigation_ui_data, |
| - ServiceWorkerNavigationHandle* service_worker_handle, |
| + ServiceWorkerNavigationHandle* service_worker_navigation_handle, |
| AppCacheNavigationHandle* appcache_handle, |
| NavigationURLLoaderDelegate* delegate) |
| : delegate_(delegate), binding_(this), weak_factory_(this) { |
| DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| - // TODO(scottmg): Maybe some of this setup should be done only once, instead |
| - // of every time. |
| - ServiceManagerConnection::GetForProcess()->GetConnector()->BindInterface( |
| - mojom::kNetworkServiceName, &url_loader_factory_); |
| - |
| // TODO(scottmg): Port over stuff from RDHI::BeginNavigationRequest() here. |
| auto new_request = base::MakeUnique<ResourceRequest>(); |
| @@ -89,19 +119,38 @@ NavigationURLLoaderNetworkService::NavigationURLLoaderNetworkService( |
| new_request->load_flags = load_flags; |
| new_request->request_body = request_info->common_params.post_data.get(); |
| - if (new_request->request_body.get()) { |
| - // The request body may need blob handles to be added to it. This |
| - // functionality has to be invoked on the IO thread. |
| + |
| + // Determine where the request will be serviced. If there's work that needs to |
| + // be done on the IO thread due to Service Worker or POST body, then post to |
| + // the IO thread to have it do that work, and then continue on to |
| + // StartURLRequest. Otherwise, handle the request directly. |
| + const bool need_to_work_on_io = |
| + service_worker_navigation_handle || new_request->request_body; |
| + if (need_to_work_on_io) { |
| + auto creation_data = base::MakeUnique<NavigationFactoryCreationData>(); |
| + creation_data->request = std::move(new_request); |
| + creation_data->navigation_handle = |
| + service_worker_navigation_handle |
| + ? service_worker_navigation_handle->core() |
| + : nullptr; |
| + creation_data->resource_context = resource_context; |
| + creation_data->web_contents_getter = base::Bind( |
| + &GetWebContentsFromFrameTreeNodeID, request_info->frame_tree_node_id); |
| + creation_data->resource_type = request_info->is_main_frame |
| + ? RESOURCE_TYPE_MAIN_FRAME |
| + : RESOURCE_TYPE_SUB_FRAME; |
| + creation_data->is_parent_frame_secure = request_info->are_ancestors_secure; |
| + |
| BrowserThread::PostTask( |
| BrowserThread::IO, FROM_HERE, |
| - base::Bind(&HandleRequestsWithBody, |
| - base::Passed(&new_request), |
| - resource_context, |
| - weak_factory_.GetWeakPtr())); |
| + base::Bind( |
| + &NavigationStartupWorkOnIO, base::Passed(std::move(creation_data)), |
| + base::Bind(&NavigationURLLoaderNetworkService::StartURLRequest, |
| + weak_factory_.GetWeakPtr()))); |
| return; |
| } |
| - StartURLRequest(std::move(new_request)); |
| + StartURLRequest(mojom::URLLoaderFactoryPtrInfo(), std::move(new_request)); |
| } |
| NavigationURLLoaderNetworkService::~NavigationURLLoaderNetworkService() {} |
| @@ -170,12 +219,25 @@ void NavigationURLLoaderNetworkService::OnComplete( |
| } |
| void NavigationURLLoaderNetworkService::StartURLRequest( |
| + mojom::URLLoaderFactoryPtrInfo url_loader_factory_info, |
| std::unique_ptr<ResourceRequest> request) { |
| DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| + // If a URLLoaderFactory was provided, then we use that one, otherwise |
| + // fall back to connecting directly to the network service. |
|
kinuko
2017/05/01 02:06:24
Initially this is probably ok, but we'll need netw
|
| + if (url_loader_factory_info.is_valid()) { |
| + url_loader_factory_.Bind(std::move(url_loader_factory_info)); |
| + } else { |
| + ServiceManagerConnection::GetForProcess()->GetConnector()->BindInterface( |
| + mojom::kNetworkServiceName, &url_loader_factory_); |
| + } |
| + |
| + // Bind the URLClient implementation to this object to pass to the URLLoader. |
|
kinuko
2017/05/01 02:06:24
nit: URLClient -> URLLoaderClient
|
| mojom::URLLoaderClientPtr url_loader_client_ptr_to_pass; |
| binding_.Bind(&url_loader_client_ptr_to_pass); |
| + // Use the URLLoaderFactory to create a URLLoader that uses |binding_| as the |
| + // URLLoaderClient. |
| url_loader_factory_->CreateLoaderAndStart( |
| mojo::MakeRequest(&url_loader_associated_ptr_), 0 /* routing_id? */, |
| 0 /* request_id? */, mojom::kURLLoadOptionSendSSLInfo, *request, |