diff options
author | cbentzel@chromium.org <cbentzel@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-02-18 16:20:55 +0000 |
---|---|---|
committer | cbentzel@chromium.org <cbentzel@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-02-18 16:20:55 +0000 |
commit | d5e6bdca31d7719e00f9a790d20d8faeb758b0f2 (patch) | |
tree | 58fe404c2f862015ddcd4ddedfb7742c3cfbf5f3 /chrome/browser/prerender | |
parent | bdddb676d97056742f83d280843ff099768b07f3 (diff) | |
download | chromium_src-d5e6bdca31d7719e00f9a790d20d8faeb758b0f2.zip chromium_src-d5e6bdca31d7719e00f9a790d20d8faeb758b0f2.tar.gz chromium_src-d5e6bdca31d7719e00f9a790d20d8faeb758b0f2.tar.bz2 |
Cancel prerender if any of the visited URLs are https.
BUG=72486
TEST=added new unit_tests and browser_tests
Manual Test: With preendering enabled, do a search for "yahoo mail". Prerendering should be canceled
due to https.
Review URL: http://codereview.chromium.org/6523062
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@75393 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/prerender')
6 files changed, 106 insertions, 24 deletions
diff --git a/chrome/browser/prerender/prerender_browsertest.cc b/chrome/browser/prerender/prerender_browsertest.cc index 7972ae8..740aad9 100644 --- a/chrome/browser/prerender/prerender_browsertest.cc +++ b/chrome/browser/prerender/prerender_browsertest.cc @@ -114,14 +114,20 @@ class PrerenderBrowserTest : public InProcessBrowserTest { FinalStatus expected_final_status, int total_navigations) { ASSERT_TRUE(test_server()->Start()); - std::string src_path = "files/prerender/prerender_loader.html?"; - src_path.append(html_file); std::string dest_path = "files/prerender/"; dest_path.append(html_file); - - GURL src_url = test_server()->GetURL(src_path); dest_url_ = test_server()->GetURL(dest_path); + std::vector<net::TestServer::StringPair> replacement_text; + replacement_text.push_back( + make_pair("REPLACE_WITH_PREFETCH_URL", dest_url_.spec())); + std::string replacement_path; + ASSERT_TRUE(net::TestServer::GetFilePathWithReplacements( + "files/prerender/prerender_loader.html", + replacement_text, + &replacement_path)); + GURL src_url = test_server()->GetURL(replacement_path); + Profile* profile = browser()->GetSelectedTabContents()->profile(); PrerenderManager* prerender_manager = profile->GetPrerenderManager(); ASSERT_TRUE(prerender_manager); @@ -291,4 +297,23 @@ IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderPopup) { FINAL_STATUS_CREATE_NEW_WINDOW, 1); } +// Test that page-based redirects to https will cancel prerenders. +IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderRedirectToHttps) { + net::TestServer https_server(net::TestServer::TYPE_HTTPS, + FilePath(FILE_PATH_LITERAL("chrome/test/data"))); + ASSERT_TRUE(https_server.Start()); + GURL https_url = https_server.GetURL("files/prerender/prerender_page.html"); + std::vector<net::TestServer::StringPair> replacement_text; + replacement_text.push_back( + make_pair("REPLACE_WITH_HTTPS_URL", https_url.spec())); + std::string redirect_path; + ASSERT_TRUE(net::TestServer::GetFilePathWithReplacements( + "prerender_redirect_to_https.html", + replacement_text, + &redirect_path)); + PrerenderTestURL(redirect_path, + FINAL_STATUS_HTTPS, + 2); +} + } // namespace prerender diff --git a/chrome/browser/prerender/prerender_contents.cc b/chrome/browser/prerender/prerender_contents.cc index 7428b0e..03ce8a6 100644 --- a/chrome/browser/prerender/prerender_contents.cc +++ b/chrome/browser/prerender/prerender_contents.cc @@ -48,11 +48,11 @@ PrerenderContents::PrerenderContents(PrerenderManager* prerender_manager, has_stopped_loading_(false), final_status_(FINAL_STATUS_MAX) { DCHECK(prerender_manager != NULL); - AddAliasURL(prerender_url_); + DCHECK(AddAliasURL(prerender_url_)); for (std::vector<GURL>::const_iterator it = alias_urls.begin(); it != alias_urls.end(); ++it) { - AddAliasURL(*it); + DCHECK(AddAliasURL(*it)); } } @@ -151,9 +151,12 @@ void PrerenderContents::DidNavigate( *p = params; navigate_params_.reset(p); - url_ = params.url; + if (!AddAliasURL(params.url)) { + Destroy(FINAL_STATUS_HTTPS); + return; + } - AddAliasURL(url_); + url_ = params.url; } void PrerenderContents::UpdateTitle(RenderViewHost* render_view_host, @@ -340,14 +343,19 @@ bool PrerenderContents::OnMessageReceived(const IPC::Message& message) { void PrerenderContents::OnDidStartProvisionalLoadForFrame(int64 frame_id, bool is_main_frame, const GURL& url) { - if (is_main_frame) - AddAliasURL(url); + if (is_main_frame) { + if (!AddAliasURL(url)) { + Destroy(FINAL_STATUS_HTTPS); + return; + } + } } void PrerenderContents::OnDidRedirectProvisionalLoad(int32 page_id, const GURL& source_url, const GURL& target_url) { - AddAliasURL(target_url); + if (!AddAliasURL(target_url)) + Destroy(FINAL_STATUS_HTTPS); } void PrerenderContents::OnUpdateFavIconURL(int32 page_id, @@ -355,8 +363,11 @@ void PrerenderContents::OnUpdateFavIconURL(int32 page_id, icon_url_ = icon_url; } -void PrerenderContents::AddAliasURL(const GURL& url) { +bool PrerenderContents::AddAliasURL(const GURL& url) { + if (!url.SchemeIs("http")) + return false; alias_urls_.push_back(url); + return true; } bool PrerenderContents::MatchesURL(const GURL& url) const { diff --git a/chrome/browser/prerender/prerender_contents.h b/chrome/browser/prerender/prerender_contents.h index f558dd7..7b631f4 100644 --- a/chrome/browser/prerender/prerender_contents.h +++ b/chrome/browser/prerender/prerender_contents.h @@ -189,7 +189,9 @@ class PrerenderContents : public RenderViewHostDelegate, void OnUpdateFavIconURL(int32 page_id, const GURL& icon_url); - void AddAliasURL(const GURL& url); + // Adds an alias URL, for one of the many redirections. Returns whether + // the URL is valid. + bool AddAliasURL(const GURL& url); // Remove |this| from the PrerenderManager, set a final status, and // delete |this|. diff --git a/chrome/browser/prerender/prerender_resource_handler.cc b/chrome/browser/prerender/prerender_resource_handler.cc index 0d60610..65ec6d3 100644 --- a/chrome/browser/prerender/prerender_resource_handler.cc +++ b/chrome/browser/prerender/prerender_resource_handler.cc @@ -14,16 +14,32 @@ namespace prerender { namespace { -bool ShouldPrerender(const GURL& url, const ResourceResponse* response) { +bool ShouldPrerenderURL(const GURL& url) { + if (!url.is_valid()) + return false; + if (!url.SchemeIs("http")) { + RecordFinalStatus(FINAL_STATUS_HTTPS); + return false; + } + return true; +} + +bool ValidateAliasURLs(const std::vector<GURL>& urls) { + for (std::vector<GURL>::const_iterator it = urls.begin(); + it != urls.end(); + ++it) { + if (!ShouldPrerenderURL(*it)) + return false; + } + return true; +} + +bool ShouldPrerender(const ResourceResponse* response) { 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) @@ -41,6 +57,8 @@ PrerenderResourceHandler* PrerenderResourceHandler::MaybeCreate( return NULL; if (!(request.load_flags() & net::LOAD_PREFETCH)) return NULL; + if (!ShouldPrerenderURL(request.url())) + return NULL; if (request.method() != "GET") return NULL; return new PrerenderResourceHandler(request, @@ -89,6 +107,8 @@ bool PrerenderResourceHandler::OnRequestRedirected(int request_id, bool will_redirect = next_handler_->OnRequestRedirected( request_id, url, response, defer); if (will_redirect) { + if (!ShouldPrerenderURL(url)) + return false; alias_urls_.push_back(url); url_ = url; } @@ -97,7 +117,8 @@ bool PrerenderResourceHandler::OnRequestRedirected(int request_id, bool PrerenderResourceHandler::OnResponseStarted(int request_id, ResourceResponse* response) { - if (ShouldPrerender(url_, response)) { + if (ShouldPrerender(response)) { + DCHECK(ValidateAliasURLs(alias_urls_)); BrowserThread::PostTask( BrowserThread::UI, FROM_HERE, @@ -116,6 +137,8 @@ bool PrerenderResourceHandler::OnWillStart(int request_id, bool* defer) { bool will_start = next_handler_->OnWillStart(request_id, url, defer); if (will_start) { + if (!ShouldPrerenderURL(url)) + return false; alias_urls_.push_back(url); url_ = url; } diff --git a/chrome/browser/prerender/prerender_resource_handler.h b/chrome/browser/prerender/prerender_resource_handler.h index 46c9a25..967d9f0 100644 --- a/chrome/browser/prerender/prerender_resource_handler.h +++ b/chrome/browser/prerender/prerender_resource_handler.h @@ -92,7 +92,7 @@ class PrerenderResourceHandler : public ResourceHandler { const GURL& referrer); // The set of URLs that are aliases to the URL to be prerendered, - // as a result of redirects. + // as a result of redirects, including the final URL. std::vector<GURL> alias_urls_; GURL url_; scoped_refptr<ResourceHandler> next_handler_; diff --git a/chrome/browser/prerender/prerender_resource_handler_unittest.cc b/chrome/browser/prerender/prerender_resource_handler_unittest.cc index c940bff..3bfcaf6 100644 --- a/chrome/browser/prerender/prerender_resource_handler_unittest.cc +++ b/chrome/browser/prerender/prerender_resource_handler_unittest.cc @@ -169,15 +169,16 @@ TEST_F(PrerenderResourceHandlerTest, Prerender) { EXPECT_EQ(default_url_, last_handled_url_); } +static const int kRequestId = 1; + // Tests that the final request in a redirect chain will // get diverted to the PrerenderManager. TEST_F(PrerenderResourceHandlerTest, PrerenderRedirect) { - int request_id = 1; GURL url_redirect("http://www.redirect.com"); bool defer = false; - EXPECT_TRUE(pre_handler_->OnWillStart(request_id, default_url_, &defer)); + EXPECT_TRUE(pre_handler_->OnWillStart(kRequestId, default_url_, &defer)); EXPECT_FALSE(defer); - EXPECT_TRUE(pre_handler_->OnRequestRedirected(request_id, + EXPECT_TRUE(pre_handler_->OnRequestRedirected(kRequestId, url_redirect, NULL, &defer)); @@ -186,7 +187,7 @@ TEST_F(PrerenderResourceHandlerTest, PrerenderRedirect) { response->response_head.mime_type = "text/html"; response->response_head.headers = CreateResponseHeaders( "HTTP/1.1 200 OK\n"); - EXPECT_TRUE(pre_handler_->OnResponseStarted(request_id, response)); + EXPECT_TRUE(pre_handler_->OnResponseStarted(kRequestId, response)); EXPECT_TRUE(last_handled_url_.is_empty()); loop_.RunAllPending(); EXPECT_EQ(url_redirect, last_handled_url_); @@ -195,6 +196,26 @@ TEST_F(PrerenderResourceHandlerTest, PrerenderRedirect) { EXPECT_EQ(2, static_cast<int>(alias_urls_.size())); } +// Tests that https requests will not be prerendered. +TEST_F(PrerenderResourceHandlerTest, PrerenderHttps) { + GURL url_https("https://www.google.com"); + bool defer = false; + EXPECT_FALSE(pre_handler_->OnWillStart(kRequestId, url_https, &defer)); + EXPECT_FALSE(defer); +} + +TEST_F(PrerenderResourceHandlerTest, PrerenderRedirectToHttps) { + bool defer = false; + EXPECT_TRUE(pre_handler_->OnWillStart(kRequestId, default_url_, &defer)); + EXPECT_FALSE(defer); + GURL url_https("https://www.google.com"); + EXPECT_FALSE(pre_handler_->OnRequestRedirected(kRequestId, + url_https, + NULL, + &defer)); + EXPECT_FALSE(defer); +} + } // namespace } // namespace prerender |