prerender_resource_handler.cc revision 72a454cd3513ac24fbdd0e0cb9ad70b86a99b801
1// Copyright (c) 2011 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include "chrome/browser/prerender/prerender_resource_handler.h" 6 7#include "chrome/browser/net/chrome_url_request_context.h" 8#include "chrome/common/resource_response.h" 9#include "net/base/load_flags.h" 10#include "net/http/http_response_headers.h" 11#include "net/url_request/url_request.h" 12 13namespace { 14 15bool ShouldPrerender(const GURL& url, const ResourceResponse* response) { 16 if (!response) 17 return false; 18 const ResourceResponseHead& rrh = response->response_head; 19 if (!url.is_valid()) 20 return false; 21 if (!rrh.headers) 22 return false; 23 if (!(url.SchemeIs("http") || url.SchemeIs("https"))) 24 return false; 25 if (rrh.mime_type != "text/html") 26 return false; 27 if (rrh.headers->response_code() != 200) 28 return false; 29 return true; 30} 31 32} // namespace 33 34PrerenderResourceHandler* PrerenderResourceHandler::MaybeCreate( 35 const net::URLRequest& request, 36 ChromeURLRequestContext* context, 37 ResourceHandler* next_handler) { 38 if (!context || !context->prerender_manager()) 39 return NULL; 40 if (!(request.load_flags() & net::LOAD_PREFETCH)) 41 return NULL; 42 if (request.method() != "GET") 43 return NULL; 44 return new PrerenderResourceHandler(next_handler, 45 context->prerender_manager()); 46} 47 48PrerenderResourceHandler::PrerenderResourceHandler( 49 ResourceHandler* next_handler, 50 PrerenderManager* prerender_manager) 51 : next_handler_(next_handler), 52 prerender_manager_(prerender_manager), 53 ALLOW_THIS_IN_INITIALIZER_LIST( 54 prerender_callback_(NewCallback( 55 this, &PrerenderResourceHandler::StartPrerender))) { 56 DCHECK(next_handler); 57 DCHECK(prerender_manager); 58} 59 60// This constructor is only used from unit tests. 61PrerenderResourceHandler::PrerenderResourceHandler( 62 ResourceHandler* next_handler, 63 PrerenderCallback* callback) 64 : next_handler_(next_handler), 65 prerender_callback_(callback) { 66 DCHECK(next_handler); 67 DCHECK(callback); 68} 69 70PrerenderResourceHandler::~PrerenderResourceHandler() { 71} 72 73bool PrerenderResourceHandler::OnUploadProgress(int request_id, 74 uint64 position, 75 uint64 size) { 76 return next_handler_->OnUploadProgress(request_id, position, size); 77} 78 79bool PrerenderResourceHandler::OnRequestRedirected(int request_id, 80 const GURL& url, 81 ResourceResponse* response, 82 bool* defer) { 83 bool will_redirect = next_handler_->OnRequestRedirected( 84 request_id, url, response, defer); 85 if (will_redirect) { 86 alias_urls_.push_back(url); 87 url_ = url; 88 } 89 return will_redirect; 90} 91 92bool PrerenderResourceHandler::OnResponseStarted(int request_id, 93 ResourceResponse* response) { 94 if (ShouldPrerender(url_, response)) { 95 BrowserThread::PostTask( 96 BrowserThread::UI, 97 FROM_HERE, 98 NewRunnableMethod( 99 this, 100 &PrerenderResourceHandler::RunCallbackFromUIThread, 101 url_, 102 alias_urls_)); 103 } 104 return next_handler_->OnResponseStarted(request_id, response); 105} 106 107bool PrerenderResourceHandler::OnWillStart(int request_id, 108 const GURL& url, 109 bool* defer) { 110 bool will_start = next_handler_->OnWillStart(request_id, url, defer); 111 if (will_start) { 112 alias_urls_.push_back(url); 113 url_ = url; 114 } 115 return will_start; 116} 117 118bool PrerenderResourceHandler::OnWillRead(int request_id, 119 net::IOBuffer** buf, 120 int* buf_size, 121 int min_size) { 122 return next_handler_->OnWillRead(request_id, buf, buf_size, min_size); 123} 124 125bool PrerenderResourceHandler::OnReadCompleted(int request_id, 126 int* bytes_read) { 127 return next_handler_->OnReadCompleted(request_id, bytes_read); 128} 129 130bool PrerenderResourceHandler::OnResponseCompleted( 131 int request_id, 132 const net::URLRequestStatus& status, 133 const std::string& security_info) { 134 return next_handler_->OnResponseCompleted(request_id, status, security_info); 135} 136 137void PrerenderResourceHandler::OnRequestClosed() { 138 next_handler_->OnRequestClosed(); 139} 140 141void PrerenderResourceHandler::RunCallbackFromUIThread(const GURL& url, 142 const std::vector<GURL>& 143 alias_urls) { 144 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 145 prerender_callback_->Run(url, alias_urls); 146} 147 148void PrerenderResourceHandler::StartPrerender(const GURL& url, 149 const std::vector<GURL>& 150 alias_urls) { 151 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 152 prerender_manager_->AddPreload(url, alias_urls); 153} 154