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 <utility> | 7 #include <utility> |
8 | 8 |
9 #include "base/base64.h" | 9 #include "base/base64.h" |
10 #include "base/environment.h" | 10 #include "base/environment.h" |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
86 static const int kSbTimerStartIntervalSecMax = 300; | 86 static const int kSbTimerStartIntervalSecMax = 300; |
87 | 87 |
88 // The maximum time, in seconds, to wait for a response to an update request. | 88 // The maximum time, in seconds, to wait for a response to an update request. |
89 static const int kSbMaxUpdateWaitSec = 30; | 89 static const int kSbMaxUpdateWaitSec = 30; |
90 | 90 |
91 // Maximum back off multiplier. | 91 // Maximum back off multiplier. |
92 static const size_t kSbMaxBackOff = 8; | 92 static const size_t kSbMaxBackOff = 8; |
93 | 93 |
94 const char kGetHashUmaResponseMetricName[] = "SB2.GetHashResponseOrErrorCode"; | 94 const char kGetHashUmaResponseMetricName[] = "SB2.GetHashResponseOrErrorCode"; |
95 const char kGetChunkUmaResponseMetricName[] = "SB2.GetChunkResponseOrErrorCode"; | 95 const char kGetChunkUmaResponseMetricName[] = "SB2.GetChunkResponseOrErrorCode"; |
| 96 const char kUmaV4ResponseMetricName[] = |
| 97 "SafeBrowsing.GetV4HashHttpResponseOrErrorCode"; |
96 | 98 |
97 // The V4 URL prefix where browser fetches hashes from the V4 server. | 99 // The V4 URL prefix where browser fetches hashes from the V4 server. |
98 const char kSbV4UrlPrefix[] = "https://safebrowsing.googleapis.com/v4"; | 100 const char kSbV4UrlPrefix[] = "https://safebrowsing.googleapis.com/v4"; |
99 | 101 |
100 // The default SBProtocolManagerFactory. | 102 // The default SBProtocolManagerFactory. |
101 class SBProtocolManagerFactoryImpl : public SBProtocolManagerFactory { | 103 class SBProtocolManagerFactoryImpl : public SBProtocolManagerFactory { |
102 public: | 104 public: |
103 SBProtocolManagerFactoryImpl() {} | 105 SBProtocolManagerFactoryImpl() {} |
104 ~SBProtocolManagerFactoryImpl() override {} | 106 ~SBProtocolManagerFactoryImpl() override {} |
105 SafeBrowsingProtocolManager* CreateProtocolManager( | 107 SafeBrowsingProtocolManager* CreateProtocolManager( |
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
209 ResultType result_type) { | 211 ResultType result_type) { |
210 if (is_download) { | 212 if (is_download) { |
211 UMA_HISTOGRAM_ENUMERATION("SB2.GetHashResultDownload", result_type, | 213 UMA_HISTOGRAM_ENUMERATION("SB2.GetHashResultDownload", result_type, |
212 GET_HASH_RESULT_MAX); | 214 GET_HASH_RESULT_MAX); |
213 } else { | 215 } else { |
214 UMA_HISTOGRAM_ENUMERATION("SB2.GetHashResult", result_type, | 216 UMA_HISTOGRAM_ENUMERATION("SB2.GetHashResult", result_type, |
215 GET_HASH_RESULT_MAX); | 217 GET_HASH_RESULT_MAX); |
216 } | 218 } |
217 } | 219 } |
218 | 220 |
| 221 // static |
| 222 void SafeBrowsingProtocolManager::RecordGetV4HashResult( |
| 223 ResultType result_type) { |
| 224 UMA_HISTOGRAM_ENUMERATION("SafeBrowsing.GetV4HashResult", result_type, |
| 225 GET_HASH_RESULT_MAX); |
| 226 } |
| 227 |
219 void SafeBrowsingProtocolManager::RecordHttpResponseOrErrorCode( | 228 void SafeBrowsingProtocolManager::RecordHttpResponseOrErrorCode( |
220 const char* metric_name, | 229 const char* metric_name, |
221 const net::URLRequestStatus& status, | 230 const net::URLRequestStatus& status, |
222 int response_code) { | 231 int response_code) { |
223 UMA_HISTOGRAM_SPARSE_SLOWLY( | 232 UMA_HISTOGRAM_SPARSE_SLOWLY( |
224 metric_name, status.is_success() ? response_code : status.error()); | 233 metric_name, status.is_success() ? response_code : status.error()); |
225 } | 234 } |
226 | 235 |
227 bool SafeBrowsingProtocolManager::IsUpdateScheduled() const { | 236 bool SafeBrowsingProtocolManager::IsUpdateScheduled() const { |
228 return update_timer_.IsRunning(); | 237 return update_timer_.IsRunning(); |
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
366 const std::vector<SBPrefix>& prefixes, | 375 const std::vector<SBPrefix>& prefixes, |
367 const std::vector<PlatformType>& platforms, | 376 const std::vector<PlatformType>& platforms, |
368 ThreatType threat_type, | 377 ThreatType threat_type, |
369 FullHashCallback callback) { | 378 FullHashCallback callback) { |
370 DCHECK(CalledOnValidThread()); | 379 DCHECK(CalledOnValidThread()); |
371 // We need to wait the minimum waiting duration, and if we are in backoff, | 380 // We need to wait the minimum waiting duration, and if we are in backoff, |
372 // we need to check if we're past the next allowed time. If we are, we can | 381 // we need to check if we're past the next allowed time. If we are, we can |
373 // proceed with the request. If not, we are required to return empty results | 382 // proceed with the request. If not, we are required to return empty results |
374 // (i.e. treat the page as safe). | 383 // (i.e. treat the page as safe). |
375 if (Time::Now() <= next_gethash_v4_time_) { | 384 if (Time::Now() <= next_gethash_v4_time_) { |
376 // TODO(kcarattini): Add UMA recording. | 385 if (gethash_v4_error_count_) { |
| 386 RecordGetV4HashResult(GET_HASH_BACKOFF_ERROR); |
| 387 } else { |
| 388 RecordGetV4HashResult(GET_HASH_MIN_WAIT_DURATION_ERROR); |
| 389 } |
377 std::vector<SBFullHashResult> full_hashes; | 390 std::vector<SBFullHashResult> full_hashes; |
378 callback.Run(full_hashes, base::TimeDelta()); | 391 callback.Run(full_hashes, base::TimeDelta()); |
379 return; | 392 return; |
380 } | 393 } |
381 | 394 |
382 std::string req_base64 = GetV4HashRequest(prefixes, platforms, threat_type); | 395 std::string req_base64 = GetV4HashRequest(prefixes, platforms, threat_type); |
383 GURL gethash_url = GetV4HashUrl(req_base64); | 396 GURL gethash_url = GetV4HashUrl(req_base64); |
384 | 397 |
385 net::URLFetcher* fetcher = | 398 net::URLFetcher* fetcher = |
386 net::URLFetcher::Create(url_fetcher_id_++, gethash_url, | 399 net::URLFetcher::Create(url_fetcher_id_++, gethash_url, |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
470 } | 483 } |
471 | 484 |
472 // Invoke the callback with full_hashes, even if there was a parse error or | 485 // Invoke the callback with full_hashes, even if there was a parse error or |
473 // an error response code (in which case full_hashes will be empty). The | 486 // an error response code (in which case full_hashes will be empty). The |
474 // caller can't be blocked indefinitely. | 487 // caller can't be blocked indefinitely. |
475 details.callback.Run(full_hashes, cache_lifetime); | 488 details.callback.Run(full_hashes, cache_lifetime); |
476 | 489 |
477 hash_requests_.erase(it); | 490 hash_requests_.erase(it); |
478 } else if (v4_it != v4_hash_requests_.end()) { | 491 } else if (v4_it != v4_hash_requests_.end()) { |
479 // V4 FindFullHashes response. | 492 // V4 FindFullHashes response. |
| 493 // TODO(kcarattini): Consider pulling all the V4 handling out into a |
| 494 // separate V4ProtocolManager class. |
| 495 RecordHttpResponseOrErrorCode(kUmaV4ResponseMetricName, status, |
| 496 response_code); |
480 const FullHashDetails& details = v4_it->second; | 497 const FullHashDetails& details = v4_it->second; |
481 std::vector<SBFullHashResult> full_hashes; | 498 std::vector<SBFullHashResult> full_hashes; |
482 base::TimeDelta negative_cache_duration; | 499 base::TimeDelta negative_cache_duration; |
483 if (status.is_success() && response_code == net::HTTP_OK) { | 500 if (status.is_success() && response_code == net::HTTP_OK) { |
484 // TODO(kcarattini): Add UMA reporting. | 501 RecordGetV4HashResult(GET_HASH_STATUS_200); |
485 ResetGetHashV4Errors(); | 502 ResetGetHashV4Errors(); |
486 std::string data; | 503 std::string data; |
487 source->GetResponseAsString(&data); | 504 source->GetResponseAsString(&data); |
488 if (!ParseV4HashResponse(data, &full_hashes, &negative_cache_duration)) { | 505 if (!ParseV4HashResponse(data, &full_hashes, &negative_cache_duration)) { |
489 full_hashes.clear(); | 506 full_hashes.clear(); |
490 // TODO(kcarattini): Add UMA reporting. | 507 RecordGetV4HashResult(GET_HASH_PARSE_ERROR); |
491 } | 508 } |
492 } else { | 509 } else { |
493 HandleGetHashV4Error(Time::Now()); | 510 HandleGetHashV4Error(Time::Now()); |
494 // TODO(kcarattini): Add UMA reporting. | 511 |
495 DVLOG(1) << "SafeBrowsing GetEncodedFullHashes request for: " << | 512 DVLOG(1) << "SafeBrowsing GetEncodedFullHashes request for: " << |
496 source->GetURL() << " failed with error: " << status.error() << | 513 source->GetURL() << " failed with error: " << status.error() << |
497 " and response code: " << response_code; | 514 " and response code: " << response_code; |
| 515 |
| 516 if (status.status() == net::URLRequestStatus::FAILED) { |
| 517 RecordGetV4HashResult(GET_HASH_NETWORK_ERROR); |
| 518 } else { |
| 519 RecordGetV4HashResult(GET_HASH_HTTP_ERROR); |
| 520 } |
498 } | 521 } |
499 | 522 |
500 // Invoke the callback with full_hashes, even if there was a parse error or | 523 // Invoke the callback with full_hashes, even if there was a parse error or |
501 // an error response code (in which case full_hashes will be empty). The | 524 // an error response code (in which case full_hashes will be empty). The |
502 // caller can't be blocked indefinitely. | 525 // caller can't be blocked indefinitely. |
503 details.callback.Run(full_hashes, negative_cache_duration); | 526 details.callback.Run(full_hashes, negative_cache_duration); |
504 | 527 |
505 v4_hash_requests_.erase(v4_it); | 528 v4_hash_requests_.erase(v4_it); |
506 } else { | 529 } else { |
507 // Update or chunk response. | 530 // Update or chunk response. |
(...skipping 503 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1011 SafeBrowsingProtocolManager::FullHashDetails::FullHashDetails( | 1034 SafeBrowsingProtocolManager::FullHashDetails::FullHashDetails( |
1012 FullHashCallback callback, | 1035 FullHashCallback callback, |
1013 bool is_download) | 1036 bool is_download) |
1014 : callback(callback), is_download(is_download) {} | 1037 : callback(callback), is_download(is_download) {} |
1015 | 1038 |
1016 SafeBrowsingProtocolManager::FullHashDetails::~FullHashDetails() {} | 1039 SafeBrowsingProtocolManager::FullHashDetails::~FullHashDetails() {} |
1017 | 1040 |
1018 SafeBrowsingProtocolManagerDelegate::~SafeBrowsingProtocolManagerDelegate() {} | 1041 SafeBrowsingProtocolManagerDelegate::~SafeBrowsingProtocolManagerDelegate() {} |
1019 | 1042 |
1020 } // namespace safe_browsing | 1043 } // namespace safe_browsing |
OLD | NEW |