diff options
author | cbentzel@chromium.org <cbentzel@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-04-27 19:36:48 +0000 |
---|---|---|
committer | cbentzel@chromium.org <cbentzel@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-04-27 19:36:48 +0000 |
commit | 8a6e41619ddac0aa52625ff425b574142fd96ba1 (patch) | |
tree | 204d113e1ae06989f79b483def48fb1850f7ea15 /content | |
parent | cb8d84e8f3635ee048e8ad8a560f233ba096a9f5 (diff) | |
download | chromium_src-8a6e41619ddac0aa52625ff425b574142fd96ba1.zip chromium_src-8a6e41619ddac0aa52625ff425b574142fd96ba1.tar.gz chromium_src-8a6e41619ddac0aa52625ff425b574142fd96ba1.tar.bz2 |
Eliminate double-get for prerendered pages.
BUG=71089
TEST=prerender browser_tests and unit_tests
Review URL: http://codereview.chromium.org/6904027
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@83192 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'content')
-rw-r--r-- | content/browser/renderer_host/resource_dispatcher_host.cc | 111 |
1 files changed, 67 insertions, 44 deletions
diff --git a/content/browser/renderer_host/resource_dispatcher_host.cc b/content/browser/renderer_host/resource_dispatcher_host.cc index 6422aeb..169468e 100644 --- a/content/browser/renderer_host/resource_dispatcher_host.cc +++ b/content/browser/renderer_host/resource_dispatcher_host.cc @@ -26,7 +26,6 @@ #include "chrome/browser/net/chrome_url_request_context.h" #include "chrome/browser/net/url_request_tracking.h" #include "chrome/browser/prerender/prerender_manager.h" -#include "chrome/browser/prerender/prerender_resource_handler.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/renderer_host/download_resource_handler.h" #include "chrome/browser/renderer_host/safe_browsing_resource_handler.h" @@ -120,6 +119,35 @@ const int kMaxPendingDataMessages = 20; // This bound is 25MB, which allows for around 6000 outstanding requests. const int kMaxOutstandingRequestsCostPerProcess = 26214400; +// Aborts a request before an URLRequest has actually been created. +void AbortRequestBeforeItStarts(ResourceMessageFilter* filter, + IPC::Message* sync_result, + int route_id, + int request_id) { + net::URLRequestStatus status(net::URLRequestStatus::FAILED, + net::ERR_ABORTED); + if (sync_result) { + SyncLoadResult result; + result.status = status; + ResourceHostMsg_SyncLoad::WriteReplyParams(sync_result, result); + filter->Send(sync_result); + } else { + // Tell the renderer that this request was disallowed. + filter->Send(new ResourceMsg_RequestComplete( + route_id, + request_id, + status, + std::string(), // No security info needed, connection was not + base::Time())); // established. + } +} + +GURL MaybeStripReferrer(const GURL& possible_referrer) { + if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kNoReferrers)) + return GURL(); + return possible_referrer; +} + // Consults the RendererSecurity policy to determine whether the // ResourceDispatcherHost should service this request. A request might be // disallowed if the renderer is not authorized to retrieve the request URL or @@ -130,12 +158,6 @@ bool ShouldServiceRequest(ChildProcessInfo::ProcessType process_type, if (process_type == ChildProcessInfo::PLUGIN_PROCESS) return true; - if (request_data.resource_type == ResourceType::PREFETCH) { - prerender::PrerenderManager::RecordPrefetchTagObserved(); - if (!ResourceDispatcherHost::is_prefetch_enabled()) - return false; - } - ChildProcessSecurityPolicy* policy = ChildProcessSecurityPolicy::GetInstance(); @@ -367,25 +389,43 @@ void ResourceDispatcherHost::BeginRequest( if (is_shutdown_ || !ShouldServiceRequest(process_type, child_id, request_data)) { - net::URLRequestStatus status(net::URLRequestStatus::FAILED, - net::ERR_ABORTED); - if (sync_result) { - SyncLoadResult result; - result.status = status; - ResourceHostMsg_SyncLoad::WriteReplyParams(sync_result, result); - filter_->Send(sync_result); - } else { - // Tell the renderer that this request was disallowed. - filter_->Send(new ResourceMsg_RequestComplete( - route_id, - request_id, - status, - std::string(), // No security info needed, connection was not - base::Time())); // established. - } + AbortRequestBeforeItStarts(filter_, sync_result, route_id, request_id); return; } + const GURL referrer = MaybeStripReferrer(request_data.referrer); + const bool is_prerendering = IsPrerenderingChildRoutePair(child_id, route_id); + + // Handle a PREFETCH resource type. If prefetch is disabled, squelch the + // request. If prerendering is enabled, trigger a prerender for the URL + // and abort the request, to prevent double-gets. Otherwise, do a normal + // prefetch. + if (request_data.resource_type == ResourceType::PREFETCH) { + // All PREFETCH requests should be GETs, but be defensive about it. + if (request_data.method != "GET") { + AbortRequestBeforeItStarts(filter_, sync_result, route_id, request_id); + return; + } + if (!ResourceDispatcherHost::is_prefetch_enabled()) { + AbortRequestBeforeItStarts(filter_, sync_result, route_id, request_id); + return; + } + if (prerender::PrerenderManager::IsPrerenderingPossible()) { + BrowserThread::PostTask( + BrowserThread::UI, FROM_HERE, + NewRunnableFunction(prerender::HandlePrefetchTagOnUIThread, + context->prerender_manager(), + std::make_pair(child_id, route_id), + request_data.url, + referrer, + is_prerendering)); + AbortRequestBeforeItStarts(filter_, sync_result, route_id, request_id); + return; + } + // Otherwise, treat like a normal request, and fall-through. + } + + // Construct the event handler. scoped_refptr<ResourceHandler> handler; if (sync_result) { @@ -410,8 +450,7 @@ void ResourceDispatcherHost::BeginRequest( net::URLRequest* request = new net::URLRequest(request_data.url, this); request->set_method(request_data.method); request->set_first_party_for_cookies(request_data.first_party_for_cookies); - request->set_referrer(CommandLine::ForCurrentProcess()->HasSwitch( - switches::kNoReferrers) ? std::string() : request_data.referrer.spec()); + request->set_referrer(referrer.spec()); net::HttpRequestHeaders headers; headers.AddHeadersFromString(request_data.headers); request->SetExtraRequestHeaders(headers); @@ -432,7 +471,7 @@ void ResourceDispatcherHost::BeginRequest( load_flags |= net::LOAD_DO_NOT_PROMPT_FOR_LOGIN; } - if (IsPrerenderingChildRoutePair(child_id, route_id)) + if (is_prerendering) load_flags |= net::LOAD_PRERENDER; if (sync_result) @@ -459,20 +498,6 @@ void ResourceDispatcherHost::BeginRequest( upload_size = request_data.upload_data->GetContentLength(); } - // Install a PrerenderResourceHandler if the requested URL could - // be prerendered. This should be in front of the [a]syncResourceHandler, - // but after the BufferedResourceHandler since it depends on the MIME - // sniffing capabilities in the BufferedResourceHandler. - prerender::PrerenderResourceHandler* pre_handler = - prerender::PrerenderResourceHandler::MaybeCreate( - *request, - context, - handler, - ((load_flags & net::LOAD_PRERENDER) != 0), - child_id, route_id); - if (pre_handler) - handler = pre_handler; - // Install a CrossSiteResourceHandler if this request is coming from a // RenderViewHost with a pending cross-site request. We only check this for // MAIN_FRAME requests. Unblock requests only come from a blocked page, do @@ -726,8 +751,7 @@ void ResourceDispatcherHost::BeginDownload( } request->set_method("GET"); - request->set_referrer(CommandLine::ForCurrentProcess()->HasSwitch( - switches::kNoReferrers) ? std::string() : referrer.spec()); + request->set_referrer(MaybeStripReferrer(referrer).spec()); request->set_context(request_context); request->set_load_flags(request->load_flags() | net::LOAD_IS_DOWNLOAD); @@ -767,8 +791,7 @@ void ResourceDispatcherHost::BeginSaveFile( net::URLRequest* request = new net::URLRequest(url, this); request->set_method("GET"); - request->set_referrer(CommandLine::ForCurrentProcess()->HasSwitch( - switches::kNoReferrers) ? std::string() : referrer.spec()); + request->set_referrer(MaybeStripReferrer(referrer).spec()); // So far, for saving page, we need fetch content from cache, in the // future, maybe we can use a configuration to configure this behavior. request->set_load_flags(net::LOAD_PREFERRING_CACHE); |