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/escape.h" | 18 #include "net/base/escape.h" |
| 18 #include "net/base/load_flags.h" | 19 #include "net/base/load_flags.h" |
| 19 #include "net/url_request/url_fetcher.h" | 20 #include "net/url_request/url_fetcher.h" |
| 20 #include "net/url_request/url_fetcher_delegate.h" | 21 #include "net/url_request/url_fetcher_delegate.h" |
| 21 #include "net/url_request/url_request_context_getter.h" | 22 #include "net/url_request/url_request_context_getter.h" |
| 22 #include "net/url_request/url_request_status.h" | 23 #include "net/url_request/url_request_status.h" |
| 23 | 24 |
| 24 using net::URLFetcher; | 25 using net::URLFetcher; |
| 25 | 26 |
| 26 namespace precache { | 27 namespace precache { |
| 27 | 28 |
| 28 namespace { | 29 namespace { |
| 29 | 30 |
| 31 // The 99%ile number of bytes we expect to receive during prefetch, and the max | |
|
bengr
2015/06/30 19:26:19
99%ile -> 99th percentile
and the max -> which wi
twifkak
2015/06/30 20:23:51
Done.
| |
| 32 // for the histogram. | |
| 33 const int kMaxResponseBytes = 100 * 1024 * 1024; | |
| 34 | |
| 30 GURL GetConfigURL() { | 35 GURL GetConfigURL() { |
| 31 const base::CommandLine& command_line = | 36 const base::CommandLine& command_line = |
| 32 *base::CommandLine::ForCurrentProcess(); | 37 *base::CommandLine::ForCurrentProcess(); |
| 33 if (command_line.HasSwitch(switches::kPrecacheConfigSettingsURL)) { | 38 if (command_line.HasSwitch(switches::kPrecacheConfigSettingsURL)) { |
| 34 return GURL( | 39 return GURL( |
| 35 command_line.GetSwitchValueASCII(switches::kPrecacheConfigSettingsURL)); | 40 command_line.GetSwitchValueASCII(switches::kPrecacheConfigSettingsURL)); |
| 36 } | 41 } |
| 37 | 42 |
| 38 #if defined(PRECACHE_CONFIG_SETTINGS_URL) | 43 #if defined(PRECACHE_CONFIG_SETTINGS_URL) |
| 39 return GURL(PRECACHE_CONFIG_SETTINGS_URL); | 44 return GURL(PRECACHE_CONFIG_SETTINGS_URL); |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 101 // response to different kinds of fetches, e.g. OnConfigFetchComplete when | 106 // response to different kinds of fetches, e.g. OnConfigFetchComplete when |
| 102 // configuration settings are fetched, OnManifestFetchComplete when a manifest | 107 // configuration settings are fetched, OnManifestFetchComplete when a manifest |
| 103 // is fetched, etc. | 108 // is fetched, etc. |
| 104 class PrecacheFetcher::Fetcher : public net::URLFetcherDelegate { | 109 class PrecacheFetcher::Fetcher : public net::URLFetcherDelegate { |
| 105 public: | 110 public: |
| 106 // Construct a new Fetcher. This will create and start a new URLFetcher for | 111 // Construct a new Fetcher. This will create and start a new URLFetcher for |
| 107 // the specified URL using the specified request context. | 112 // the specified URL using the specified request context. |
| 108 Fetcher(net::URLRequestContextGetter* request_context, const GURL& url, | 113 Fetcher(net::URLRequestContextGetter* request_context, const GURL& url, |
| 109 const base::Callback<void(const URLFetcher&)>& callback); | 114 const base::Callback<void(const URLFetcher&)>& callback); |
| 110 ~Fetcher() override {} | 115 ~Fetcher() override {} |
| 116 void OnURLFetchDownloadProgress(const URLFetcher* source, | |
| 117 int64 current, | |
| 118 int64 total) override; | |
| 111 void OnURLFetchComplete(const URLFetcher* source) override; | 119 void OnURLFetchComplete(const URLFetcher* source) override; |
| 120 int response_bytes() { return response_bytes_; } | |
| 112 | 121 |
| 113 private: | 122 private: |
| 114 const base::Callback<void(const URLFetcher&)> callback_; | 123 const base::Callback<void(const URLFetcher&)> callback_; |
| 115 scoped_ptr<URLFetcher> url_fetcher_; | 124 scoped_ptr<URLFetcher> url_fetcher_; |
| 125 int response_bytes_; | |
| 116 | 126 |
| 117 DISALLOW_COPY_AND_ASSIGN(Fetcher); | 127 DISALLOW_COPY_AND_ASSIGN(Fetcher); |
| 118 }; | 128 }; |
| 119 | 129 |
| 120 PrecacheFetcher::Fetcher::Fetcher( | 130 PrecacheFetcher::Fetcher::Fetcher( |
| 121 net::URLRequestContextGetter* request_context, const GURL& url, | 131 net::URLRequestContextGetter* request_context, |
| 132 const GURL& url, | |
| 122 const base::Callback<void(const URLFetcher&)>& callback) | 133 const base::Callback<void(const URLFetcher&)>& callback) |
| 123 : callback_(callback) { | 134 : callback_(callback), response_bytes_(0) { |
| 124 url_fetcher_ = URLFetcher::Create(url, URLFetcher::GET, this); | 135 url_fetcher_ = URLFetcher::Create(url, URLFetcher::GET, this); |
| 125 url_fetcher_->SetRequestContext(request_context); | 136 url_fetcher_->SetRequestContext(request_context); |
| 126 url_fetcher_->SetLoadFlags(net::LOAD_DO_NOT_SAVE_COOKIES | | 137 url_fetcher_->SetLoadFlags(net::LOAD_DO_NOT_SAVE_COOKIES | |
| 127 net::LOAD_DO_NOT_SEND_COOKIES); | 138 net::LOAD_DO_NOT_SEND_COOKIES); |
| 128 url_fetcher_->Start(); | 139 url_fetcher_->Start(); |
| 129 } | 140 } |
| 130 | 141 |
| 142 void PrecacheFetcher::Fetcher::OnURLFetchDownloadProgress( | |
| 143 const URLFetcher* source, | |
| 144 int64 current, | |
| 145 int64 total) { | |
| 146 response_bytes_ = current; | |
| 147 } | |
| 148 | |
| 131 void PrecacheFetcher::Fetcher::OnURLFetchComplete(const URLFetcher* source) { | 149 void PrecacheFetcher::Fetcher::OnURLFetchComplete(const URLFetcher* source) { |
| 132 callback_.Run(*source); | 150 callback_.Run(*source); |
| 133 } | 151 } |
| 134 | 152 |
| 135 PrecacheFetcher::PrecacheFetcher( | 153 PrecacheFetcher::PrecacheFetcher( |
| 136 const std::vector<std::string>& starting_hosts, | 154 const std::vector<std::string>& starting_hosts, |
| 137 net::URLRequestContextGetter* request_context, | 155 net::URLRequestContextGetter* request_context, |
| 138 const std::string& manifest_url_prefix, | 156 const std::string& manifest_url_prefix, |
| 139 PrecacheFetcher::PrecacheDelegate* precache_delegate) | 157 PrecacheFetcher::PrecacheDelegate* precache_delegate) |
| 140 : starting_hosts_(starting_hosts), | 158 : starting_hosts_(starting_hosts), |
| 141 request_context_(request_context), | 159 request_context_(request_context), |
| 142 manifest_url_prefix_(manifest_url_prefix), | 160 manifest_url_prefix_(manifest_url_prefix), |
| 143 precache_delegate_(precache_delegate) { | 161 precache_delegate_(precache_delegate), |
| 162 total_response_bytes_(0), | |
| 163 num_manifest_urls_to_fetch_(0) { | |
| 144 DCHECK(request_context_.get()); // Request context must be non-NULL. | 164 DCHECK(request_context_.get()); // Request context must be non-NULL. |
| 145 DCHECK(precache_delegate_); // Precache delegate must be non-NULL. | 165 DCHECK(precache_delegate_); // Precache delegate must be non-NULL. |
| 146 | 166 |
| 147 DCHECK_NE(GURL(), GetConfigURL()) | 167 DCHECK_NE(GURL(), GetConfigURL()) |
| 148 << "Could not determine the precache config settings URL."; | 168 << "Could not determine the precache config settings URL."; |
| 149 DCHECK_NE(std::string(), GetDefaultManifestURLPrefix()) | 169 DCHECK_NE(std::string(), GetDefaultManifestURLPrefix()) |
| 150 << "Could not determine the default precache manifest URL prefix."; | 170 << "Could not determine the default precache manifest URL prefix."; |
| 151 } | 171 } |
| 152 | 172 |
| 153 PrecacheFetcher::~PrecacheFetcher() { | 173 PrecacheFetcher::~PrecacheFetcher() { |
| 174 // Number of manifests for which we have downloaded all resources. | |
| 175 int manifests_completed = | |
| 176 num_manifest_urls_to_fetch_ - manifest_urls_to_fetch_.size(); | |
| 177 | |
| 178 // If there are resource URLs left to fetch, the last manifest is not yet | |
| 179 // completed. | |
| 180 if (!resource_urls_to_fetch_.empty()) | |
| 181 --manifests_completed; | |
| 182 | |
| 183 int percent_completed = | |
| 184 manifests_completed == 0 ? 0 : (static_cast<double>(manifests_completed) / | |
| 185 num_manifest_urls_to_fetch_ * 100); | |
|
bengr
2015/06/30 19:26:19
Can num_manifest_urls_to_fetch_ be 0?
twifkak
2015/06/30 20:23:51
Yes, but if num_manifests_urls_to_fetch_ is 0, so
bengr
2015/07/06 17:31:08
DCHECK(num_manifest_urls_to_fetch_ >= manifests_co
twifkak
2015/07/07 00:26:28
OK, added a different DCHECK, but changed the cond
| |
| 186 UMA_HISTOGRAM_PERCENTAGE("Precache.Fetch.PercentCompleted", | |
| 187 percent_completed); | |
| 188 UMA_HISTOGRAM_CUSTOM_COUNTS("Precache.Fetch.ResponseBytes", | |
| 189 total_response_bytes_, 1, kMaxResponseBytes, 50); | |
| 154 } | 190 } |
| 155 | 191 |
| 156 void PrecacheFetcher::Start() { | 192 void PrecacheFetcher::Start() { |
| 157 DCHECK(!fetcher_); // Start shouldn't be called repeatedly. | 193 DCHECK(!fetcher_); // Start shouldn't be called repeatedly. |
| 158 | 194 |
| 159 GURL config_url = GetConfigURL(); | 195 GURL config_url = GetConfigURL(); |
| 160 DCHECK(config_url.is_valid()); | 196 DCHECK(config_url.is_valid()); |
| 161 | 197 |
| 162 // Fetch the precache configuration settings from the server. | 198 // Fetch the precache configuration settings from the server. |
| 163 fetcher_.reset(new Fetcher(request_context_.get(), | 199 fetcher_.reset(new Fetcher(request_context_.get(), |
| 164 config_url, | 200 config_url, |
| 165 base::Bind(&PrecacheFetcher::OnConfigFetchComplete, | 201 base::Bind(&PrecacheFetcher::OnConfigFetchComplete, |
| 166 base::Unretained(this)))); | 202 base::Unretained(this)))); |
| 167 } | 203 } |
| 168 | 204 |
| 169 void PrecacheFetcher::StartNextFetch() { | 205 void PrecacheFetcher::StartNextFetch() { |
| 206 total_response_bytes_ += fetcher_->response_bytes(); | |
| 207 | |
| 170 if (!resource_urls_to_fetch_.empty()) { | 208 if (!resource_urls_to_fetch_.empty()) { |
| 171 // Fetch the next resource URL. | 209 // Fetch the next resource URL. |
| 172 fetcher_.reset( | 210 fetcher_.reset( |
| 173 new Fetcher(request_context_.get(), | 211 new Fetcher(request_context_.get(), |
| 174 resource_urls_to_fetch_.front(), | 212 resource_urls_to_fetch_.front(), |
| 175 base::Bind(&PrecacheFetcher::OnResourceFetchComplete, | 213 base::Bind(&PrecacheFetcher::OnResourceFetchComplete, |
| 176 base::Unretained(this)))); | 214 base::Unretained(this)))); |
| 177 | 215 |
| 178 resource_urls_to_fetch_.pop_front(); | 216 resource_urls_to_fetch_.pop_front(); |
| 179 return; | 217 return; |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 222 if (rank > config.top_sites_count()) | 260 if (rank > config.top_sites_count()) |
| 223 break; | 261 break; |
| 224 unique_manifest_urls.insert(ConstructManifestURL(prefix, host)); | 262 unique_manifest_urls.insert(ConstructManifestURL(prefix, host)); |
| 225 } | 263 } |
| 226 | 264 |
| 227 for (const std::string& url : config.forced_site()) | 265 for (const std::string& url : config.forced_site()) |
| 228 unique_manifest_urls.insert(ConstructManifestURL(prefix, url)); | 266 unique_manifest_urls.insert(ConstructManifestURL(prefix, url)); |
| 229 | 267 |
| 230 for (const std::string& manifest_url : unique_manifest_urls) | 268 for (const std::string& manifest_url : unique_manifest_urls) |
| 231 manifest_urls_to_fetch_.push_back(GURL(manifest_url)); | 269 manifest_urls_to_fetch_.push_back(GURL(manifest_url)); |
| 270 num_manifest_urls_to_fetch_ = manifest_urls_to_fetch_.size(); | |
| 232 | 271 |
| 233 StartNextFetch(); | 272 StartNextFetch(); |
| 234 } | 273 } |
| 235 | 274 |
| 236 void PrecacheFetcher::OnManifestFetchComplete(const URLFetcher& source) { | 275 void PrecacheFetcher::OnManifestFetchComplete(const URLFetcher& source) { |
| 237 PrecacheManifest manifest; | 276 PrecacheManifest manifest; |
| 238 | 277 |
| 239 if (ParseProtoFromFetchResponse(source, &manifest)) { | 278 if (ParseProtoFromFetchResponse(source, &manifest)) { |
| 240 for (int i = 0; i < manifest.resource_size(); ++i) { | 279 for (int i = 0; i < manifest.resource_size(); ++i) { |
| 241 if (manifest.resource(i).has_url()) { | 280 if (manifest.resource(i).has_url()) { |
| 242 resource_urls_to_fetch_.push_back(GURL(manifest.resource(i).url())); | 281 resource_urls_to_fetch_.push_back(GURL(manifest.resource(i).url())); |
| 243 } | 282 } |
| 244 } | 283 } |
| 245 } | 284 } |
| 246 | 285 |
| 247 StartNextFetch(); | 286 StartNextFetch(); |
| 248 } | 287 } |
| 249 | 288 |
| 250 void PrecacheFetcher::OnResourceFetchComplete(const URLFetcher& source) { | 289 void PrecacheFetcher::OnResourceFetchComplete(const URLFetcher& source) { |
| 251 // The resource has already been put in the cache during the fetch process, so | 290 // The resource has already been put in the cache during the fetch process, so |
| 252 // nothing more needs to be done for the resource. | 291 // nothing more needs to be done for the resource. |
| 253 StartNextFetch(); | 292 StartNextFetch(); |
| 254 } | 293 } |
| 255 | 294 |
| 256 } // namespace precache | 295 } // namespace precache |
| OLD | NEW |