OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 "chrome/browser/safe_browsing/protocol_manager.h" | 5 #include "chrome/browser/safe_browsing/protocol_manager.h" |
6 | 6 |
7 #include "base/environment.h" | 7 #include "base/environment.h" |
8 #include "base/logging.h" | 8 #include "base/logging.h" |
9 #include "base/memory/scoped_vector.h" | 9 #include "base/memory/scoped_vector.h" |
10 #include "base/metrics/histogram_macros.h" | 10 #include "base/metrics/histogram_macros.h" |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
67 kSBUpdateFrequencyFinchExperiment, kSBUpdateFrequencyFinchParam); | 67 kSBUpdateFrequencyFinchExperiment, kSBUpdateFrequencyFinchParam); |
68 int finch_next_update_interval_minutes = 0; | 68 int finch_next_update_interval_minutes = 0; |
69 if (!base::StringToInt(num_str, &finch_next_update_interval_minutes)) { | 69 if (!base::StringToInt(num_str, &finch_next_update_interval_minutes)) { |
70 finch_next_update_interval_minutes = 0; // Defaults to 0. | 70 finch_next_update_interval_minutes = 0; // Defaults to 0. |
71 } | 71 } |
72 return base::TimeDelta::FromMinutes(finch_next_update_interval_minutes); | 72 return base::TimeDelta::FromMinutes(finch_next_update_interval_minutes); |
73 } | 73 } |
74 | 74 |
75 } // namespace | 75 } // namespace |
76 | 76 |
| 77 namespace safe_browsing { |
| 78 |
77 // Minimum time, in seconds, from start up before we must issue an update query. | 79 // Minimum time, in seconds, from start up before we must issue an update query. |
78 static const int kSbTimerStartIntervalSecMin = 60; | 80 static const int kSbTimerStartIntervalSecMin = 60; |
79 | 81 |
80 // Maximum time, in seconds, from start up before we must issue an update query. | 82 // Maximum time, in seconds, from start up before we must issue an update query. |
81 static const int kSbTimerStartIntervalSecMax = 300; | 83 static const int kSbTimerStartIntervalSecMax = 300; |
82 | 84 |
83 // The maximum time, in seconds, to wait for a response to an update request. | 85 // The maximum time, in seconds, to wait for a response to an update request. |
84 static const int kSbMaxUpdateWaitSec = 30; | 86 static const int kSbMaxUpdateWaitSec = 30; |
85 | 87 |
86 // Maximum back off multiplier. | 88 // Maximum back off multiplier. |
87 static const size_t kSbMaxBackOff = 8; | 89 static const size_t kSbMaxBackOff = 8; |
88 | 90 |
89 const char kUmaHashResponseMetricName[] = "SB2.GetHashResponseOrErrorCode"; | 91 const char kUmaHashResponseMetricName[] = "SB2.GetHashResponseOrErrorCode"; |
90 | 92 |
91 // The default SBProtocolManagerFactory. | 93 // The default SBProtocolManagerFactory. |
92 class SBProtocolManagerFactoryImpl : public SBProtocolManagerFactory { | 94 class SBProtocolManagerFactoryImpl : public SBProtocolManagerFactory { |
93 public: | 95 public: |
94 SBProtocolManagerFactoryImpl() { } | 96 SBProtocolManagerFactoryImpl() {} |
95 ~SBProtocolManagerFactoryImpl() override {} | 97 ~SBProtocolManagerFactoryImpl() override {} |
96 SafeBrowsingProtocolManager* CreateProtocolManager( | 98 SafeBrowsingProtocolManager* CreateProtocolManager( |
97 SafeBrowsingProtocolManagerDelegate* delegate, | 99 SafeBrowsingProtocolManagerDelegate* delegate, |
98 net::URLRequestContextGetter* request_context_getter, | 100 net::URLRequestContextGetter* request_context_getter, |
99 const SafeBrowsingProtocolConfig& config) override { | 101 const SafeBrowsingProtocolConfig& config) override { |
100 return new SafeBrowsingProtocolManager( | 102 return new SafeBrowsingProtocolManager(delegate, request_context_getter, |
101 delegate, request_context_getter, config); | 103 config); |
102 } | 104 } |
| 105 |
103 private: | 106 private: |
104 DISALLOW_COPY_AND_ASSIGN(SBProtocolManagerFactoryImpl); | 107 DISALLOW_COPY_AND_ASSIGN(SBProtocolManagerFactoryImpl); |
105 }; | 108 }; |
106 | 109 |
107 // SafeBrowsingProtocolManager implementation ---------------------------------- | 110 // SafeBrowsingProtocolManager implementation ---------------------------------- |
108 | 111 |
109 // static | 112 // static |
110 SBProtocolManagerFactory* SafeBrowsingProtocolManager::factory_ = NULL; | 113 SBProtocolManagerFactory* SafeBrowsingProtocolManager::factory_ = NULL; |
111 | 114 |
112 // static | 115 // static |
113 SafeBrowsingProtocolManager* SafeBrowsingProtocolManager::Create( | 116 SafeBrowsingProtocolManager* SafeBrowsingProtocolManager::Create( |
114 SafeBrowsingProtocolManagerDelegate* delegate, | 117 SafeBrowsingProtocolManagerDelegate* delegate, |
115 net::URLRequestContextGetter* request_context_getter, | 118 net::URLRequestContextGetter* request_context_getter, |
116 const SafeBrowsingProtocolConfig& config) { | 119 const SafeBrowsingProtocolConfig& config) { |
117 // TODO(cbentzel): Remove ScopedTracker below once crbug.com/483689 is fixed. | 120 // TODO(cbentzel): Remove ScopedTracker below once crbug.com/483689 is fixed. |
118 tracked_objects::ScopedTracker tracking_profile( | 121 tracked_objects::ScopedTracker tracking_profile( |
119 FROM_HERE_WITH_EXPLICIT_FUNCTION( | 122 FROM_HERE_WITH_EXPLICIT_FUNCTION( |
120 "483689 SafeBrowsingProtocolManager::Create")); | 123 "483689 SafeBrowsingProtocolManager::Create")); |
121 if (!factory_) | 124 if (!factory_) |
122 factory_ = new SBProtocolManagerFactoryImpl(); | 125 factory_ = new SBProtocolManagerFactoryImpl(); |
123 return factory_->CreateProtocolManager( | 126 return factory_->CreateProtocolManager(delegate, request_context_getter, |
124 delegate, request_context_getter, config); | 127 config); |
125 } | 128 } |
126 | 129 |
127 SafeBrowsingProtocolManager::SafeBrowsingProtocolManager( | 130 SafeBrowsingProtocolManager::SafeBrowsingProtocolManager( |
128 SafeBrowsingProtocolManagerDelegate* delegate, | 131 SafeBrowsingProtocolManagerDelegate* delegate, |
129 net::URLRequestContextGetter* request_context_getter, | 132 net::URLRequestContextGetter* request_context_getter, |
130 const SafeBrowsingProtocolConfig& config) | 133 const SafeBrowsingProtocolConfig& config) |
131 : delegate_(delegate), | 134 : delegate_(delegate), |
132 request_type_(NO_REQUEST), | 135 request_type_(NO_REQUEST), |
133 update_error_count_(0), | 136 update_error_count_(0), |
134 gethash_error_count_(0), | 137 gethash_error_count_(0), |
(...skipping 21 matching lines...) Expand all Loading... |
156 backup_url_prefixes_[BACKUP_UPDATE_REASON_NETWORK] = | 159 backup_url_prefixes_[BACKUP_UPDATE_REASON_NETWORK] = |
157 config.backup_network_error_url_prefix; | 160 config.backup_network_error_url_prefix; |
158 | 161 |
159 // Set the backoff multiplier fuzz to a random value between 0 and 1. | 162 // Set the backoff multiplier fuzz to a random value between 0 and 1. |
160 back_off_fuzz_ = static_cast<float>(base::RandDouble()); | 163 back_off_fuzz_ = static_cast<float>(base::RandDouble()); |
161 if (version_.empty()) | 164 if (version_.empty()) |
162 version_ = SafeBrowsingProtocolManagerHelper::Version(); | 165 version_ = SafeBrowsingProtocolManagerHelper::Version(); |
163 } | 166 } |
164 | 167 |
165 // static | 168 // static |
166 void SafeBrowsingProtocolManager::RecordGetHashResult( | 169 void SafeBrowsingProtocolManager::RecordGetHashResult(bool is_download, |
167 bool is_download, ResultType result_type) { | 170 ResultType result_type) { |
168 if (is_download) { | 171 if (is_download) { |
169 UMA_HISTOGRAM_ENUMERATION("SB2.GetHashResultDownload", result_type, | 172 UMA_HISTOGRAM_ENUMERATION("SB2.GetHashResultDownload", result_type, |
170 GET_HASH_RESULT_MAX); | 173 GET_HASH_RESULT_MAX); |
171 } else { | 174 } else { |
172 UMA_HISTOGRAM_ENUMERATION("SB2.GetHashResult", result_type, | 175 UMA_HISTOGRAM_ENUMERATION("SB2.GetHashResult", result_type, |
173 GET_HASH_RESULT_MAX); | 176 GET_HASH_RESULT_MAX); |
174 } | 177 } |
175 } | 178 } |
176 | 179 |
177 void SafeBrowsingProtocolManager::RecordHttpResponseOrErrorCode( | 180 void SafeBrowsingProtocolManager::RecordHttpResponseOrErrorCode( |
178 const char* metric_name, const net::URLRequestStatus& status, | 181 const char* metric_name, |
| 182 const net::URLRequestStatus& status, |
179 int response_code) { | 183 int response_code) { |
180 UMA_HISTOGRAM_SPARSE_SLOWLY( | 184 UMA_HISTOGRAM_SPARSE_SLOWLY( |
181 metric_name, status.is_success() ? response_code : status.error()); | 185 metric_name, status.is_success() ? response_code : status.error()); |
182 } | 186 } |
183 | 187 |
184 bool SafeBrowsingProtocolManager::IsUpdateScheduled() const { | 188 bool SafeBrowsingProtocolManager::IsUpdateScheduled() const { |
185 return update_timer_.IsRunning(); | 189 return update_timer_.IsRunning(); |
186 } | 190 } |
187 | 191 |
188 SafeBrowsingProtocolManager::~SafeBrowsingProtocolManager() { | 192 SafeBrowsingProtocolManager::~SafeBrowsingProtocolManager() { |
(...skipping 17 matching lines...) Expand all Loading... |
206 // required to return empty results (i.e. treat the page as safe). | 210 // required to return empty results (i.e. treat the page as safe). |
207 if (gethash_error_count_ && Time::Now() <= next_gethash_time_) { | 211 if (gethash_error_count_ && Time::Now() <= next_gethash_time_) { |
208 RecordGetHashResult(is_download, GET_HASH_BACKOFF_ERROR); | 212 RecordGetHashResult(is_download, GET_HASH_BACKOFF_ERROR); |
209 std::vector<SBFullHashResult> full_hashes; | 213 std::vector<SBFullHashResult> full_hashes; |
210 callback.Run(full_hashes, base::TimeDelta()); | 214 callback.Run(full_hashes, base::TimeDelta()); |
211 return; | 215 return; |
212 } | 216 } |
213 GURL gethash_url = GetHashUrl(is_extended_reporting); | 217 GURL gethash_url = GetHashUrl(is_extended_reporting); |
214 net::URLFetcher* fetcher = | 218 net::URLFetcher* fetcher = |
215 net::URLFetcher::Create(url_fetcher_id_++, gethash_url, | 219 net::URLFetcher::Create(url_fetcher_id_++, gethash_url, |
216 net::URLFetcher::POST, this).release(); | 220 net::URLFetcher::POST, this) |
| 221 .release(); |
217 hash_requests_[fetcher] = FullHashDetails(callback, is_download); | 222 hash_requests_[fetcher] = FullHashDetails(callback, is_download); |
218 | 223 |
219 const std::string get_hash = safe_browsing::FormatGetHash(prefixes); | 224 const std::string get_hash = FormatGetHash(prefixes); |
220 | 225 |
221 fetcher->SetLoadFlags(net::LOAD_DISABLE_CACHE); | 226 fetcher->SetLoadFlags(net::LOAD_DISABLE_CACHE); |
222 fetcher->SetRequestContext(request_context_getter_.get()); | 227 fetcher->SetRequestContext(request_context_getter_.get()); |
223 fetcher->SetUploadData("text/plain", get_hash); | 228 fetcher->SetUploadData("text/plain", get_hash); |
224 fetcher->Start(); | 229 fetcher->Start(); |
225 } | 230 } |
226 | 231 |
227 void SafeBrowsingProtocolManager::GetNextUpdate() { | 232 void SafeBrowsingProtocolManager::GetNextUpdate() { |
228 DCHECK(CalledOnValidThread()); | 233 DCHECK(CalledOnValidThread()); |
229 if (request_.get() || request_type_ != NO_REQUEST) | 234 if (request_.get() || request_type_ != NO_REQUEST) |
(...skipping 13 matching lines...) Expand all Loading... |
243 // do will report all the chunks we have. If that chunk is still | 248 // do will report all the chunks we have. If that chunk is still |
244 // required, the SafeBrowsing servers will tell us to get it again. | 249 // required, the SafeBrowsing servers will tell us to get it again. |
245 void SafeBrowsingProtocolManager::OnURLFetchComplete( | 250 void SafeBrowsingProtocolManager::OnURLFetchComplete( |
246 const net::URLFetcher* source) { | 251 const net::URLFetcher* source) { |
247 DCHECK(CalledOnValidThread()); | 252 DCHECK(CalledOnValidThread()); |
248 scoped_ptr<const net::URLFetcher> fetcher; | 253 scoped_ptr<const net::URLFetcher> fetcher; |
249 | 254 |
250 HashRequests::iterator it = hash_requests_.find(source); | 255 HashRequests::iterator it = hash_requests_.find(source); |
251 int response_code = source->GetResponseCode(); | 256 int response_code = source->GetResponseCode(); |
252 net::URLRequestStatus status = source->GetStatus(); | 257 net::URLRequestStatus status = source->GetStatus(); |
253 RecordHttpResponseOrErrorCode( | 258 RecordHttpResponseOrErrorCode(kUmaHashResponseMetricName, status, |
254 kUmaHashResponseMetricName, status, response_code); | 259 response_code); |
255 if (it != hash_requests_.end()) { | 260 if (it != hash_requests_.end()) { |
256 // GetHash response. | 261 // GetHash response. |
257 fetcher.reset(it->first); | 262 fetcher.reset(it->first); |
258 const FullHashDetails& details = it->second; | 263 const FullHashDetails& details = it->second; |
259 std::vector<SBFullHashResult> full_hashes; | 264 std::vector<SBFullHashResult> full_hashes; |
260 base::TimeDelta cache_lifetime; | 265 base::TimeDelta cache_lifetime; |
261 if (status.is_success() && | 266 if (status.is_success() && (response_code == net::HTTP_OK || |
262 (response_code == net::HTTP_OK || | 267 response_code == net::HTTP_NO_CONTENT)) { |
263 response_code == net::HTTP_NO_CONTENT)) { | |
264 // For tracking our GetHash false positive (net::HTTP_NO_CONTENT) rate, | 268 // For tracking our GetHash false positive (net::HTTP_NO_CONTENT) rate, |
265 // compared to real (net::HTTP_OK) responses. | 269 // compared to real (net::HTTP_OK) responses. |
266 if (response_code == net::HTTP_OK) | 270 if (response_code == net::HTTP_OK) |
267 RecordGetHashResult(details.is_download, GET_HASH_STATUS_200); | 271 RecordGetHashResult(details.is_download, GET_HASH_STATUS_200); |
268 else | 272 else |
269 RecordGetHashResult(details.is_download, GET_HASH_STATUS_204); | 273 RecordGetHashResult(details.is_download, GET_HASH_STATUS_204); |
270 | 274 |
271 gethash_error_count_ = 0; | 275 gethash_error_count_ = 0; |
272 gethash_back_off_mult_ = 1; | 276 gethash_back_off_mult_ = 1; |
273 std::string data; | 277 std::string data; |
274 source->GetResponseAsString(&data); | 278 source->GetResponseAsString(&data); |
275 if (!safe_browsing::ParseGetHash( | 279 if (!ParseGetHash(data.data(), data.length(), &cache_lifetime, |
276 data.data(), data.length(), &cache_lifetime, &full_hashes)) { | 280 &full_hashes)) { |
277 full_hashes.clear(); | 281 full_hashes.clear(); |
278 RecordGetHashResult(details.is_download, GET_HASH_PARSE_ERROR); | 282 RecordGetHashResult(details.is_download, GET_HASH_PARSE_ERROR); |
279 // TODO(cbentzel): Should cache_lifetime be set to 0 here? (See | 283 // TODO(cbentzel): Should cache_lifetime be set to 0 here? (See |
280 // http://crbug.com/360232.) | 284 // http://crbug.com/360232.) |
281 } | 285 } |
282 } else { | 286 } else { |
283 HandleGetHashError(Time::Now()); | 287 HandleGetHashError(Time::Now()); |
284 if (status.status() == net::URLRequestStatus::FAILED) { | 288 if (status.status() == net::URLRequestStatus::FAILED) { |
285 RecordGetHashResult(details.is_download, GET_HASH_NETWORK_ERROR); | 289 RecordGetHashResult(details.is_download, GET_HASH_NETWORK_ERROR); |
286 DVLOG(1) << "SafeBrowsing GetHash request for: " << source->GetURL() | 290 DVLOG(1) << "SafeBrowsing GetHash request for: " << source->GetURL() |
(...skipping 27 matching lines...) Expand all Loading... |
314 timeout_timer_.Stop(); | 318 timeout_timer_.Stop(); |
315 } | 319 } |
316 | 320 |
317 if (status.is_success() && response_code == net::HTTP_OK) { | 321 if (status.is_success() && response_code == net::HTTP_OK) { |
318 // We have data from the SafeBrowsing service. | 322 // We have data from the SafeBrowsing service. |
319 std::string data; | 323 std::string data; |
320 source->GetResponseAsString(&data); | 324 source->GetResponseAsString(&data); |
321 | 325 |
322 // TODO(shess): Cleanup the flow of this code so that |parsed_ok| can be | 326 // TODO(shess): Cleanup the flow of this code so that |parsed_ok| can be |
323 // removed or omitted. | 327 // removed or omitted. |
324 const bool parsed_ok = HandleServiceResponse( | 328 const bool parsed_ok = |
325 source->GetURL(), data.data(), data.length()); | 329 HandleServiceResponse(source->GetURL(), data.data(), data.length()); |
326 if (!parsed_ok) { | 330 if (!parsed_ok) { |
327 DVLOG(1) << "SafeBrowsing request for: " << source->GetURL() | 331 DVLOG(1) << "SafeBrowsing request for: " << source->GetURL() |
328 << " failed parse."; | 332 << " failed parse."; |
329 chunk_request_urls_.clear(); | 333 chunk_request_urls_.clear(); |
330 if (request_type_ == UPDATE_REQUEST && | 334 if (request_type_ == UPDATE_REQUEST && |
331 IssueBackupUpdateRequest(BACKUP_UPDATE_REASON_HTTP)) { | 335 IssueBackupUpdateRequest(BACKUP_UPDATE_REASON_HTTP)) { |
332 return; | 336 return; |
333 } | 337 } |
334 UpdateFinished(false); | 338 UpdateFinished(false); |
335 } | 339 } |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
389 } | 393 } |
390 } | 394 } |
391 UpdateFinished(false); | 395 UpdateFinished(false); |
392 } | 396 } |
393 } | 397 } |
394 | 398 |
395 // Get the next chunk if available. | 399 // Get the next chunk if available. |
396 IssueChunkRequest(); | 400 IssueChunkRequest(); |
397 } | 401 } |
398 | 402 |
399 bool SafeBrowsingProtocolManager::HandleServiceResponse( | 403 bool SafeBrowsingProtocolManager::HandleServiceResponse(const GURL& url, |
400 const GURL& url, const char* data, size_t length) { | 404 const char* data, |
| 405 size_t length) { |
401 DCHECK(CalledOnValidThread()); | 406 DCHECK(CalledOnValidThread()); |
402 | 407 |
403 switch (request_type_) { | 408 switch (request_type_) { |
404 case UPDATE_REQUEST: | 409 case UPDATE_REQUEST: |
405 case BACKUP_UPDATE_REQUEST: { | 410 case BACKUP_UPDATE_REQUEST: { |
406 size_t next_update_sec = 0; | 411 size_t next_update_sec = 0; |
407 bool reset = false; | 412 bool reset = false; |
408 scoped_ptr<std::vector<SBChunkDelete> > chunk_deletes( | 413 scoped_ptr<std::vector<SBChunkDelete>> chunk_deletes( |
409 new std::vector<SBChunkDelete>); | 414 new std::vector<SBChunkDelete>); |
410 std::vector<ChunkUrl> chunk_urls; | 415 std::vector<ChunkUrl> chunk_urls; |
411 if (!safe_browsing::ParseUpdate(data, length, &next_update_sec, &reset, | 416 if (!ParseUpdate(data, length, &next_update_sec, &reset, |
412 chunk_deletes.get(), &chunk_urls)) { | 417 chunk_deletes.get(), &chunk_urls)) { |
413 return false; | 418 return false; |
414 } | 419 } |
415 | 420 |
416 // New time for the next update. | 421 // New time for the next update. |
417 base::TimeDelta finch_next_update_interval = | 422 base::TimeDelta finch_next_update_interval = |
418 GetNextUpdateIntervalFromFinch(); | 423 GetNextUpdateIntervalFromFinch(); |
419 if (finch_next_update_interval > base::TimeDelta()) { | 424 if (finch_next_update_interval > base::TimeDelta()) { |
420 next_update_interval_ = finch_next_update_interval; | 425 next_update_interval_ = finch_next_update_interval; |
421 } else { | 426 } else { |
422 base::TimeDelta next_update_interval = | 427 base::TimeDelta next_update_interval = |
423 base::TimeDelta::FromSeconds(next_update_sec); | 428 base::TimeDelta::FromSeconds(next_update_sec); |
424 if (next_update_interval > base::TimeDelta()) { | 429 if (next_update_interval > base::TimeDelta()) { |
425 next_update_interval_ = next_update_interval; | 430 next_update_interval_ = next_update_interval; |
426 } | 431 } |
427 } | 432 } |
428 last_update_ = Time::Now(); | 433 last_update_ = Time::Now(); |
429 | 434 |
430 // New chunks to download. | 435 // New chunks to download. |
(...skipping 14 matching lines...) Expand all Loading... |
445 if (!chunk_deletes->empty()) | 450 if (!chunk_deletes->empty()) |
446 delegate_->DeleteChunks(chunk_deletes.Pass()); | 451 delegate_->DeleteChunks(chunk_deletes.Pass()); |
447 | 452 |
448 break; | 453 break; |
449 } | 454 } |
450 case CHUNK_REQUEST: { | 455 case CHUNK_REQUEST: { |
451 UMA_HISTOGRAM_TIMES("SB2.ChunkRequest", | 456 UMA_HISTOGRAM_TIMES("SB2.ChunkRequest", |
452 base::Time::Now() - chunk_request_start_); | 457 base::Time::Now() - chunk_request_start_); |
453 | 458 |
454 const ChunkUrl chunk_url = chunk_request_urls_.front(); | 459 const ChunkUrl chunk_url = chunk_request_urls_.front(); |
455 scoped_ptr<ScopedVector<SBChunkData> > | 460 scoped_ptr<ScopedVector<SBChunkData>> chunks( |
456 chunks(new ScopedVector<SBChunkData>); | 461 new ScopedVector<SBChunkData>); |
457 UMA_HISTOGRAM_COUNTS("SB2.ChunkSize", length); | 462 UMA_HISTOGRAM_COUNTS("SB2.ChunkSize", length); |
458 update_size_ += length; | 463 update_size_ += length; |
459 if (!safe_browsing::ParseChunk(data, length, chunks.get())) | 464 if (!ParseChunk(data, length, chunks.get())) |
460 return false; | 465 return false; |
461 | 466 |
462 // Chunks to add to storage. Pass ownership of |chunks|. | 467 // Chunks to add to storage. Pass ownership of |chunks|. |
463 if (!chunks->empty()) { | 468 if (!chunks->empty()) { |
464 chunk_pending_to_write_ = true; | 469 chunk_pending_to_write_ = true; |
465 delegate_->AddChunks( | 470 delegate_->AddChunks( |
466 chunk_url.list_name, chunks.Pass(), | 471 chunk_url.list_name, chunks.Pass(), |
467 base::Bind(&SafeBrowsingProtocolManager::OnAddChunksComplete, | 472 base::Bind(&SafeBrowsingProtocolManager::OnAddChunksComplete, |
468 base::Unretained(this))); | 473 base::Unretained(this))); |
469 } | 474 } |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
525 next = GetNextBackOffInterval(&update_error_count_, &update_back_off_mult_); | 530 next = GetNextBackOffInterval(&update_error_count_, &update_back_off_mult_); |
526 } else { | 531 } else { |
527 // Successful response means error reset. | 532 // Successful response means error reset. |
528 update_error_count_ = 0; | 533 update_error_count_ = 0; |
529 update_back_off_mult_ = 1; | 534 update_back_off_mult_ = 1; |
530 } | 535 } |
531 return next; | 536 return next; |
532 } | 537 } |
533 | 538 |
534 base::TimeDelta SafeBrowsingProtocolManager::GetNextBackOffInterval( | 539 base::TimeDelta SafeBrowsingProtocolManager::GetNextBackOffInterval( |
535 size_t* error_count, size_t* multiplier) const { | 540 size_t* error_count, |
| 541 size_t* multiplier) const { |
536 DCHECK(CalledOnValidThread()); | 542 DCHECK(CalledOnValidThread()); |
537 DCHECK(multiplier && error_count); | 543 DCHECK(multiplier && error_count); |
538 (*error_count)++; | 544 (*error_count)++; |
539 if (*error_count > 1 && *error_count < 6) { | 545 if (*error_count > 1 && *error_count < 6) { |
540 base::TimeDelta next = base::TimeDelta::FromMinutes( | 546 base::TimeDelta next = |
541 *multiplier * (1 + back_off_fuzz_) * 30); | 547 base::TimeDelta::FromMinutes(*multiplier * (1 + back_off_fuzz_) * 30); |
542 *multiplier *= 2; | 548 *multiplier *= 2; |
543 if (*multiplier > kSbMaxBackOff) | 549 if (*multiplier > kSbMaxBackOff) |
544 *multiplier = kSbMaxBackOff; | 550 *multiplier = kSbMaxBackOff; |
545 return next; | 551 return next; |
546 } | 552 } |
547 if (*error_count >= 6) | 553 if (*error_count >= 6) |
548 return base::TimeDelta::FromHours(8); | 554 return base::TimeDelta::FromHours(8); |
549 return base::TimeDelta::FromMinutes(1); | 555 return base::TimeDelta::FromMinutes(1); |
550 } | 556 } |
551 | 557 |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
624 if (database_error) { | 630 if (database_error) { |
625 // The update was not successful, but don't back off. | 631 // The update was not successful, but don't back off. |
626 UpdateFinished(false, false); | 632 UpdateFinished(false, false); |
627 return; | 633 return; |
628 } | 634 } |
629 | 635 |
630 // Format our stored chunks: | 636 // Format our stored chunks: |
631 bool found_malware = false; | 637 bool found_malware = false; |
632 bool found_phishing = false; | 638 bool found_phishing = false; |
633 for (size_t i = 0; i < lists.size(); ++i) { | 639 for (size_t i = 0; i < lists.size(); ++i) { |
634 update_list_data_.append(safe_browsing::FormatList(lists[i])); | 640 update_list_data_.append(FormatList(lists[i])); |
635 if (lists[i].name == safe_browsing::kPhishingList) | 641 if (lists[i].name == kPhishingList) |
636 found_phishing = true; | 642 found_phishing = true; |
637 | 643 |
638 if (lists[i].name == safe_browsing::kMalwareList) | 644 if (lists[i].name == kMalwareList) |
639 found_malware = true; | 645 found_malware = true; |
640 } | 646 } |
641 | 647 |
642 // If we have an empty database, let the server know we want data for these | 648 // If we have an empty database, let the server know we want data for these |
643 // lists. | 649 // lists. |
644 // TODO(shess): These cases never happen because the database fills in the | 650 // TODO(shess): These cases never happen because the database fills in the |
645 // lists in GetChunks(). Refactor the unit tests so that this code can be | 651 // lists in GetChunks(). Refactor the unit tests so that this code can be |
646 // removed. | 652 // removed. |
647 if (!found_phishing) { | 653 if (!found_phishing) { |
648 update_list_data_.append(safe_browsing::FormatList( | 654 update_list_data_.append(FormatList(SBListChunkRanges(kPhishingList))); |
649 SBListChunkRanges(safe_browsing::kPhishingList))); | |
650 } | 655 } |
651 if (!found_malware) { | 656 if (!found_malware) { |
652 update_list_data_.append(safe_browsing::FormatList( | 657 update_list_data_.append(FormatList(SBListChunkRanges(kMalwareList))); |
653 SBListChunkRanges(safe_browsing::kMalwareList))); | |
654 } | 658 } |
655 | 659 |
656 // Large requests are (probably) a sign of database corruption. | 660 // Large requests are (probably) a sign of database corruption. |
657 // Record stats to inform decisions about whether to automate | 661 // Record stats to inform decisions about whether to automate |
658 // deletion of such databases. http://crbug.com/120219 | 662 // deletion of such databases. http://crbug.com/120219 |
659 UMA_HISTOGRAM_COUNTS("SB2.UpdateRequestSize", update_list_data_.size()); | 663 UMA_HISTOGRAM_COUNTS("SB2.UpdateRequestSize", update_list_data_.size()); |
660 | 664 |
661 GURL update_url = UpdateUrl(is_extended_reporting); | 665 GURL update_url = UpdateUrl(is_extended_reporting); |
662 request_ = net::URLFetcher::Create(url_fetcher_id_++, update_url, | 666 request_ = net::URLFetcher::Create(url_fetcher_id_++, update_url, |
663 net::URLFetcher::POST, this); | 667 net::URLFetcher::POST, this); |
(...skipping 29 matching lines...) Expand all Loading... |
693 if (chunk_request_urls_.empty()) { | 697 if (chunk_request_urls_.empty()) { |
694 UMA_HISTOGRAM_LONG_TIMES("SB2.Update", Time::Now() - last_update_); | 698 UMA_HISTOGRAM_LONG_TIMES("SB2.Update", Time::Now() - last_update_); |
695 UpdateFinished(true); | 699 UpdateFinished(true); |
696 } else { | 700 } else { |
697 IssueChunkRequest(); | 701 IssueChunkRequest(); |
698 } | 702 } |
699 } | 703 } |
700 | 704 |
701 void SafeBrowsingProtocolManager::HandleGetHashError(const Time& now) { | 705 void SafeBrowsingProtocolManager::HandleGetHashError(const Time& now) { |
702 DCHECK(CalledOnValidThread()); | 706 DCHECK(CalledOnValidThread()); |
703 base::TimeDelta next = GetNextBackOffInterval( | 707 base::TimeDelta next = |
704 &gethash_error_count_, &gethash_back_off_mult_); | 708 GetNextBackOffInterval(&gethash_error_count_, &gethash_back_off_mult_); |
705 next_gethash_time_ = now + next; | 709 next_gethash_time_ = now + next; |
706 } | 710 } |
707 | 711 |
708 void SafeBrowsingProtocolManager::UpdateFinished(bool success) { | 712 void SafeBrowsingProtocolManager::UpdateFinished(bool success) { |
709 UpdateFinished(success, !success); | 713 UpdateFinished(success, !success); |
710 } | 714 } |
711 | 715 |
712 void SafeBrowsingProtocolManager::UpdateFinished(bool success, bool back_off) { | 716 void SafeBrowsingProtocolManager::UpdateFinished(bool success, bool back_off) { |
713 DCHECK(CalledOnValidThread()); | 717 DCHECK(CalledOnValidThread()); |
714 UMA_HISTOGRAM_COUNTS("SB2.UpdateSize", update_size_); | 718 UMA_HISTOGRAM_COUNTS("SB2.UpdateSize", update_size_); |
715 update_size_ = 0; | 719 update_size_ = 0; |
716 bool update_success = success || request_type_ == CHUNK_REQUEST; | 720 bool update_success = success || request_type_ == CHUNK_REQUEST; |
717 if (backup_update_reason_ == BACKUP_UPDATE_REASON_MAX) { | 721 if (backup_update_reason_ == BACKUP_UPDATE_REASON_MAX) { |
718 RecordUpdateResult( | 722 RecordUpdateResult(update_success ? UPDATE_RESULT_SUCCESS |
719 update_success ? UPDATE_RESULT_SUCCESS : UPDATE_RESULT_FAIL); | 723 : UPDATE_RESULT_FAIL); |
720 } else { | 724 } else { |
721 UpdateResult update_result = static_cast<UpdateResult>( | 725 UpdateResult update_result = static_cast<UpdateResult>( |
722 UPDATE_RESULT_BACKUP_START + | 726 UPDATE_RESULT_BACKUP_START + |
723 (static_cast<int>(backup_update_reason_) * 2) + | 727 (static_cast<int>(backup_update_reason_) * 2) + update_success); |
724 update_success); | |
725 RecordUpdateResult(update_result); | 728 RecordUpdateResult(update_result); |
726 } | 729 } |
727 backup_update_reason_ = BACKUP_UPDATE_REASON_MAX; | 730 backup_update_reason_ = BACKUP_UPDATE_REASON_MAX; |
728 request_type_ = NO_REQUEST; | 731 request_type_ = NO_REQUEST; |
729 update_list_data_.clear(); | 732 update_list_data_.clear(); |
730 delegate_->UpdateFinished(success); | 733 delegate_->UpdateFinished(success); |
731 ScheduleNextUpdate(back_off); | 734 ScheduleNextUpdate(back_off); |
732 } | 735 } |
733 | 736 |
734 GURL SafeBrowsingProtocolManager::UpdateUrl(bool is_extended_reporting) const { | 737 GURL SafeBrowsingProtocolManager::UpdateUrl(bool is_extended_reporting) const { |
(...skipping 17 matching lines...) Expand all Loading... |
752 GURL SafeBrowsingProtocolManager::GetHashUrl(bool is_extended_reporting) const { | 755 GURL SafeBrowsingProtocolManager::GetHashUrl(bool is_extended_reporting) const { |
753 std::string url = SafeBrowsingProtocolManagerHelper::ComposeUrl( | 756 std::string url = SafeBrowsingProtocolManagerHelper::ComposeUrl( |
754 url_prefix_, "gethash", client_name_, version_, additional_query_, | 757 url_prefix_, "gethash", client_name_, version_, additional_query_, |
755 is_extended_reporting); | 758 is_extended_reporting); |
756 return GURL(url); | 759 return GURL(url); |
757 } | 760 } |
758 | 761 |
759 GURL SafeBrowsingProtocolManager::NextChunkUrl(const std::string& url) const { | 762 GURL SafeBrowsingProtocolManager::NextChunkUrl(const std::string& url) const { |
760 DCHECK(CalledOnValidThread()); | 763 DCHECK(CalledOnValidThread()); |
761 std::string next_url; | 764 std::string next_url; |
762 if (!base::StartsWith(url, "http://", | 765 if (!base::StartsWith(url, "http://", base::CompareCase::INSENSITIVE_ASCII) && |
763 base::CompareCase::INSENSITIVE_ASCII) && | |
764 !base::StartsWith(url, "https://", | 766 !base::StartsWith(url, "https://", |
765 base::CompareCase::INSENSITIVE_ASCII)) { | 767 base::CompareCase::INSENSITIVE_ASCII)) { |
766 // Use https if we updated via https, otherwise http (useful for testing). | 768 // Use https if we updated via https, otherwise http (useful for testing). |
767 if (base::StartsWith(url_prefix_, "https://", | 769 if (base::StartsWith(url_prefix_, "https://", |
768 base::CompareCase::INSENSITIVE_ASCII)) | 770 base::CompareCase::INSENSITIVE_ASCII)) |
769 next_url.append("https://"); | 771 next_url.append("https://"); |
770 else | 772 else |
771 next_url.append("http://"); | 773 next_url.append("http://"); |
772 next_url.append(url); | 774 next_url.append(url); |
773 } else { | 775 } else { |
774 next_url = url; | 776 next_url = url; |
775 } | 777 } |
776 if (!additional_query_.empty()) { | 778 if (!additional_query_.empty()) { |
777 if (next_url.find("?") != std::string::npos) { | 779 if (next_url.find("?") != std::string::npos) { |
778 next_url.append("&"); | 780 next_url.append("&"); |
779 } else { | 781 } else { |
780 next_url.append("?"); | 782 next_url.append("?"); |
781 } | 783 } |
782 next_url.append(additional_query_); | 784 next_url.append(additional_query_); |
783 } | 785 } |
784 return GURL(next_url); | 786 return GURL(next_url); |
785 } | 787 } |
786 | 788 |
787 SafeBrowsingProtocolManager::FullHashDetails::FullHashDetails() | 789 SafeBrowsingProtocolManager::FullHashDetails::FullHashDetails() |
788 : callback(), | 790 : callback(), is_download(false) {} |
789 is_download(false) { | |
790 } | |
791 | 791 |
792 SafeBrowsingProtocolManager::FullHashDetails::FullHashDetails( | 792 SafeBrowsingProtocolManager::FullHashDetails::FullHashDetails( |
793 FullHashCallback callback, bool is_download) | 793 FullHashCallback callback, |
794 : callback(callback), | 794 bool is_download) |
795 is_download(is_download) { | 795 : callback(callback), is_download(is_download) {} |
796 } | |
797 | 796 |
798 SafeBrowsingProtocolManager::FullHashDetails::~FullHashDetails() { | 797 SafeBrowsingProtocolManager::FullHashDetails::~FullHashDetails() {} |
799 } | |
800 | 798 |
801 SafeBrowsingProtocolManagerDelegate::~SafeBrowsingProtocolManagerDelegate() { | 799 SafeBrowsingProtocolManagerDelegate::~SafeBrowsingProtocolManagerDelegate() {} |
802 } | 800 |
| 801 } // namespace safe_browsing |
OLD | NEW |