Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(846)

Side by Side Diff: components/safe_browsing_db/v4_get_hash_protocol_manager.cc

Issue 1703413002: Move common PVer4 code into a V4ProtocolManagerUtil class. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Pass config as pointer, instead of reference Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 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/safe_browsing_db/v4_get_hash_protocol_manager.h" 5 #include "components/safe_browsing_db/v4_get_hash_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/logging.h"
11 #include "base/macros.h" 10 #include "base/macros.h"
12 #include "base/metrics/histogram_macros.h" 11 #include "base/metrics/histogram_macros.h"
13 #include "base/metrics/sparse_histogram.h"
14 #include "base/rand_util.h"
15 #include "base/stl_util.h"
16 #include "base/strings/string_util.h"
17 #include "base/strings/stringprintf.h"
18 #include "base/timer/timer.h" 12 #include "base/timer/timer.h"
19 #include "net/base/escape.h"
20 #include "net/base/load_flags.h" 13 #include "net/base/load_flags.h"
21 #include "net/base/net_errors.h"
22 #include "net/http/http_response_headers.h" 14 #include "net/http/http_response_headers.h"
23 #include "net/http/http_status_code.h" 15 #include "net/http/http_status_code.h"
24 #include "net/url_request/url_fetcher.h" 16 #include "net/url_request/url_fetcher.h"
25 #include "net/url_request/url_request_context_getter.h" 17 #include "net/url_request/url_request_context_getter.h"
26 #include "net/url_request/url_request_status.h"
27 18
28 using base::Time; 19 using base::Time;
29 using base::TimeDelta; 20 using base::TimeDelta;
30 21
31 namespace { 22 namespace {
32 23
33 // Enumerate parsing failures for histogramming purposes. DO NOT CHANGE 24 // Enumerate parsing failures for histogramming purposes. DO NOT CHANGE
34 // THE ORDERING OF THESE VALUES. 25 // THE ORDERING OF THESE VALUES.
35 enum ParseResultType { 26 enum ParseResultType {
36 // Error parsing the protocol buffer from a string. 27 // Error parsing the protocol buffer from a string.
(...skipping 11 matching lines...) Expand all
48 // A match in the response contained no metadata where metadata was 39 // A match in the response contained no metadata where metadata was
49 // expected. 40 // expected.
50 NO_METADATA_ERROR = 4, 41 NO_METADATA_ERROR = 4,
51 42
52 // A match in the response contained a ThreatType that was inconsistent 43 // A match in the response contained a ThreatType that was inconsistent
53 // with the other matches. 44 // with the other matches.
54 INCONSISTENT_THREAT_TYPE_ERROR = 5, 45 INCONSISTENT_THREAT_TYPE_ERROR = 5,
55 46
56 // Memory space for histograms is determined by the max. ALWAYS 47 // Memory space for histograms is determined by the max. ALWAYS
57 // ADD NEW VALUES BEFORE THIS ONE. 48 // ADD NEW VALUES BEFORE THIS ONE.
58 PARSE_GET_HASH_RESULT_MAX = 6 49 PARSE_RESULT_TYPE_MAX = 6
59 }; 50 };
60 51
61 // Record parsing errors of a GetHash result. 52 // Record parsing errors of a GetHash result.
62 void RecordParseGetHashResult(ParseResultType result_type) { 53 void RecordParseGetHashResult(ParseResultType result_type) {
63 UMA_HISTOGRAM_ENUMERATION("SafeBrowsing.ParseV4HashResult", result_type, 54 UMA_HISTOGRAM_ENUMERATION("SafeBrowsing.ParseV4HashResult", result_type,
64 PARSE_GET_HASH_RESULT_MAX); 55 PARSE_RESULT_TYPE_MAX);
65 } 56 }
66 57
67 } // namespace 58 } // namespace
68 59
69 namespace safe_browsing { 60 namespace safe_browsing {
70 61
71 const char kUmaV4HashResponseMetricName[] = 62 const char kUmaV4HashResponseMetricName[] =
72 "SafeBrowsing.GetV4HashHttpResponseOrErrorCode"; 63 "SafeBrowsing.GetV4HashHttpResponseOrErrorCode";
73 64
74 // The default V4GetHashProtocolManagerFactory. 65 // The default V4GetHashProtocolManagerFactory.
75 class V4GetHashProtocolManagerFactoryImpl 66 class V4GetHashProtocolManagerFactoryImpl
76 : public V4GetHashProtocolManagerFactory { 67 : public V4GetHashProtocolManagerFactory {
77 public: 68 public:
78 V4GetHashProtocolManagerFactoryImpl() {} 69 V4GetHashProtocolManagerFactoryImpl() {}
79 ~V4GetHashProtocolManagerFactoryImpl() override {} 70 ~V4GetHashProtocolManagerFactoryImpl() override {}
80 V4GetHashProtocolManager* CreateProtocolManager( 71 V4GetHashProtocolManager* CreateProtocolManager(
81 net::URLRequestContextGetter* request_context_getter, 72 net::URLRequestContextGetter* request_context_getter,
82 const V4GetHashProtocolConfig& config) override { 73 const V4ProtocolConfig& config) override {
83 return new V4GetHashProtocolManager(request_context_getter, config); 74 return new V4GetHashProtocolManager(request_context_getter, config);
84 } 75 }
85 76
86 private: 77 private:
87 DISALLOW_COPY_AND_ASSIGN(V4GetHashProtocolManagerFactoryImpl); 78 DISALLOW_COPY_AND_ASSIGN(V4GetHashProtocolManagerFactoryImpl);
88 }; 79 };
89 80
90 // V4GetHashProtocolManager implementation -------------------------------- 81 // V4GetHashProtocolManager implementation --------------------------------
91 82
92 // static 83 // static
93 V4GetHashProtocolManagerFactory* V4GetHashProtocolManager::factory_ = NULL; 84 V4GetHashProtocolManagerFactory* V4GetHashProtocolManager::factory_ = NULL;
94 85
95 // static 86 // static
96 V4GetHashProtocolManager* V4GetHashProtocolManager::Create( 87 V4GetHashProtocolManager* V4GetHashProtocolManager::Create(
97 net::URLRequestContextGetter* request_context_getter, 88 net::URLRequestContextGetter* request_context_getter,
98 const V4GetHashProtocolConfig& config) { 89 const V4ProtocolConfig& config) {
99 if (!factory_) 90 if (!factory_)
100 factory_ = new V4GetHashProtocolManagerFactoryImpl(); 91 factory_ = new V4GetHashProtocolManagerFactoryImpl();
101 return factory_->CreateProtocolManager(request_context_getter, config); 92 return factory_->CreateProtocolManager(request_context_getter, config);
102 } 93 }
103 94
104 // static
105 // Backoff interval is MIN(((2^(n-1))*15 minutes) * (RAND + 1), 24 hours) where
106 // n is the number of consecutive errors.
107 base::TimeDelta V4GetHashProtocolManager::GetNextBackOffInterval(
108 size_t* error_count,
109 size_t* multiplier) {
110 DCHECK(multiplier && error_count);
111 (*error_count)++;
112 if (*error_count > 1 && *error_count < 9) {
113 // With error count 9 and above we will hit the 24 hour max interval.
114 // Cap the multiplier here to prevent integer overflow errors.
115 *multiplier *= 2;
116 }
117 base::TimeDelta next =
118 base::TimeDelta::FromMinutes(*multiplier * (1 + base::RandDouble()) * 15);
119
120 base::TimeDelta day = base::TimeDelta::FromHours(24);
121
122 if (next < day)
123 return next;
124 else
125 return day;
126 }
127
128 void V4GetHashProtocolManager::ResetGetHashErrors() { 95 void V4GetHashProtocolManager::ResetGetHashErrors() {
129 gethash_error_count_ = 0; 96 gethash_error_count_ = 0;
130 gethash_back_off_mult_ = 1; 97 gethash_back_off_mult_ = 1;
131 } 98 }
132 99
133 V4GetHashProtocolManager::V4GetHashProtocolManager( 100 V4GetHashProtocolManager::V4GetHashProtocolManager(
134 net::URLRequestContextGetter* request_context_getter, 101 net::URLRequestContextGetter* request_context_getter,
135 const V4GetHashProtocolConfig& config) 102 const V4ProtocolConfig& config)
136 : gethash_error_count_(0), 103 : gethash_error_count_(0),
137 gethash_back_off_mult_(1), 104 gethash_back_off_mult_(1),
138 next_gethash_time_(Time::FromDoubleT(0)), 105 next_gethash_time_(Time::FromDoubleT(0)),
139 version_(config.version), 106 config_(config),
140 client_name_(config.client_name),
141 key_param_(config.key_param),
142 request_context_getter_(request_context_getter), 107 request_context_getter_(request_context_getter),
143 url_fetcher_id_(0) { 108 url_fetcher_id_(0) {
144 DCHECK(!version_.empty());
145 } 109 }
146 110
147 // static 111 // static
148 void V4GetHashProtocolManager::RecordGetHashResult(ResultType result_type) { 112 void V4GetHashProtocolManager::RecordGetHashResult(ResultType result_type) {
149 UMA_HISTOGRAM_ENUMERATION("SafeBrowsing.GetV4HashResult", result_type, 113 UMA_HISTOGRAM_ENUMERATION("SafeBrowsing.GetV4HashResult", result_type,
150 GET_HASH_RESULT_MAX); 114 GET_HASH_RESULT_MAX);
151 } 115 }
152 116
153 void V4GetHashProtocolManager::RecordHttpResponseOrErrorCode(
154 const char* metric_name,
155 const net::URLRequestStatus& status,
156 int response_code) {
157 UMA_HISTOGRAM_SPARSE_SLOWLY(
158 metric_name, status.is_success() ? response_code : status.error());
159 }
160
161 V4GetHashProtocolManager::~V4GetHashProtocolManager() { 117 V4GetHashProtocolManager::~V4GetHashProtocolManager() {
162 // Delete in-progress SafeBrowsing requests. 118 // Delete in-progress SafeBrowsing requests.
163 STLDeleteContainerPairFirstPointers(hash_requests_.begin(), 119 STLDeleteContainerPairFirstPointers(hash_requests_.begin(),
164 hash_requests_.end()); 120 hash_requests_.end());
165 hash_requests_.clear(); 121 hash_requests_.clear();
166 } 122 }
167 123
168 std::string V4GetHashProtocolManager::GetHashRequest( 124 std::string V4GetHashProtocolManager::GetHashRequest(
169 const std::vector<SBPrefix>& prefixes, 125 const std::vector<SBPrefix>& prefixes,
170 const std::vector<PlatformType>& platforms, 126 const std::vector<PlatformType>& platforms,
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after
331 287
332 HashRequests::iterator it = hash_requests_.find(source); 288 HashRequests::iterator it = hash_requests_.find(source);
333 DCHECK(it != hash_requests_.end()) << "Request not found"; 289 DCHECK(it != hash_requests_.end()) << "Request not found";
334 290
335 // FindFullHashes response. 291 // FindFullHashes response.
336 // Reset the scoped pointer so the fetcher gets destroyed properly. 292 // Reset the scoped pointer so the fetcher gets destroyed properly.
337 scoped_ptr<const net::URLFetcher> fetcher(it->first); 293 scoped_ptr<const net::URLFetcher> fetcher(it->first);
338 294
339 int response_code = source->GetResponseCode(); 295 int response_code = source->GetResponseCode();
340 net::URLRequestStatus status = source->GetStatus(); 296 net::URLRequestStatus status = source->GetStatus();
341 RecordHttpResponseOrErrorCode(kUmaV4HashResponseMetricName, status, 297 V4ProtocolManagerUtil::RecordHttpResponseOrErrorCode(
342 response_code); 298 kUmaV4HashResponseMetricName, status, response_code);
343 299
344 const FullHashCallback& callback = it->second; 300 const FullHashCallback& callback = it->second;
345 std::vector<SBFullHashResult> full_hashes; 301 std::vector<SBFullHashResult> full_hashes;
346 base::TimeDelta negative_cache_duration; 302 base::TimeDelta negative_cache_duration;
347 if (status.is_success() && response_code == net::HTTP_OK) { 303 if (status.is_success() && response_code == net::HTTP_OK) {
348 RecordGetHashResult(GET_HASH_STATUS_200); 304 RecordGetHashResult(GET_HASH_STATUS_200);
349 ResetGetHashErrors(); 305 ResetGetHashErrors();
350 std::string data; 306 std::string data;
351 source->GetResponseAsString(&data); 307 source->GetResponseAsString(&data);
352 if (!ParseHashResponse(data, &full_hashes, &negative_cache_duration)) { 308 if (!ParseHashResponse(data, &full_hashes, &negative_cache_duration)) {
(...skipping 17 matching lines...) Expand all
370 // Invoke the callback with full_hashes, even if there was a parse error or 326 // Invoke the callback with full_hashes, even if there was a parse error or
371 // an error response code (in which case full_hashes will be empty). The 327 // an error response code (in which case full_hashes will be empty). The
372 // caller can't be blocked indefinitely. 328 // caller can't be blocked indefinitely.
373 callback.Run(full_hashes, negative_cache_duration); 329 callback.Run(full_hashes, negative_cache_duration);
374 330
375 hash_requests_.erase(it); 331 hash_requests_.erase(it);
376 } 332 }
377 333
378 void V4GetHashProtocolManager::HandleGetHashError(const Time& now) { 334 void V4GetHashProtocolManager::HandleGetHashError(const Time& now) {
379 DCHECK(CalledOnValidThread()); 335 DCHECK(CalledOnValidThread());
380 base::TimeDelta next = 336 base::TimeDelta next = V4ProtocolManagerUtil::GetNextBackOffInterval(
381 GetNextBackOffInterval(&gethash_error_count_, &gethash_back_off_mult_); 337 &gethash_error_count_, &gethash_back_off_mult_);
382 next_gethash_time_ = now + next; 338 next_gethash_time_ = now + next;
383 } 339 }
384 340
385 // The API hash call uses the pver4 Safe Browsing server. 341 GURL V4GetHashProtocolManager::GetHashUrl(const std::string& req_base64) const {
386 GURL V4GetHashProtocolManager::GetHashUrl( 342 return V4ProtocolManagerUtil::GetRequestUrl(req_base64, "encodedFullHashes",
387 const std::string& request_base64) const { 343 config_);
388 std::string url =
389 ComposePver4Url(kSbV4UrlPrefix, "encodedFullHashes", request_base64,
390 client_name_, version_, key_param_);
391 return GURL(url);
392 } 344 }
393 345
394 // static
395 std::string V4GetHashProtocolManager::ComposePver4Url(
396 const std::string& prefix,
397 const std::string& method,
398 const std::string& request_base64,
399 const std::string& client_id,
400 const std::string& version,
401 const std::string& key_param) {
402 DCHECK(!prefix.empty() && !method.empty() && !client_id.empty() &&
403 !version.empty());
404 std::string url =
405 base::StringPrintf("%s/%s/%s?alt=proto&client_id=%s&client_version=%s",
406 prefix.c_str(), method.c_str(), request_base64.c_str(),
407 client_id.c_str(), version.c_str());
408 if (!key_param.empty()) {
409 base::StringAppendF(&url, "&key=%s",
410 net::EscapeQueryParamValue(key_param, true).c_str());
411 }
412 return url;
413 }
414 346
415 } // namespace safe_browsing 347 } // namespace safe_browsing
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698