Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "components/precache/core/precache_fetcher.h" | 5 #include "components/precache/core/precache_fetcher.h" |
| 6 | 6 |
| 7 #include <string> | 7 #include <string> |
| 8 #include <vector> | 8 #include <vector> |
| 9 | 9 |
| 10 #include "base/bind.h" | 10 #include "base/bind.h" |
| 11 #include "base/callback.h" | 11 #include "base/callback.h" |
| 12 #include "base/command_line.h" | 12 #include "base/command_line.h" |
| 13 #include "base/compiler_specific.h" | 13 #include "base/compiler_specific.h" |
| 14 #include "base/containers/hash_tables.h" | 14 #include "base/containers/hash_tables.h" |
| 15 #include "base/metrics/histogram_macros.h" | |
| 15 #include "components/precache/core/precache_switches.h" | 16 #include "components/precache/core/precache_switches.h" |
| 16 #include "components/precache/core/proto/precache.pb.h" | 17 #include "components/precache/core/proto/precache.pb.h" |
| 17 #include "net/base/completion_callback.h" | 18 #include "net/base/completion_callback.h" |
| 18 #include "net/base/escape.h" | 19 #include "net/base/escape.h" |
| 19 #include "net/base/io_buffer.h" | 20 #include "net/base/io_buffer.h" |
| 20 #include "net/base/load_flags.h" | 21 #include "net/base/load_flags.h" |
| 21 #include "net/base/net_errors.h" | 22 #include "net/base/net_errors.h" |
| 22 #include "net/url_request/url_fetcher.h" | 23 #include "net/url_request/url_fetcher.h" |
| 23 #include "net/url_request/url_fetcher_delegate.h" | 24 #include "net/url_request/url_fetcher_delegate.h" |
| 24 #include "net/url_request/url_fetcher_response_writer.h" | 25 #include "net/url_request/url_fetcher_response_writer.h" |
| 25 #include "net/url_request/url_request_context_getter.h" | 26 #include "net/url_request/url_request_context_getter.h" |
| 26 #include "net/url_request/url_request_status.h" | 27 #include "net/url_request/url_request_status.h" |
| 27 | 28 |
| 28 using net::URLFetcher; | 29 using net::URLFetcher; |
| 29 | 30 |
| 30 namespace precache { | 31 namespace precache { |
| 31 | 32 |
| 32 namespace { | 33 namespace { |
| 33 | 34 |
| 35 // The maximum for the Precache.Fetch.ResponseBytes histogram. We set this to a | |
| 36 // number we expect to be in the 99th percentile for the histogram, give or | |
| 37 // take. | |
| 38 const int kMaxResponseBytes = 100 * 1024 * 1024; | |
| 39 | |
| 34 GURL GetConfigURL() { | 40 GURL GetConfigURL() { |
| 35 const base::CommandLine& command_line = | 41 const base::CommandLine& command_line = |
| 36 *base::CommandLine::ForCurrentProcess(); | 42 *base::CommandLine::ForCurrentProcess(); |
| 37 if (command_line.HasSwitch(switches::kPrecacheConfigSettingsURL)) { | 43 if (command_line.HasSwitch(switches::kPrecacheConfigSettingsURL)) { |
| 38 return GURL( | 44 return GURL( |
| 39 command_line.GetSwitchValueASCII(switches::kPrecacheConfigSettingsURL)); | 45 command_line.GetSwitchValueASCII(switches::kPrecacheConfigSettingsURL)); |
| 40 } | 46 } |
| 41 | 47 |
| 42 #if defined(PRECACHE_CONFIG_SETTINGS_URL) | 48 #if defined(PRECACHE_CONFIG_SETTINGS_URL) |
| 43 return GURL(PRECACHE_CONFIG_SETTINGS_URL); | 49 return GURL(PRECACHE_CONFIG_SETTINGS_URL); |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 128 // is fetched, etc. | 134 // is fetched, etc. |
| 129 class PrecacheFetcher::Fetcher : public net::URLFetcherDelegate { | 135 class PrecacheFetcher::Fetcher : public net::URLFetcherDelegate { |
| 130 public: | 136 public: |
| 131 // Construct a new Fetcher. This will create and start a new URLFetcher for | 137 // Construct a new Fetcher. This will create and start a new URLFetcher for |
| 132 // the specified URL using the specified request context. | 138 // the specified URL using the specified request context. |
| 133 Fetcher(net::URLRequestContextGetter* request_context, | 139 Fetcher(net::URLRequestContextGetter* request_context, |
| 134 const GURL& url, | 140 const GURL& url, |
| 135 const base::Callback<void(const URLFetcher&)>& callback, | 141 const base::Callback<void(const URLFetcher&)>& callback, |
| 136 bool ignore_response_body); | 142 bool ignore_response_body); |
| 137 ~Fetcher() override {} | 143 ~Fetcher() override {} |
| 144 void OnURLFetchDownloadProgress(const URLFetcher* source, | |
| 145 int64 current, | |
|
bengr
2015/07/08 19:52:40
I think you want to use int64_t. See https://googl
twifkak
2015/07/08 19:59:03
I'm implementing the net::URLFetcherDelegate inter
| |
| 146 int64 total) override; | |
| 138 void OnURLFetchComplete(const URLFetcher* source) override; | 147 void OnURLFetchComplete(const URLFetcher* source) override; |
| 148 int response_bytes() { return response_bytes_; } | |
| 139 | 149 |
| 140 private: | 150 private: |
| 141 const base::Callback<void(const URLFetcher&)> callback_; | 151 const base::Callback<void(const URLFetcher&)> callback_; |
| 142 scoped_ptr<URLFetcher> url_fetcher_; | 152 scoped_ptr<URLFetcher> url_fetcher_; |
| 153 int response_bytes_; | |
| 143 | 154 |
| 144 DISALLOW_COPY_AND_ASSIGN(Fetcher); | 155 DISALLOW_COPY_AND_ASSIGN(Fetcher); |
| 145 }; | 156 }; |
| 146 | 157 |
| 147 PrecacheFetcher::Fetcher::Fetcher( | 158 PrecacheFetcher::Fetcher::Fetcher( |
| 148 net::URLRequestContextGetter* request_context, | 159 net::URLRequestContextGetter* request_context, |
| 149 const GURL& url, | 160 const GURL& url, |
| 150 const base::Callback<void(const URLFetcher&)>& callback, | 161 const base::Callback<void(const URLFetcher&)>& callback, |
| 151 bool ignore_response_body) | 162 bool ignore_response_body) |
| 152 : callback_(callback) { | 163 : callback_(callback), response_bytes_(0) { |
| 153 url_fetcher_ = URLFetcher::Create(url, URLFetcher::GET, this); | 164 url_fetcher_ = URLFetcher::Create(url, URLFetcher::GET, this); |
| 154 url_fetcher_->SetRequestContext(request_context); | 165 url_fetcher_->SetRequestContext(request_context); |
| 155 url_fetcher_->SetLoadFlags(net::LOAD_DO_NOT_SAVE_COOKIES | | 166 url_fetcher_->SetLoadFlags(net::LOAD_DO_NOT_SAVE_COOKIES | |
| 156 net::LOAD_DO_NOT_SEND_COOKIES); | 167 net::LOAD_DO_NOT_SEND_COOKIES); |
| 157 if (ignore_response_body) { | 168 if (ignore_response_body) { |
| 158 scoped_ptr<URLFetcherNullWriter> null_writer(new URLFetcherNullWriter); | 169 scoped_ptr<URLFetcherNullWriter> null_writer(new URLFetcherNullWriter); |
| 159 url_fetcher_->SaveResponseWithWriter(null_writer.Pass()); | 170 url_fetcher_->SaveResponseWithWriter(null_writer.Pass()); |
| 160 } | 171 } |
| 161 url_fetcher_->Start(); | 172 url_fetcher_->Start(); |
| 162 } | 173 } |
| 163 | 174 |
| 175 void PrecacheFetcher::Fetcher::OnURLFetchDownloadProgress( | |
| 176 const URLFetcher* source, | |
| 177 int64 current, | |
| 178 int64 total) { | |
| 179 response_bytes_ = current; | |
| 180 } | |
| 181 | |
| 164 void PrecacheFetcher::Fetcher::OnURLFetchComplete(const URLFetcher* source) { | 182 void PrecacheFetcher::Fetcher::OnURLFetchComplete(const URLFetcher* source) { |
| 165 callback_.Run(*source); | 183 callback_.Run(*source); |
| 166 } | 184 } |
| 167 | 185 |
| 168 PrecacheFetcher::PrecacheFetcher( | 186 PrecacheFetcher::PrecacheFetcher( |
| 169 const std::vector<std::string>& starting_hosts, | 187 const std::vector<std::string>& starting_hosts, |
| 170 net::URLRequestContextGetter* request_context, | 188 net::URLRequestContextGetter* request_context, |
| 171 const std::string& manifest_url_prefix, | 189 const std::string& manifest_url_prefix, |
| 172 PrecacheFetcher::PrecacheDelegate* precache_delegate) | 190 PrecacheFetcher::PrecacheDelegate* precache_delegate) |
| 173 : starting_hosts_(starting_hosts), | 191 : starting_hosts_(starting_hosts), |
| 174 request_context_(request_context), | 192 request_context_(request_context), |
| 175 manifest_url_prefix_(manifest_url_prefix), | 193 manifest_url_prefix_(manifest_url_prefix), |
| 176 precache_delegate_(precache_delegate) { | 194 precache_delegate_(precache_delegate), |
| 195 total_response_bytes_(0), | |
| 196 num_manifest_urls_to_fetch_(0) { | |
| 177 DCHECK(request_context_.get()); // Request context must be non-NULL. | 197 DCHECK(request_context_.get()); // Request context must be non-NULL. |
| 178 DCHECK(precache_delegate_); // Precache delegate must be non-NULL. | 198 DCHECK(precache_delegate_); // Precache delegate must be non-NULL. |
| 179 | 199 |
| 180 DCHECK_NE(GURL(), GetConfigURL()) | 200 DCHECK_NE(GURL(), GetConfigURL()) |
| 181 << "Could not determine the precache config settings URL."; | 201 << "Could not determine the precache config settings URL."; |
| 182 DCHECK_NE(std::string(), GetDefaultManifestURLPrefix()) | 202 DCHECK_NE(std::string(), GetDefaultManifestURLPrefix()) |
| 183 << "Could not determine the default precache manifest URL prefix."; | 203 << "Could not determine the default precache manifest URL prefix."; |
| 184 } | 204 } |
| 185 | 205 |
| 186 PrecacheFetcher::~PrecacheFetcher() { | 206 PrecacheFetcher::~PrecacheFetcher() { |
| 207 // Number of manifests for which we have downloaded all resources. | |
| 208 int manifests_completed = | |
| 209 num_manifest_urls_to_fetch_ - manifest_urls_to_fetch_.size(); | |
| 210 | |
| 211 // If there are resource URLs left to fetch, the last manifest is not yet | |
| 212 // completed. | |
| 213 if (!resource_urls_to_fetch_.empty()) | |
| 214 --manifests_completed; | |
| 215 | |
| 216 DCHECK_GE(manifests_completed, 0); | |
| 217 int percent_completed = num_manifest_urls_to_fetch_ == 0 | |
| 218 ? 0 | |
| 219 : (static_cast<double>(manifests_completed) / | |
| 220 num_manifest_urls_to_fetch_ * 100); | |
| 221 UMA_HISTOGRAM_PERCENTAGE("Precache.Fetch.PercentCompleted", | |
| 222 percent_completed); | |
| 223 UMA_HISTOGRAM_CUSTOM_COUNTS("Precache.Fetch.ResponseBytes", | |
| 224 total_response_bytes_, 1, kMaxResponseBytes, 50); | |
| 187 } | 225 } |
| 188 | 226 |
| 189 void PrecacheFetcher::Start() { | 227 void PrecacheFetcher::Start() { |
| 190 DCHECK(!fetcher_); // Start shouldn't be called repeatedly. | 228 DCHECK(!fetcher_); // Start shouldn't be called repeatedly. |
| 191 | 229 |
| 192 GURL config_url = GetConfigURL(); | 230 GURL config_url = GetConfigURL(); |
| 193 DCHECK(config_url.is_valid()); | 231 DCHECK(config_url.is_valid()); |
| 194 | 232 |
| 195 // Fetch the precache configuration settings from the server. | 233 // Fetch the precache configuration settings from the server. |
| 196 fetcher_.reset(new Fetcher(request_context_.get(), config_url, | 234 fetcher_.reset(new Fetcher(request_context_.get(), config_url, |
| 197 base::Bind(&PrecacheFetcher::OnConfigFetchComplete, | 235 base::Bind(&PrecacheFetcher::OnConfigFetchComplete, |
| 198 base::Unretained(this)), | 236 base::Unretained(this)), |
| 199 false /* ignore_response_body */)); | 237 false /* ignore_response_body */)); |
| 200 } | 238 } |
| 201 | 239 |
| 202 void PrecacheFetcher::StartNextFetch() { | 240 void PrecacheFetcher::StartNextFetch() { |
| 241 total_response_bytes_ += fetcher_->response_bytes(); | |
| 242 | |
| 203 if (!resource_urls_to_fetch_.empty()) { | 243 if (!resource_urls_to_fetch_.empty()) { |
| 204 // Fetch the next resource URL. | 244 // Fetch the next resource URL. |
| 205 fetcher_.reset( | 245 fetcher_.reset( |
| 206 new Fetcher(request_context_.get(), resource_urls_to_fetch_.front(), | 246 new Fetcher(request_context_.get(), resource_urls_to_fetch_.front(), |
| 207 base::Bind(&PrecacheFetcher::OnResourceFetchComplete, | 247 base::Bind(&PrecacheFetcher::OnResourceFetchComplete, |
| 208 base::Unretained(this)), | 248 base::Unretained(this)), |
| 209 true /* ignore_response_body */)); | 249 true /* ignore_response_body */)); |
| 210 | 250 |
| 211 resource_urls_to_fetch_.pop_front(); | 251 resource_urls_to_fetch_.pop_front(); |
| 212 return; | 252 return; |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 255 if (rank > config.top_sites_count()) | 295 if (rank > config.top_sites_count()) |
| 256 break; | 296 break; |
| 257 unique_manifest_urls.insert(ConstructManifestURL(prefix, host)); | 297 unique_manifest_urls.insert(ConstructManifestURL(prefix, host)); |
| 258 } | 298 } |
| 259 | 299 |
| 260 for (const std::string& url : config.forced_site()) | 300 for (const std::string& url : config.forced_site()) |
| 261 unique_manifest_urls.insert(ConstructManifestURL(prefix, url)); | 301 unique_manifest_urls.insert(ConstructManifestURL(prefix, url)); |
| 262 | 302 |
| 263 for (const std::string& manifest_url : unique_manifest_urls) | 303 for (const std::string& manifest_url : unique_manifest_urls) |
| 264 manifest_urls_to_fetch_.push_back(GURL(manifest_url)); | 304 manifest_urls_to_fetch_.push_back(GURL(manifest_url)); |
| 305 num_manifest_urls_to_fetch_ = manifest_urls_to_fetch_.size(); | |
| 265 | 306 |
| 266 StartNextFetch(); | 307 StartNextFetch(); |
| 267 } | 308 } |
| 268 | 309 |
| 269 void PrecacheFetcher::OnManifestFetchComplete(const URLFetcher& source) { | 310 void PrecacheFetcher::OnManifestFetchComplete(const URLFetcher& source) { |
| 270 PrecacheManifest manifest; | 311 PrecacheManifest manifest; |
| 271 | 312 |
| 272 if (ParseProtoFromFetchResponse(source, &manifest)) { | 313 if (ParseProtoFromFetchResponse(source, &manifest)) { |
| 273 for (int i = 0; i < manifest.resource_size(); ++i) { | 314 for (int i = 0; i < manifest.resource_size(); ++i) { |
| 274 if (manifest.resource(i).has_url()) { | 315 if (manifest.resource(i).has_url()) { |
| 275 resource_urls_to_fetch_.push_back(GURL(manifest.resource(i).url())); | 316 resource_urls_to_fetch_.push_back(GURL(manifest.resource(i).url())); |
| 276 } | 317 } |
| 277 } | 318 } |
| 278 } | 319 } |
| 279 | 320 |
| 280 StartNextFetch(); | 321 StartNextFetch(); |
| 281 } | 322 } |
| 282 | 323 |
| 283 void PrecacheFetcher::OnResourceFetchComplete(const URLFetcher& source) { | 324 void PrecacheFetcher::OnResourceFetchComplete(const URLFetcher& source) { |
| 284 // The resource has already been put in the cache during the fetch process, so | 325 // The resource has already been put in the cache during the fetch process, so |
| 285 // nothing more needs to be done for the resource. | 326 // nothing more needs to be done for the resource. |
| 286 StartNextFetch(); | 327 StartNextFetch(); |
| 287 } | 328 } |
| 288 | 329 |
| 289 } // namespace precache | 330 } // namespace precache |
| OLD | NEW |