summaryrefslogtreecommitdiffstats
path: root/content
diff options
context:
space:
mode:
authorcbentzel@chromium.org <cbentzel@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-04-27 19:36:48 +0000
committercbentzel@chromium.org <cbentzel@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-04-27 19:36:48 +0000
commit8a6e41619ddac0aa52625ff425b574142fd96ba1 (patch)
tree204d113e1ae06989f79b483def48fb1850f7ea15 /content
parentcb8d84e8f3635ee048e8ad8a560f233ba096a9f5 (diff)
downloadchromium_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.cc111
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);