| Index: chrome/browser/prerender/prerender_resource_handler.cc
|
| diff --git a/chrome/browser/prerender/prerender_resource_handler.cc b/chrome/browser/prerender/prerender_resource_handler.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..507782eef924636ef88b73cf379a1ae302f57a97
|
| --- /dev/null
|
| +++ b/chrome/browser/prerender/prerender_resource_handler.cc
|
| @@ -0,0 +1,179 @@
|
| +// Copyright (c) 2011 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +#include "chrome/browser/prerender/prerender_resource_handler.h"
|
| +
|
| +#include "chrome/browser/net/chrome_url_request_context.h"
|
| +#include "chrome/common/resource_response.h"
|
| +#include "net/base/load_flags.h"
|
| +#include "net/http/http_response_headers.h"
|
| +#include "net/url_request/url_request.h"
|
| +
|
| +namespace {
|
| +
|
| +base::Time DefaultGetCurrentTime() {
|
| + return base::Time::Now();
|
| +}
|
| +
|
| +bool ShouldPrerender(const GURL& url,
|
| + const ResourceResponse* response,
|
| + PrerenderResourceHandler::GetCurrentTimeFunction get_time,
|
| + base::TimeDelta prerender_duration) {
|
| + if (!response)
|
| + return false;
|
| + const ResourceResponseHead& rrh = response->response_head;
|
| + if (!url.is_valid())
|
| + return false;
|
| + if (!rrh.headers)
|
| + return false;
|
| + if (!(url.SchemeIs("http") || url.SchemeIs("https")))
|
| + return false;
|
| + if (rrh.mime_type != "text/html")
|
| + return false;
|
| + if (rrh.headers->response_code() != 200)
|
| + return false;
|
| + if (rrh.headers->RequiresValidation(
|
| + rrh.request_time,
|
| + rrh.response_time,
|
| + get_time() + prerender_duration))
|
| + return false;
|
| + return true;
|
| +}
|
| +
|
| +} // namespace
|
| +
|
| +PrerenderResourceHandler* PrerenderResourceHandler::MaybeCreate(
|
| + const net::URLRequest& request,
|
| + ChromeURLRequestContext* context,
|
| + ResourceHandler* next_handler) {
|
| + if (!context || !context->prerender_manager())
|
| + return NULL;
|
| + if (!(request.load_flags() & net::LOAD_PREFETCH))
|
| + return NULL;
|
| + if (request.method() != "GET")
|
| + return NULL;
|
| + return new PrerenderResourceHandler(next_handler,
|
| + context->prerender_manager());
|
| +}
|
| +
|
| +PrerenderResourceHandler::PrerenderResourceHandler(
|
| + ResourceHandler* next_handler,
|
| + PrerenderManager* prerender_manager)
|
| + : next_handler_(next_handler),
|
| + prerender_manager_(prerender_manager),
|
| + ALLOW_THIS_IN_INITIALIZER_LIST(
|
| + prerender_callback_(NewCallback(
|
| + this, &PrerenderResourceHandler::StartPrerender))),
|
| + prerender_duration_(
|
| + base::TimeDelta::FromSeconds(kDefaultPrerenderDurationSeconds)),
|
| + get_current_time_(&DefaultGetCurrentTime) {
|
| + DCHECK(next_handler);
|
| + DCHECK(prerender_manager);
|
| +}
|
| +
|
| +// This constructor is only used from unit tests.
|
| +PrerenderResourceHandler::PrerenderResourceHandler(
|
| + ResourceHandler* next_handler,
|
| + PrerenderCallback* callback)
|
| + : next_handler_(next_handler),
|
| + prerender_callback_(callback),
|
| + prerender_duration_(
|
| + base::TimeDelta::FromSeconds(kDefaultPrerenderDurationSeconds)),
|
| + get_current_time_(&DefaultGetCurrentTime) {
|
| + DCHECK(next_handler);
|
| + DCHECK(callback);
|
| +}
|
| +
|
| +PrerenderResourceHandler::~PrerenderResourceHandler() {
|
| +}
|
| +
|
| +bool PrerenderResourceHandler::OnUploadProgress(int request_id,
|
| + uint64 position,
|
| + uint64 size) {
|
| + return next_handler_->OnUploadProgress(request_id, position, size);
|
| +}
|
| +
|
| +bool PrerenderResourceHandler::OnRequestRedirected(int request_id,
|
| + const GURL& url,
|
| + ResourceResponse* response,
|
| + bool* defer) {
|
| + bool will_redirect = next_handler_->OnRequestRedirected(
|
| + request_id, url, response, defer);
|
| + if (will_redirect)
|
| + url_ = url;
|
| + return will_redirect;
|
| +}
|
| +
|
| +bool PrerenderResourceHandler::OnResponseStarted(int request_id,
|
| + ResourceResponse* response) {
|
| + if (ShouldPrerender(url_,
|
| + response,
|
| + get_current_time_,
|
| + prerender_duration_)) {
|
| + BrowserThread::PostTask(
|
| + BrowserThread::UI,
|
| + FROM_HERE,
|
| + NewRunnableMethod(
|
| + this,
|
| + &PrerenderResourceHandler::RunCallbackFromUIThread,
|
| + url_));
|
| + }
|
| + return next_handler_->OnResponseStarted(request_id, response);
|
| +}
|
| +
|
| +bool PrerenderResourceHandler::OnWillStart(int request_id,
|
| + const GURL& url,
|
| + bool* defer) {
|
| + bool will_start = next_handler_->OnWillStart(request_id, url, defer);
|
| + if (will_start)
|
| + url_ = url;
|
| + return will_start;
|
| +}
|
| +
|
| +bool PrerenderResourceHandler::OnWillRead(int request_id,
|
| + net::IOBuffer** buf,
|
| + int* buf_size,
|
| + int min_size) {
|
| + return next_handler_->OnWillRead(request_id, buf, buf_size, min_size);
|
| +}
|
| +
|
| +bool PrerenderResourceHandler::OnReadCompleted(int request_id,
|
| + int* bytes_read) {
|
| + return next_handler_->OnReadCompleted(request_id, bytes_read);
|
| +}
|
| +
|
| +bool PrerenderResourceHandler::OnResponseCompleted(
|
| + int request_id,
|
| + const net::URLRequestStatus& status,
|
| + const std::string& security_info) {
|
| + return next_handler_->OnResponseCompleted(request_id, status, security_info);
|
| +}
|
| +
|
| +void PrerenderResourceHandler::OnRequestClosed() {
|
| + next_handler_->OnRequestClosed();
|
| +}
|
| +
|
| +void PrerenderResourceHandler::RunCallbackFromUIThread(const GURL& url) {
|
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
|
| + prerender_callback_->Run(url);
|
| +}
|
| +
|
| +void PrerenderResourceHandler::StartPrerender(const GURL& url) {
|
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
|
| + prerender_manager_->AddPreload(url);
|
| +}
|
| +
|
| +void PrerenderResourceHandler::set_prerender_duration(base::TimeDelta dt) {
|
| + prerender_duration_ = dt;
|
| +}
|
| +
|
| +void PrerenderResourceHandler::set_get_current_time_function(
|
| + GetCurrentTimeFunction get_current_time) {
|
| + DCHECK(get_current_time);
|
| + get_current_time_ = get_current_time;
|
| +}
|
| +
|
| +// Note: this should stay in line with prerendermanager
|
| +// static
|
| +const int PrerenderResourceHandler::kDefaultPrerenderDurationSeconds = 20;
|
|
|