18bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved. 28bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 38bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// found in the LICENSE file. 48bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 58bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "components/precache/core/precache_fetcher.h" 68bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 78bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include <string> 88bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 98bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "base/bind.h" 108bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "base/callback.h" 118bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "base/command_line.h" 128bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "base/compiler_specific.h" 135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/containers/hash_tables.h" 148bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "components/precache/core/precache_switches.h" 158bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "components/precache/core/proto/precache.pb.h" 168bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "net/base/escape.h" 178bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "net/base/load_flags.h" 188bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "net/url_request/url_fetcher.h" 198bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "net/url_request/url_fetcher_delegate.h" 208bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "net/url_request/url_request_context_getter.h" 218bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "net/url_request/url_request_status.h" 228bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 238bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)using net::URLFetcher; 248bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 258bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)namespace precache { 268bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 278bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)namespace { 288bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 298bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)GURL GetConfigURL() { 308bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) const CommandLine& command_line = *CommandLine::ForCurrentProcess(); 318bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (command_line.HasSwitch(switches::kPrecacheConfigSettingsURL)) { 328bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return GURL( 338bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) command_line.GetSwitchValueASCII(switches::kPrecacheConfigSettingsURL)); 348bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 358bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 368bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#if defined(PRECACHE_CONFIG_SETTINGS_URL) 378bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return GURL(PRECACHE_CONFIG_SETTINGS_URL); 388bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#else 398bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // The precache config settings URL could not be determined, so return an 408bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // empty, invalid GURL. 418bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return GURL(); 428bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#endif 438bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)} 448bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 458bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)std::string GetManifestURLPrefix() { 468bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) const CommandLine& command_line = *CommandLine::ForCurrentProcess(); 478bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (command_line.HasSwitch(switches::kPrecacheManifestURLPrefix)) { 488bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return command_line.GetSwitchValueASCII( 498bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) switches::kPrecacheManifestURLPrefix); 508bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 518bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 528bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#if defined(PRECACHE_MANIFEST_URL_PREFIX) 538bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return PRECACHE_MANIFEST_URL_PREFIX; 548bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#else 558bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // The precache manifest URL prefix could not be determined, so return an 568bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // empty string. 578bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return std::string(); 588bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#endif 598bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)} 608bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 618bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// Construct the URL of the precache manifest for the given starting URL. 628bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// The server is expecting a request for a URL consisting of the manifest URL 638bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// prefix followed by the doubly escaped starting URL. 648bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)GURL ConstructManifestURL(const GURL& starting_url) { 658bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return GURL( 668bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) GetManifestURLPrefix() + 678bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) net::EscapeQueryParamValue( 688bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) net::EscapeQueryParamValue(starting_url.spec(), false), false)); 698bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)} 708bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 718bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// Attempts to parse a protobuf message from the response string of a 728bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// URLFetcher. If parsing is successful, the message parameter will contain the 738bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// parsed protobuf and this function will return true. Otherwise, returns false. 748bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)bool ParseProtoFromFetchResponse(const URLFetcher& source, 758bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) ::google::protobuf::MessageLite* message) { 768bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) std::string response_string; 778bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 788bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (!source.GetStatus().is_success()) { 798bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) DLOG(WARNING) << "Fetch failed: " << source.GetOriginalURL().spec(); 808bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return false; 818bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 828bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (!source.GetResponseAsString(&response_string)) { 838bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) DLOG(WARNING) << "No response string present: " 848bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) << source.GetOriginalURL().spec(); 858bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return false; 868bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 878bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (!message->ParseFromString(response_string)) { 888bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) DLOG(WARNING) << "Unable to parse proto served from " 898bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) << source.GetOriginalURL().spec(); 908bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return false; 918bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 928bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return true; 938bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)} 948bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 958bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)} // namespace 968bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 978bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// Class that fetches a URL, and runs the specified callback when the fetch is 988bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// complete. This class exists so that a different method can be run in 998bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// response to different kinds of fetches, e.g. OnConfigFetchComplete when 1008bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// configuration settings are fetched, OnManifestFetchComplete when a manifest 1018bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// is fetched, etc. 1028bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)class PrecacheFetcher::Fetcher : public net::URLFetcherDelegate { 1038bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) public: 1048bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // Construct a new Fetcher. This will create and start a new URLFetcher for 1058bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // the specified URL using the specified request context. 1068bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) Fetcher(net::URLRequestContextGetter* request_context, const GURL& url, 1078bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) const base::Callback<void(const URLFetcher&)>& callback); 1088bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) virtual ~Fetcher() {} 1098bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) virtual void OnURLFetchComplete(const URLFetcher* source) OVERRIDE; 1108bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 1118bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) private: 1128bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) const base::Callback<void(const URLFetcher&)> callback_; 1138bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) scoped_ptr<URLFetcher> url_fetcher_; 1148bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 1158bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(Fetcher); 1168bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}; 1178bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 1188bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)PrecacheFetcher::Fetcher::Fetcher( 1198bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) net::URLRequestContextGetter* request_context, const GURL& url, 1208bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) const base::Callback<void(const URLFetcher&)>& callback) 1218bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) : callback_(callback) { 1228bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) url_fetcher_.reset(URLFetcher::Create(url, URLFetcher::GET, this)); 1238bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) url_fetcher_->SetRequestContext(request_context); 1248bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) url_fetcher_->SetLoadFlags(net::LOAD_DO_NOT_PROMPT_FOR_LOGIN); 1258bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) url_fetcher_->Start(); 1268bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)} 1278bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 1288bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void PrecacheFetcher::Fetcher::OnURLFetchComplete(const URLFetcher* source) { 1298bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) callback_.Run(*source); 1308bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)} 1318bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 1328bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)PrecacheFetcher::PrecacheFetcher( 1338bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) const std::list<GURL>& starting_urls, 1348bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) net::URLRequestContextGetter* request_context, 1358bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) PrecacheFetcher::PrecacheDelegate* precache_delegate) 1368bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) : starting_urls_(starting_urls), 1378bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) request_context_(request_context), 1388bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) precache_delegate_(precache_delegate) { 1391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(request_context_.get()); // Request context must be non-NULL. 1408bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) DCHECK(precache_delegate_); // Precache delegate must be non-NULL. 1418bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 1428bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) DCHECK_NE(GURL(), GetConfigURL()) 1438bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) << "Could not determine the precache config settings URL."; 1448bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) DCHECK_NE(std::string(), GetManifestURLPrefix()) 1458bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) << "Could not determine the precache manifest URL prefix."; 1468bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)} 1478bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 1488bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)PrecacheFetcher::~PrecacheFetcher() { 1498bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)} 1508bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 1518bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void PrecacheFetcher::Start() { 1528bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) DCHECK(!fetcher_); // Start shouldn't be called repeatedly. 1538bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 1548bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) GURL config_url = GetConfigURL(); 1558bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) DCHECK(config_url.is_valid()); 1568bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 1578bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // Fetch the precache configuration settings from the server. 1581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci fetcher_.reset(new Fetcher(request_context_.get(), 1591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci config_url, 1608bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) base::Bind(&PrecacheFetcher::OnConfigFetchComplete, 1618bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) base::Unretained(this)))); 1628bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)} 1638bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 1648bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void PrecacheFetcher::StartNextFetch() { 1658bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (!resource_urls_to_fetch_.empty()) { 1668bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // Fetch the next resource URL. 1678bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) fetcher_.reset( 1681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci new Fetcher(request_context_.get(), 1691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci resource_urls_to_fetch_.front(), 1708bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) base::Bind(&PrecacheFetcher::OnResourceFetchComplete, 1718bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) base::Unretained(this)))); 1728bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 1738bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) resource_urls_to_fetch_.pop_front(); 1748bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return; 1758bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 1768bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 1778bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (!manifest_urls_to_fetch_.empty()) { 1788bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // Fetch the next manifest URL. 1798bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) fetcher_.reset( 1801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci new Fetcher(request_context_.get(), 1811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci manifest_urls_to_fetch_.front(), 1828bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) base::Bind(&PrecacheFetcher::OnManifestFetchComplete, 1838bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) base::Unretained(this)))); 1848bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 1858bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) manifest_urls_to_fetch_.pop_front(); 1868bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return; 1878bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 1888bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 1898bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // There are no more URLs to fetch, so end the precache cycle. 1908bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) precache_delegate_->OnDone(); 1918bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // OnDone may have deleted this PrecacheFetcher, so don't do anything after it 1928bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // is called. 1938bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)} 1948bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 1958bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void PrecacheFetcher::OnConfigFetchComplete(const URLFetcher& source) { 1968bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) PrecacheConfigurationSettings config; 1978bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 1988bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (ParseProtoFromFetchResponse(source, &config)) { 1995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Keep track of starting URLs that manifests are being fetched for, in 2005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // order to remove duplicates. This is a hash set on strings, and not GURLs, 2015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // because there is no hash function defined for GURL. 2025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::hash_set<std::string> unique_starting_urls; 2035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 204a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // Attempt to fetch manifests for starting URLs up to the maximum top sites 205a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // count. If a manifest does not exist for a particular starting URL, then 206a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // the fetch will fail, and that starting URL will be ignored. 2078bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) int64 rank = 0; 2088bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) for (std::list<GURL>::const_iterator it = starting_urls_.begin(); 209a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) it != starting_urls_.end() && rank < config.top_sites_count(); 2108bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) ++it, ++rank) { 2115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (unique_starting_urls.find(it->spec()) == unique_starting_urls.end()) { 2125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Only add a fetch for the manifest URL if this manifest isn't already 2135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // going to be fetched. 2145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) manifest_urls_to_fetch_.push_back(ConstructManifestURL(*it)); 2155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) unique_starting_urls.insert(it->spec()); 2165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 2175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 2185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (int i = 0; i < config.forced_starting_url_size(); ++i) { 2205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Convert the string URL into a GURL and take the spec() of it so that 2215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // the URL string gets canonicalized. 2225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) GURL url(config.forced_starting_url(i)); 2235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (unique_starting_urls.find(url.spec()) == unique_starting_urls.end()) { 2245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Only add a fetch for the manifest URL if this manifest isn't already 2255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // going to be fetched. 2265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) manifest_urls_to_fetch_.push_back(ConstructManifestURL(url)); 2275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) unique_starting_urls.insert(url.spec()); 2285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 2298bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 2308bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 2318bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 2328bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) StartNextFetch(); 2338bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)} 2348bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 2358bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void PrecacheFetcher::OnManifestFetchComplete(const URLFetcher& source) { 2368bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) PrecacheManifest manifest; 2378bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 2388bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (ParseProtoFromFetchResponse(source, &manifest)) { 2398bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) for (int i = 0; i < manifest.resource_size(); ++i) { 2408bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (manifest.resource(i).has_url()) { 2418bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) resource_urls_to_fetch_.push_back(GURL(manifest.resource(i).url())); 2428bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 2438bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 2448bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 2458bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 2468bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) StartNextFetch(); 2478bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)} 2488bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 2498bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void PrecacheFetcher::OnResourceFetchComplete(const URLFetcher& source) { 2508bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // The resource has already been put in the cache during the fetch process, so 2518bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // nothing more needs to be done for the resource. 2528bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) StartNextFetch(); 2538bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)} 2548bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 2558bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)} // namespace precache 256