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

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

Issue 519533002: Initial PlzNavigate RDH-side logic. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 years, 3 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/resource_dispatcher_host_impl.cc
diff --git a/content/browser/loader/resource_dispatcher_host_impl.cc b/content/browser/loader/resource_dispatcher_host_impl.cc
index 4df00ab3f9cfd9d86e0dfcd117cc3ca23668288e..f1b49062f3b00cac57ddbcbee51cf0c7ce2b364a 100644
--- a/content/browser/loader/resource_dispatcher_host_impl.cc
+++ b/content/browser/loader/resource_dispatcher_host_impl.cc
@@ -36,6 +36,7 @@
#include "content/browser/loader/buffered_resource_handler.h"
#include "content/browser/loader/cross_site_resource_handler.h"
#include "content/browser/loader/detachable_resource_handler.h"
+#include "content/browser/loader/navigation_resource_handler.h"
#include "content/browser/loader/power_save_block_resource_throttle.h"
#include "content/browser/loader/redirect_to_file_resource_handler.h"
#include "content/browser/loader/resource_message_filter.h"
@@ -65,6 +66,7 @@
#include "content/public/browser/resource_request_details.h"
#include "content/public/browser/resource_throttle.h"
#include "content/public/browser/stream_handle.h"
+#include "content/public/browser/stream_info.h"
#include "content/public/browser/user_metrics.h"
#include "content/public/common/content_switches.h"
#include "content/public/common/process_type.h"
@@ -303,10 +305,10 @@ bool IsValidatedSCT(
}
storage::BlobStorageContext* GetBlobStorageContext(
- ResourceMessageFilter* filter) {
- if (!filter->blob_storage_context())
+ ChromeBlobStorageContext* blob_storage_context) {
+ if (!blob_storage_context)
return NULL;
- return filter->blob_storage_context()->context();
+ return blob_storage_context->context();
}
void AttachRequestBodyBlobDataHandles(
@@ -467,15 +469,16 @@ void ResourceDispatcherHostImpl::CancelRequestsForContext(
for (LoaderList::iterator i = loaders_to_cancel.begin();
i != loaders_to_cancel.end(); ++i) {
// There is no strict requirement that this be the case, but currently
- // downloads, streams, detachable requests, and transferred requests are the
- // only requests that aren't cancelled when the associated processes go
- // away. It may be OK for this invariant to change in the future, but if
- // this assertion fires without the invariant changing, then it's indicative
- // of a leak.
+ // downloads, streams, detachable requests, transferred requests, and
+ // browser-owned requests are the only requests that aren't cancelled when
+ // the associated processes go away. It may be OK for this invariant to
+ // change in the future, but if this assertion fires without the invariant
+ // changing, then it's indicative of a leak.
DCHECK((*i)->GetRequestInfo()->IsDownload() ||
(*i)->GetRequestInfo()->is_stream() ||
((*i)->GetRequestInfo()->detachable_handler() &&
(*i)->GetRequestInfo()->detachable_handler()->is_detached()) ||
+ (*i)->GetRequestInfo()->GetProcessType() == PROCESS_TYPE_BROWSER ||
(*i)->is_transferring());
}
#endif
@@ -663,12 +666,11 @@ ResourceDispatcherHostImpl::MaybeInterceptAsStream(net::URLRequest* request,
origin));
info->set_is_stream(true);
- delegate_->OnStreamCreated(
- request,
- handler->stream()->CreateHandle(
- request->url(),
- mime_type,
- response->head.headers));
+ scoped_ptr<StreamInfo> stream_info(new StreamInfo);
+ stream_info->handle = handler->stream()->CreateHandle();
+ stream_info->original_url = request->url();
+ stream_info->response = response;
+ delegate_->OnStreamCreated(request, stream_info.Pass());
return handler.PassAs<ResourceHandler>();
}
@@ -1081,7 +1083,7 @@ void ResourceDispatcherHostImpl::BeginRequest(
new_request->SetLoadFlags(load_flags);
storage::BlobStorageContext* blob_context =
- GetBlobStorageContext(filter_);
+ GetBlobStorageContext(filter_->blob_storage_context());
// Resolve elements from request_body and prepare upload data.
if (request_data.request_body.get()) {
// Attaches the BlobDataHandles to request_body not to free the blobs and
@@ -1201,20 +1203,26 @@ scoped_ptr<ResourceHandler> ResourceDispatcherHostImpl::CreateResourceHandler(
handler.Pass()));
}
- // Install a CrossSiteResourceHandler for all main frame requests. This will
- // let us check whether a transfer is required and pause for the unload
- // handler either if so or if a cross-process navigation is already under way.
- bool is_swappable_navigation =
- request_data.resource_type == RESOURCE_TYPE_MAIN_FRAME;
- // If we are using --site-per-process, install it for subframes as well.
- if (!is_swappable_navigation &&
- base::CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kSitePerProcess)) {
- is_swappable_navigation =
- request_data.resource_type == RESOURCE_TYPE_SUB_FRAME;
+ // If using --enable-browser-side-navigation, the CrossSiteResourceHandler is
+ // not needed.
+ if (!base::CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kEnableBrowserSideNavigation)) {
+ // Install a CrossSiteResourceHandler for all main frame requests. This
+ // will let us check whether a transfer is required and pause for the unload
+ // handler either if so or if a cross-process navigation is already under
+ // way.
+ bool is_swappable_navigation =
+ request_data.resource_type == RESOURCE_TYPE_MAIN_FRAME;
+ // If we are using --site-per-process, install it for subframes as well.
+ if (!is_swappable_navigation &&
+ base::CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kSitePerProcess)) {
+ is_swappable_navigation =
+ request_data.resource_type == RESOURCE_TYPE_SUB_FRAME;
+ }
+ if (is_swappable_navigation && process_type == PROCESS_TYPE_RENDERER)
+ handler.reset(new CrossSiteResourceHandler(handler.Pass(), request));
}
- if (is_swappable_navigation && process_type == PROCESS_TYPE_RENDERER)
- handler.reset(new CrossSiteResourceHandler(handler.Pass(), request));
// Insert a buffered event handler before the actual one.
handler.reset(
@@ -1661,18 +1669,176 @@ void ResourceDispatcherHostImpl::FinishedWithResourcesForRequest(
IncrementOutstandingRequestsCount(-1, *info);
}
-void ResourceDispatcherHostImpl::StartNavigationRequest(
+bool ResourceDispatcherHostImpl::BeginNavigationRequest(
+ ResourceContext* resource_context,
+ int64 frame_tree_node_id,
const NavigationRequestInfo& info,
scoped_refptr<ResourceRequestBody> request_body,
- int64 navigation_request_id,
- int64 frame_node_id) {
- NOTIMPLEMENTED();
-}
+ NavigationURLLoaderCore* loader) {
clamy 2014/09/12 20:51:25 I would add a CHECK that browser side navigation i
davidben 2014/09/19 18:30:50 Good point. Done.
+ ResourceType resource_type = info.is_main_frame ?
+ RESOURCE_TYPE_MAIN_FRAME : RESOURCE_TYPE_SUB_FRAME;
+
+ if (is_shutdown_ ||
+ // TODO(davidben): Check ShouldServiceRequest here. This is important; it
+ // needs to be checked relative to the child that /requested/ the
+ // navigation. It's where file upload checks, etc., come in.
+ (delegate_ && !delegate_->ShouldBeginRequest(
+ info.navigation_params.method,
+ info.navigation_params.url,
+ resource_type,
+ resource_context))) {
+ return false;
+ }
+
+ // http://crbug.com/90971
+ char url_buf[128];
+ base::strlcpy(
+ url_buf, info.navigation_params.url.spec().c_str(), arraysize(url_buf));
+ base::debug::Alias(url_buf);
+ CHECK(ContainsKey(active_resource_contexts_, resource_context));
+
+ const net::URLRequestContext* request_context =
+ resource_context->GetRequestContext();
+
+ int load_flags = info.navigation_params.load_flags;
+ load_flags |= net::LOAD_VERIFY_EV_CERT;
+ if (info.is_main_frame) {
+ load_flags |= net::LOAD_MAIN_FRAME;
+ } else {
+ load_flags |= net::LOAD_SUB_FRAME;
+ }
+ // Add a flag to selectively bypass the data reduction proxy if the resource
+ // type is not an image.
+ load_flags |= net::LOAD_BYPASS_DATA_REDUCTION_PROXY;
+
+ // TODO(davidben): BuildLoadFlagsForRequest includes logic for
+ // CanSendCookiesForOrigin and CanReadRawCookies. Is this needed here?
-void ResourceDispatcherHostImpl::CancelNavigationRequest(
- int64 navigation_request_id,
- int64 frame_node_id) {
- NOTIMPLEMENTED();
+ // Sync loads should have maximum priority and should be the only
+ // requests that have the ignore limits flag set.
+ DCHECK_EQ(load_flags & net::LOAD_IGNORE_LIMITS, 0);
+
+ // TODO(davidben): OverrideCookieStoreForRenderProcess handling for
+ // prerender. There isn't a renderer process yet, so we need to use the
+ // ResourceContext or something.
+ scoped_ptr<net::URLRequest> new_request;
+ new_request = request_context->CreateRequest(
+ info.navigation_params.url, net::HIGHEST, NULL, NULL);
+
+ new_request->set_method(info.navigation_params.method);
+ new_request->set_first_party_for_cookies(
+ info.first_party_for_cookies);
+ if (info.is_main_frame) {
+ new_request->set_first_party_url_policy(
+ net::URLRequest::UPDATE_FIRST_PARTY_URL_ON_REDIRECT);
+ }
+
+ SetReferrerForRequest(new_request.get(), info.navigation_params.referrer);
+
+ net::HttpRequestHeaders headers;
+ headers.AddHeadersFromString(info.navigation_params.headers);
+ new_request->SetExtraRequestHeaders(headers);
+
+ new_request->SetLoadFlags(load_flags);
+
+ // Resolve elements from request_body and prepare upload data.
+ if (info.navigation_params.request_body.get()) {
+ storage::BlobStorageContext* blob_context = GetBlobStorageContext(
+ GetChromeBlobStorageContextForResourceContext(resource_context));
+ AttachRequestBodyBlobDataHandles(
+ info.navigation_params.request_body.get(),
+ blob_context);
+ // TODO(davidben): The FileSystemContext is NULL here. In the case where
+ // another renderer requested this navigation, this should be the same
+ // FileSystemContext passed into ShouldServiceRequest.
+ new_request->set_upload(UploadDataStreamBuilder::Build(
+ info.navigation_params.request_body.get(),
+ blob_context,
+ NULL, // file_system_context
+ BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE)
+ .get()));
+ }
+
+ request_id_--;
+
+ // Make extra info and read footer (contains request ID).
+ //
+ // TODO(davidben): Associate the request with the FrameTreeNode or tab so that
+ // IO thread -> UI thread hops will work.
+ ResourceRequestInfoImpl* extra_info =
+ new ResourceRequestInfoImpl(
+ PROCESS_TYPE_BROWSER,
+ -1, // child_id
+ -1, // route_id
+ -1, // request_data.origin_pid,
+ request_id_,
+ -1, // request_data.render_frame_id,
+ info.is_main_frame,
+ info.parent_is_main_frame,
+ -1, // request_data.parent_render_frame_id,
+ resource_type,
+ info.navigation_params.transition_type,
+ info.navigation_params.should_replace_current_entry,
+ false, // is download
+ false, // is stream
+ info.navigation_params.allow_download,
+ info.navigation_params.has_user_gesture,
+ true,
+ info.navigation_params.referrer.policy,
+ // TODO(davidben): This is only used for prerenders. Replace
+ // is_showing with something for that. Or maybe it just comes from the
+ // same mechanism as the cookie one.
+ blink::WebPageVisibilityStateVisible,
+ resource_context,
+ base::WeakPtr<ResourceMessageFilter>(), // filter
+ true);
+ // Request takes ownership.
+ extra_info->AssociateWithRequest(new_request.get());
+
+ if (new_request->url().SchemeIs(url::kBlobScheme)) {
+ // Hang on to a reference to ensure the blob is not released prior
+ // to the job being started.
+ ChromeBlobStorageContext* blob_context =
+ GetChromeBlobStorageContextForResourceContext(resource_context);
+ storage::BlobProtocolHandler::SetRequestedBlobDataHandle(
+ new_request.get(),
+ blob_context->context()->GetBlobDataFromPublicURL(new_request->url()));
+ }
+
+ // TODO(davidben): Attach ServiceWorkerRequestHandler.
+
+ // TODO(davidben): Attach AppCacheInterceptor.
+
+ scoped_ptr<ResourceHandler> handler(new NavigationResourceHandler(
+ new_request.get(), loader));
+
+ // Insert a buffered event handler before the actual one.
+ handler.reset(
+ new BufferedResourceHandler(handler.Pass(), this, new_request.get()));
+
+ ScopedVector<ResourceThrottle> throttles;
+ if (delegate_) {
+ // TODO(davidben): appcache_service is currently NULL.
+ delegate_->RequestBeginning(new_request.get(),
+ resource_context,
+ NULL,
+ resource_type,
+ &throttles);
+ }
+
+ if (new_request->has_upload()) {
+ // Block power save while uploading data.
+ throttles.push_back(new PowerSaveBlockResourceThrottle());
+ }
+
+ // TODO(davidben): Attach ResourceScheduler's throttle.
+
+ handler.reset(new ThrottlingResourceHandler(
+ handler.Pass(), new_request.get(), throttles.Pass()));
+
+ if (handler)
+ BeginRequestInternal(new_request.Pass(), handler.Pass());
+ return true;
}
// static

Powered by Google App Engine
This is Rietveld 408576698