Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(719)

Unified Diff: content/browser/loader/navigation_url_loader_network_service.cc

Issue 2843043002: network service: Create URLLoader for service worker navigation case
Patch Set: network fallback in simple cases Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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

Powered by Google App Engine
This is Rietveld 408576698