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

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

Issue 2897063002: Network service: Implement URLLoader chaining for interceptors (Closed)
Patch Set: . 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 f32156a4074b47cda6e106d7ed12dbfde21c131b..36c6c984b870792d6e0c96fb72959c45c2cbfeb9 100644
--- a/content/browser/loader/navigation_url_loader_network_service.cc
+++ b/content/browser/loader/navigation_url_loader_network_service.cc
@@ -6,6 +6,7 @@
#include "base/bind.h"
#include "base/bind_helpers.h"
+#include "base/debug/stack_trace.h"
#include "base/memory/ptr_util.h"
#include "base/trace_event/trace_event.h"
#include "content/browser/appcache/appcache_navigation_handle.h"
@@ -15,6 +16,7 @@
#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/loader/url_loader_request_handler.h"
#include "content/browser/resource_context_impl.h"
#include "content/browser/service_worker/service_worker_navigation_handle.h"
#include "content/browser/service_worker/service_worker_navigation_handle_core.h"
@@ -54,72 +56,122 @@ WebContents* GetWebContentsFromFrameTreeNodeID(int frame_tree_node_id) {
return WebContentsImpl::FromFrameTreeNode(frame_tree_node);
}
-void PrepareNavigationStartOnIO(
- std::unique_ptr<ResourceRequest> resource_request,
- ResourceContext* resource_context,
- ServiceWorkerNavigationHandleCore* service_worker_navigation_handle_core,
- AppCacheNavigationHandleCore* appcache_handle_core,
- NavigationRequestInfo* request_info,
- mojom::URLLoaderFactoryPtrInfo factory_from_ui,
- scoped_refptr<URLLoaderFactoryGetter> url_loader_factory_getter,
- const base::Callback<WebContents*(void)>& web_contents_getter,
- mojom::URLLoaderAssociatedRequest url_loader_request,
- mojom::URLLoaderClientPtr url_loader_client_to_pass,
- std::unique_ptr<service_manager::Connector> connector) {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
-
- const ResourceType resource_type = request_info->is_main_frame
- ? RESOURCE_TYPE_MAIN_FRAME
- : RESOURCE_TYPE_SUB_FRAME;
-
- if (resource_request->request_body) {
- AttachRequestBodyBlobDataHandles(resource_request->request_body.get(),
- resource_context);
+} // namespace
+
+class NavigationURLLoaderNetworkService::URLLoaderRequestController
+ : public URLLoaderRequestHandler::Controller {
+ public:
+ URLLoaderRequestController(std::unique_ptr<ResourceRequest> resource_request,
+ ResourceContext* resource_context)
+ : resource_request_(std::move(resource_request)),
+ resource_context_(resource_context) {}
+
+ virtual ~URLLoaderRequestController() {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ }
+
+ void Start(
+ ServiceWorkerNavigationHandleCore* service_worker_navigation_handle_core,
+ AppCacheNavigationHandleCore* appcache_handle_core,
+ std::unique_ptr<NavigationRequestInfo> request_info,
+ mojom::URLLoaderFactoryPtrInfo factory_for_webui,
+ scoped_refptr<URLLoaderFactoryGetter> url_loader_factory_getter,
+ const base::Callback<WebContents*(void)>& web_contents_getter,
+ mojom::URLLoaderAssociatedRequest url_loader_request,
+ mojom::URLLoaderClientPtr url_loader_client_ptr,
+ std::unique_ptr<service_manager::Connector> connector) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ const ResourceType resource_type = request_info->is_main_frame
+ ? RESOURCE_TYPE_MAIN_FRAME
+ : RESOURCE_TYPE_SUB_FRAME;
+
+ if (resource_request_->request_body) {
+ AttachRequestBodyBlobDataHandles(resource_request_->request_body.get(),
+ resource_context_);
+ }
+
+ // Requests to WebUI scheme won't get redirected to/from other schemes
+ // or be intercepted, so we just let it go here.
michaeln 2017/05/26 01:28:31 nice clarifying change to rearrange the order
+ if (factory_for_webui.is_valid()) {
+ fallback_factory_ptr_.Bind(std::move(factory_for_webui));
+ fallback_factory_ = fallback_factory_ptr_.get();
+ Restart(std::move(url_loader_request), std::move(url_loader_client_ptr));
+ return;
+ }
+
michaeln 2017/05/26 01:28:30 i think blob scheme handling will goes here too, m
+ DCHECK(handlers_.empty());
+ if (service_worker_navigation_handle_core) {
+ RequestContextFrameType frame_type =
+ request_info->is_main_frame ? REQUEST_CONTEXT_FRAME_TYPE_TOP_LEVEL
+ : REQUEST_CONTEXT_FRAME_TYPE_NESTED;
+
+ storage::BlobStorageContext* blob_storage_context = GetBlobStorageContext(
+ GetChromeBlobStorageContextForResourceContext(resource_context_));
+ std::unique_ptr<URLLoaderRequestHandler> service_worker_handler =
+ ServiceWorkerRequestHandler::InitializeForNavigationNetworkService(
+ *resource_request_, resource_context_,
+ service_worker_navigation_handle_core, blob_storage_context,
+ 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, web_contents_getter);
+ if (service_worker_handler)
+ handlers_.push_back(std::move(service_worker_handler));
+ }
+
+ if (appcache_handle_core) {
+ // TODO: add appcache code here.
+ }
+
+ DCHECK(!fallback_factory_);
+ fallback_factory_ = url_loader_factory_getter->GetNetworkFactory()->get();
+
+ Restart(std::move(url_loader_request), std::move(url_loader_client_ptr));
}
- mojom::URLLoaderFactoryPtr url_loader_factory_ptr;
- if (service_worker_navigation_handle_core) {
- RequestContextFrameType frame_type =
- request_info->is_main_frame ? REQUEST_CONTEXT_FRAME_TYPE_TOP_LEVEL
- : REQUEST_CONTEXT_FRAME_TYPE_NESTED;
-
- storage::BlobStorageContext* blob_storage_context = GetBlobStorageContext(
- GetChromeBlobStorageContextForResourceContext(resource_context));
- url_loader_factory_ptr =
- ServiceWorkerRequestHandler::InitializeForNavigationNetworkService(
- *resource_request, resource_context,
- service_worker_navigation_handle_core, blob_storage_context,
- 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, web_contents_getter);
+ // This could be called multiple times.
+ void Restart(mojom::URLLoaderAssociatedRequest url_loader_request,
+ mojom::URLLoaderClientPtr url_loader_client_ptr) {
+ handler_index_ = 0;
+ DCHECK(url_loader_client_ptr.is_bound());
+ Forward(std::move(url_loader_request), std::move(url_loader_client_ptr));
}
- // If we haven't gotten one from the above, then use the one the UI thread
- // gave us, or otherwise fallback to the default.
- mojom::URLLoaderFactory* factory;
- if (url_loader_factory_ptr) {
- factory = url_loader_factory_ptr.get();
- } else {
- if (factory_from_ui.is_valid()) {
- url_loader_factory_ptr.Bind(std::move(factory_from_ui));
- factory = url_loader_factory_ptr.get();
- } else {
- if (appcache_handle_core) {
- factory = url_loader_factory_getter->GetAppCacheFactory()->get();
- } else {
- factory = url_loader_factory_getter->GetNetworkFactory()->get();
- }
+ // This could be called multiple times.
scottmg 2017/05/25 15:12:24 nit; comment that this is URLLoaderRH::Controller.
kinuko 2017/05/26 14:30:05 (Removed the Controller interface)
+ void Forward(mojom::URLLoaderAssociatedRequest url_loader_request,
+ mojom::URLLoaderClientPtr url_loader_client_ptr) override {
+ DCHECK(url_loader_client_ptr.is_bound());
+
+ if (handler_index_ < handlers_.size()) {
+ handlers_[handler_index_++]->Start(
+ *resource_request_, this, resource_context_,
+ std::move(url_loader_request), std::move(url_loader_client_ptr));
+ return;
+ }
+
+ if (!url_loader_client_ptr.is_bound()) {
+ base::debug::StackTrace trace;
jam 2017/05/25 16:06:37 nit: is this still needed?
kinuko 2017/05/26 02:34:20 Of course not :)
kinuko 2017/05/26 14:30:05 Removed.
+ LOG(ERROR) << trace.ToString();
}
+ DCHECK_EQ(handlers_.size(), handler_index_);
+ fallback_factory_->CreateLoaderAndStart(
+ std::move(url_loader_request), 0 /* routing_id? */, 0 /* request_id? */,
+ mojom::kURLLoadOptionSendSSLInfo, *resource_request_,
+ std::move(url_loader_client_ptr));
}
- factory->CreateLoaderAndStart(
- std::move(url_loader_request), 0 /* routing_id? */, 0 /* request_id? */,
- mojom::kURLLoadOptionSendSSLInfo, *resource_request,
- std::move(url_loader_client_to_pass));
-}
+ private:
+ std::vector<std::unique_ptr<URLLoaderRequestHandler>> handlers_;
+ size_t handler_index_ = 0;
-} // namespace
+ std::unique_ptr<ResourceRequest> resource_request_;
+ ResourceContext* resource_context_;
+
+ mojom::URLLoaderFactoryPtr fallback_factory_ptr_;
+ mojom::URLLoaderFactory* fallback_factory_;
+
+ DISALLOW_COPY_AND_ASSIGN(URLLoaderRequestController);
+};
NavigationURLLoaderNetworkService::NavigationURLLoaderNetworkService(
ResourceContext* resource_context,
@@ -129,36 +181,34 @@ NavigationURLLoaderNetworkService::NavigationURLLoaderNetworkService(
ServiceWorkerNavigationHandle* service_worker_navigation_handle,
AppCacheNavigationHandle* appcache_handle,
NavigationURLLoaderDelegate* delegate)
- : delegate_(delegate),
- binding_(this),
- request_info_(std::move(request_info)) {
+ : delegate_(delegate), binding_(this) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
TRACE_EVENT_ASYNC_BEGIN_WITH_TIMESTAMP1(
"navigation", "Navigation timeToResponseStarted", this,
- request_info_->common_params.navigation_start, "FrameTreeNode id",
- request_info_->frame_tree_node_id);
+ request_info->common_params.navigation_start, "FrameTreeNode id",
+ request_info->frame_tree_node_id);
// TODO(scottmg): Port over stuff from RDHI::BeginNavigationRequest() here.
auto new_request = base::MakeUnique<ResourceRequest>();
- new_request->method = request_info_->common_params.method;
- new_request->url = request_info_->common_params.url;
- new_request->first_party_for_cookies = request_info_->first_party_for_cookies;
+ new_request->method = request_info->common_params.method;
+ new_request->url = request_info->common_params.url;
+ new_request->first_party_for_cookies = request_info->first_party_for_cookies;
new_request->priority = net::HIGHEST;
// The code below to set fields like request_initiator, referrer, etc has
// been copied from ResourceDispatcherHostImpl. We did not refactor the
// common code into a function, because RDHI uses accessor functions on the
// URLRequest class to set these fields. whereas we use ResourceRequest here.
- new_request->request_initiator = request_info_->begin_params.initiator_origin;
- new_request->referrer = request_info_->common_params.referrer.url;
- new_request->referrer_policy = request_info_->common_params.referrer.policy;
- new_request->headers = request_info_->begin_params.headers;
+ new_request->request_initiator = request_info->begin_params.initiator_origin;
+ new_request->referrer = request_info->common_params.referrer.url;
+ new_request->referrer_policy = request_info->common_params.referrer.policy;
+ new_request->headers = request_info->begin_params.headers;
- int load_flags = request_info_->begin_params.load_flags;
+ int load_flags = request_info->begin_params.load_flags;
load_flags |= net::LOAD_VERIFY_EV_CERT;
- if (request_info_->is_main_frame)
+ if (request_info->is_main_frame)
load_flags |= net::LOAD_MAIN_FRAME_DEPRECATED;
// Sync loads should have maximum priority and should be the only
@@ -167,7 +217,9 @@ NavigationURLLoaderNetworkService::NavigationURLLoaderNetworkService(
new_request->load_flags = load_flags;
- new_request->request_body = request_info_->common_params.post_data.get();
+ new_request->request_body = request_info->common_params.post_data.get();
+
+ int frame_tree_node_id = request_info->frame_tree_node_id;
mojom::URLLoaderAssociatedRequest loader_associated_request =
mojo::MakeRequest(&url_loader_associated_ptr_);
@@ -181,33 +233,40 @@ NavigationURLLoaderNetworkService::NavigationURLLoaderNetworkService(
if (std::find(schemes.begin(), schemes.end(), new_request->url.scheme()) !=
schemes.end()) {
FrameTreeNode* frame_tree_node =
- FrameTreeNode::GloballyFindByID(request_info_->frame_tree_node_id);
+ FrameTreeNode::GloballyFindByID(frame_tree_node_id);
factory_ptr_info = GetWebUIURLLoader(frame_tree_node).PassInterface();
}
g_next_request_id--;
+ DCHECK(!request_controller_);
+ request_controller_ = base::MakeUnique<URLLoaderRequestController>(
+ std::move(new_request), resource_context);
BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
- base::Bind(&PrepareNavigationStartOnIO,
- base::Passed(std::move(new_request)), resource_context,
- service_worker_navigation_handle
- ? service_worker_navigation_handle->core()
- : nullptr,
- appcache_handle ? appcache_handle->core() : nullptr,
- request_info_.get(), base::Passed(std::move(factory_ptr_info)),
- static_cast<StoragePartitionImpl*>(storage_partition)
- ->url_loader_factory_getter(),
- base::Bind(&GetWebContentsFromFrameTreeNodeID,
- request_info_->frame_tree_node_id),
- base::Passed(std::move(loader_associated_request)),
- base::Passed(std::move(url_loader_client_ptr_to_pass)),
- base::Passed(ServiceManagerConnection::GetForProcess()
- ->GetConnector()
- ->Clone())));
+ base::Bind(
+ &URLLoaderRequestController::Start,
+ base::Unretained(request_controller_.get()),
+ service_worker_navigation_handle
+ ? service_worker_navigation_handle->core()
+ : nullptr,
+ appcache_handle ? appcache_handle->core() : nullptr,
+ base::Passed(std::move(request_info)),
+ base::Passed(std::move(factory_ptr_info)),
+ static_cast<StoragePartitionImpl*>(storage_partition)
+ ->url_loader_factory_getter(),
+ base::Bind(&GetWebContentsFromFrameTreeNodeID, frame_tree_node_id),
+ base::Passed(std::move(loader_associated_request)),
+ base::Passed(std::move(url_loader_client_ptr_to_pass)),
+ base::Passed(ServiceManagerConnection::GetForProcess()
+ ->GetConnector()
+ ->Clone())));
}
-NavigationURLLoaderNetworkService::~NavigationURLLoaderNetworkService() {}
+NavigationURLLoaderNetworkService::~NavigationURLLoaderNetworkService() {
+ BrowserThread::DeleteSoon(BrowserThread::IO, FROM_HERE,
+ request_controller_.release());
+}
void NavigationURLLoaderNetworkService::FollowRedirect() {
url_loader_associated_ptr_->FollowRedirect();
@@ -232,6 +291,8 @@ void NavigationURLLoaderNetworkService::OnReceiveRedirect(
const net::RedirectInfo& redirect_info,
const ResourceResponseHead& head) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ // TODO(kinuko): Perform the necessary check and call
+ // URLLoaderRequestController::Restart with the new URL??
scoped_refptr<ResourceResponse> response(new ResourceResponse());
response->head = head;
delegate_->OnRequestRedirected(redirect_info, response);

Powered by Google App Engine
This is Rietveld 408576698