| 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 fc4fb7ebb44b3d03035eeaf15baa705b2ea4cc4b..b51d3672e1dd295fccf30d715a06aa0baa832d29 100644
|
| --- a/content/browser/loader/navigation_url_loader_network_service.cc
|
| +++ b/content/browser/loader/navigation_url_loader_network_service.cc
|
| @@ -10,10 +10,17 @@
|
| #include "base/memory/ptr_util.h"
|
| #include "base/trace_event/trace_event.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_resource_handler.h"
|
| #include "content/browser/loader/navigation_resource_throttle.h"
|
| #include "content/browser/loader/navigation_url_loader_delegate.h"
|
| +#include "content/browser/resource_context_impl.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_request_handler.h"
|
| +#include "content/browser/web_contents/web_contents_impl.h"
|
| #include "content/public/browser/browser_thread.h"
|
| #include "content/public/browser/global_request_id.h"
|
| #include "content/public/browser/navigation_data.h"
|
| @@ -32,23 +39,60 @@ namespace content {
|
| namespace {
|
|
|
| static base::LazyInstance<mojom::URLLoaderFactoryPtr>::Leaky
|
| - g_url_loader_factory = LAZY_INSTANCE_INITIALIZER;
|
| + g_direct_network_url_loader_factory = LAZY_INSTANCE_INITIALIZER;
|
|
|
| -// 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,
|
| +using CompleteNavigationStart =
|
| + base::Callback<void(mojom::URLLoaderFactoryPtrInfo,
|
| + std::unique_ptr<ResourceRequest>)>;
|
| +
|
| +void NavigationStartupWorkOnIO(
|
| + std::unique_ptr<ResourceRequest> resource_request,
|
| ResourceContext* resource_context,
|
| - base::WeakPtr<NavigationURLLoaderNetworkService> url_loader) {
|
| + ServiceWorkerNavigationHandleCore* service_worker_navigation_handle_core,
|
| + bool skip_service_worker,
|
| + ResourceType resource_type,
|
| + RequestContextType request_context_type,
|
| + RequestContextFrameType frame_type,
|
| + bool is_parent_frame_secure,
|
| + scoped_refptr<ResourceRequestBodyImpl> body,
|
| + const base::Callback<WebContents*(void)>& web_contents_getter,
|
| + CompleteNavigationStart complete_request) {
|
| DCHECK_CURRENTLY_ON(BrowserThread::IO);
|
| - DCHECK(request->request_body.get());
|
| + DCHECK(service_worker_navigation_handle_core ||
|
| + resource_request->request_body.get());
|
| +
|
| + mojom::URLLoaderFactoryPtrInfo url_loader_factory_ptr_info;
|
| + if (service_worker_navigation_handle_core) {
|
| + storage::BlobStorageContext* blob_storage_context = GetBlobStorageContext(
|
| + GetChromeBlobStorageContextForResourceContext(resource_context));
|
| + url_loader_factory_ptr_info =
|
| + ServiceWorkerRequestHandler::InitializeForNavigationNetworkService(
|
| + *resource_request, resource_context,
|
| + service_worker_navigation_handle_core, blob_storage_context,
|
| + skip_service_worker, resource_type, request_context_type,
|
| + frame_type, is_parent_frame_secure, body, web_contents_getter);
|
| + }
|
| +
|
| + if (resource_request->request_body) {
|
| + AttachRequestBodyBlobDataHandles(resource_request->request_body.get(),
|
| + 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(resource_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
|
| @@ -58,7 +102,7 @@ NavigationURLLoaderNetworkService::NavigationURLLoaderNetworkService(
|
| 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) {
|
| @@ -98,26 +142,48 @@ 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.
|
| +
|
| + ResourceType resource_type = request_info->is_main_frame
|
| + ? RESOURCE_TYPE_MAIN_FRAME
|
| + : RESOURCE_TYPE_SUB_FRAME;
|
| + RequestContextFrameType frame_type =
|
| + request_info->is_main_frame ? REQUEST_CONTEXT_FRAME_TYPE_TOP_LEVEL
|
| + : REQUEST_CONTEXT_FRAME_TYPE_NESTED;
|
| +
|
| + // 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) {
|
| 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(new_request)),
|
| + resource_context,
|
| + service_worker_navigation_handle
|
| + ? service_worker_navigation_handle->core()
|
| + : nullptr,
|
| + request_info->begin_params.skip_service_worker, resource_type,
|
| + request_info->begin_params.request_context_type, frame_type,
|
| + request_info->are_ancestors_secure,
|
| + request_info->common_params.post_data,
|
| + base::Bind(&GetWebContentsFromFrameTreeNodeID,
|
| + request_info->frame_tree_node_id),
|
| + base::Bind(&NavigationURLLoaderNetworkService::StartURLRequest,
|
| + weak_factory_.GetWeakPtr())));
|
| return;
|
| }
|
|
|
| - StartURLRequest(std::move(new_request));
|
| + StartURLRequest(mojom::URLLoaderFactoryPtrInfo(), std::move(new_request));
|
| }
|
|
|
| NavigationURLLoaderNetworkService::~NavigationURLLoaderNetworkService() {}
|
|
|
| void NavigationURLLoaderNetworkService::OverrideURLLoaderFactoryForTesting(
|
| mojom::URLLoaderFactoryPtr url_loader_factory) {
|
| - g_url_loader_factory.Get() = std::move(url_loader_factory);
|
| + g_direct_network_url_loader_factory.Get() = std::move(url_loader_factory);
|
| }
|
|
|
| void NavigationURLLoaderNetworkService::FollowRedirect() {
|
| @@ -193,28 +259,33 @@ 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.
|
| + if (url_loader_factory_info.is_valid()) {
|
| + url_loader_factory_.Bind(std::move(url_loader_factory_info));
|
| + } else {
|
| + if (!g_direct_network_url_loader_factory.Get()) {
|
| + ServiceManagerConnection::GetForProcess()->GetConnector()->BindInterface(
|
| + mojom::kNetworkServiceName,
|
| + &g_direct_network_url_loader_factory.Get());
|
| + }
|
| + url_loader_factory_ = std::move(g_direct_network_url_loader_factory.Get());
|
| + }
|
| +
|
| + // Bind the URLClient implementation to this object to pass to the URLLoader.
|
| mojom::URLLoaderClientPtr url_loader_client_ptr_to_pass;
|
| binding_.Bind(&url_loader_client_ptr_to_pass);
|
|
|
| - GetURLLoaderFactory().CreateLoaderAndStart(
|
| + // 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,
|
| std::move(url_loader_client_ptr_to_pass));
|
| }
|
|
|
| -mojom::URLLoaderFactory&
|
| -NavigationURLLoaderNetworkService::GetURLLoaderFactory() {
|
| - // TODO(yzshen): We will need the ability to customize the factory per frame
|
| - // e.g., for appcache or service worker.
|
| - if (!g_url_loader_factory.Get()) {
|
| - ServiceManagerConnection::GetForProcess()->GetConnector()->BindInterface(
|
| - mojom::kNetworkServiceName, &g_url_loader_factory.Get());
|
| - }
|
| -
|
| - return *g_url_loader_factory.Get();
|
| -}
|
| -
|
| } // namespace content
|
|
|