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/environment.h" | 9 #include "base/environment.h" |
10 #include "base/logging.h" | 10 #include "base/logging.h" |
11 #include "base/macros.h" | 11 #include "base/macros.h" |
12 #include "base/memory/ptr_util.h" | 12 #include "base/memory/ptr_util.h" |
13 #include "base/metrics/histogram_macros.h" | 13 #include "base/metrics/histogram_macros.h" |
14 #include "base/metrics/sparse_histogram.h" | 14 #include "base/metrics/sparse_histogram.h" |
15 #include "base/profiler/scoped_tracker.h" | 15 #include "base/profiler/scoped_tracker.h" |
16 #include "base/rand_util.h" | 16 #include "base/rand_util.h" |
17 #include "base/stl_util.h" | |
18 #include "base/strings/string_number_conversions.h" | 17 #include "base/strings/string_number_conversions.h" |
19 #include "base/strings/string_util.h" | 18 #include "base/strings/string_util.h" |
20 #include "base/strings/stringprintf.h" | 19 #include "base/strings/stringprintf.h" |
21 #include "base/timer/timer.h" | 20 #include "base/timer/timer.h" |
22 #include "chrome/browser/safe_browsing/protocol_parser.h" | 21 #include "chrome/browser/safe_browsing/protocol_parser.h" |
23 #include "chrome/common/env_vars.h" | 22 #include "chrome/common/env_vars.h" |
24 #include "components/safe_browsing_db/util.h" | 23 #include "components/safe_browsing_db/util.h" |
25 #include "components/variations/variations_associated_data.h" | 24 #include "components/variations/variations_associated_data.h" |
26 #include "content/public/browser/browser_thread.h" | 25 #include "content/public/browser/browser_thread.h" |
27 #include "google_apis/google_api_keys.h" | 26 #include "google_apis/google_api_keys.h" |
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
184 const net::URLRequestStatus& status, | 183 const net::URLRequestStatus& status, |
185 int response_code) { | 184 int response_code) { |
186 UMA_HISTOGRAM_SPARSE_SLOWLY( | 185 UMA_HISTOGRAM_SPARSE_SLOWLY( |
187 metric_name, status.is_success() ? response_code : status.error()); | 186 metric_name, status.is_success() ? response_code : status.error()); |
188 } | 187 } |
189 | 188 |
190 bool SafeBrowsingProtocolManager::IsUpdateScheduled() const { | 189 bool SafeBrowsingProtocolManager::IsUpdateScheduled() const { |
191 return update_timer_.IsRunning(); | 190 return update_timer_.IsRunning(); |
192 } | 191 } |
193 | 192 |
194 SafeBrowsingProtocolManager::~SafeBrowsingProtocolManager() { | 193 SafeBrowsingProtocolManager::~SafeBrowsingProtocolManager() {} |
195 // Delete in-progress SafeBrowsing requests. | |
196 base::STLDeleteContainerPairFirstPointers(hash_requests_.begin(), | |
197 hash_requests_.end()); | |
198 hash_requests_.clear(); | |
199 } | |
200 | 194 |
201 // We can only have one update or chunk request outstanding, but there may be | 195 // We can only have one update or chunk request outstanding, but there may be |
202 // multiple GetHash requests pending since we don't want to serialize them and | 196 // multiple GetHash requests pending since we don't want to serialize them and |
203 // slow down the user. | 197 // slow down the user. |
204 void SafeBrowsingProtocolManager::GetFullHash( | 198 void SafeBrowsingProtocolManager::GetFullHash( |
205 const std::vector<SBPrefix>& prefixes, | 199 const std::vector<SBPrefix>& prefixes, |
206 FullHashCallback callback, | 200 FullHashCallback callback, |
207 bool is_download, | 201 bool is_download, |
208 bool is_extended_reporting) { | 202 bool is_extended_reporting) { |
209 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); | 203 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); |
210 // If we are in GetHash backoff, we need to check if we're past the next | 204 // If we are in GetHash backoff, we need to check if we're past the next |
211 // allowed time. If we are, we can proceed with the request. If not, we are | 205 // allowed time. If we are, we can proceed with the request. If not, we are |
212 // required to return empty results (i.e. treat the page as safe). | 206 // required to return empty results (i.e. treat the page as safe). |
213 if (gethash_error_count_ && Time::Now() <= next_gethash_time_) { | 207 if (gethash_error_count_ && Time::Now() <= next_gethash_time_) { |
214 RecordGetHashResult(is_download, GET_HASH_BACKOFF_ERROR); | 208 RecordGetHashResult(is_download, GET_HASH_BACKOFF_ERROR); |
215 std::vector<SBFullHashResult> full_hashes; | 209 std::vector<SBFullHashResult> full_hashes; |
216 callback.Run(full_hashes, base::TimeDelta()); | 210 callback.Run(full_hashes, base::TimeDelta()); |
217 return; | 211 return; |
218 } | 212 } |
219 GURL gethash_url = GetHashUrl(is_extended_reporting); | 213 GURL gethash_url = GetHashUrl(is_extended_reporting); |
220 net::URLFetcher* fetcher = | 214 std::unique_ptr<net::URLFetcher> fetcher_ptr = net::URLFetcher::Create( |
221 net::URLFetcher::Create(url_fetcher_id_++, gethash_url, | 215 url_fetcher_id_++, gethash_url, net::URLFetcher::POST, this); |
222 net::URLFetcher::POST, this) | 216 net::URLFetcher* fetcher = fetcher_ptr.get(); |
223 .release(); | 217 hash_requests_[fetcher] = {std::move(fetcher_ptr), |
224 hash_requests_[fetcher] = FullHashDetails(callback, is_download); | 218 FullHashDetails(callback, is_download)}; |
225 | 219 |
226 const std::string get_hash = FormatGetHash(prefixes); | 220 const std::string get_hash = FormatGetHash(prefixes); |
227 | 221 |
228 fetcher->SetLoadFlags(net::LOAD_DISABLE_CACHE); | 222 fetcher->SetLoadFlags(net::LOAD_DISABLE_CACHE); |
229 fetcher->SetRequestContext(request_context_getter_.get()); | 223 fetcher->SetRequestContext(request_context_getter_.get()); |
230 fetcher->SetUploadData("text/plain", get_hash); | 224 fetcher->SetUploadData("text/plain", get_hash); |
231 fetcher->Start(); | 225 fetcher->Start(); |
232 } | 226 } |
233 | 227 |
234 void SafeBrowsingProtocolManager::GetNextUpdate() { | 228 void SafeBrowsingProtocolManager::GetNextUpdate() { |
(...skipping 10 matching lines...) Expand all Loading... |
245 // TODO(paulg): Clarify with the SafeBrowsing team whether a failed parse of a | 239 // TODO(paulg): Clarify with the SafeBrowsing team whether a failed parse of a |
246 // chunk should retry the download and parse of that chunk (and | 240 // chunk should retry the download and parse of that chunk (and |
247 // what back off / how many times to try), and if that effects the | 241 // what back off / how many times to try), and if that effects the |
248 // update back off. For now, a failed parse of the chunk means we | 242 // update back off. For now, a failed parse of the chunk means we |
249 // drop it. This isn't so bad because the next UPDATE_REQUEST we | 243 // drop it. This isn't so bad because the next UPDATE_REQUEST we |
250 // do will report all the chunks we have. If that chunk is still | 244 // do will report all the chunks we have. If that chunk is still |
251 // required, the SafeBrowsing servers will tell us to get it again. | 245 // required, the SafeBrowsing servers will tell us to get it again. |
252 void SafeBrowsingProtocolManager::OnURLFetchComplete( | 246 void SafeBrowsingProtocolManager::OnURLFetchComplete( |
253 const net::URLFetcher* source) { | 247 const net::URLFetcher* source) { |
254 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); | 248 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); |
255 std::unique_ptr<const net::URLFetcher> fetcher; | |
256 | 249 |
257 HashRequests::iterator it = hash_requests_.find(source); | 250 auto it = hash_requests_.find(source); |
258 int response_code = source->GetResponseCode(); | 251 int response_code = source->GetResponseCode(); |
259 net::URLRequestStatus status = source->GetStatus(); | 252 net::URLRequestStatus status = source->GetStatus(); |
260 | 253 |
261 if (it != hash_requests_.end()) { | 254 if (it != hash_requests_.end()) { |
262 // GetHash response. | 255 // GetHash response. |
263 // Reset the scoped pointer so the fetcher gets destroyed properly. | |
264 fetcher.reset(it->first); | |
265 RecordHttpResponseOrErrorCode(kGetHashUmaResponseMetricName, status, | 256 RecordHttpResponseOrErrorCode(kGetHashUmaResponseMetricName, status, |
266 response_code); | 257 response_code); |
267 const FullHashDetails& details = it->second; | 258 const FullHashDetails& details = it->second.second; |
268 std::vector<SBFullHashResult> full_hashes; | 259 std::vector<SBFullHashResult> full_hashes; |
269 base::TimeDelta cache_lifetime; | 260 base::TimeDelta cache_lifetime; |
270 if (status.is_success() && (response_code == net::HTTP_OK || | 261 if (status.is_success() && (response_code == net::HTTP_OK || |
271 response_code == net::HTTP_NO_CONTENT)) { | 262 response_code == net::HTTP_NO_CONTENT)) { |
272 // For tracking our GetHash false positive (net::HTTP_NO_CONTENT) rate, | 263 // For tracking our GetHash false positive (net::HTTP_NO_CONTENT) rate, |
273 // compared to real (net::HTTP_OK) responses. | 264 // compared to real (net::HTTP_OK) responses. |
274 if (response_code == net::HTTP_OK) | 265 if (response_code == net::HTTP_OK) |
275 RecordGetHashResult(details.is_download, GET_HASH_STATUS_200); | 266 RecordGetHashResult(details.is_download, GET_HASH_STATUS_200); |
276 else | 267 else |
277 RecordGetHashResult(details.is_download, GET_HASH_STATUS_204); | 268 RecordGetHashResult(details.is_download, GET_HASH_STATUS_204); |
(...skipping 25 matching lines...) Expand all Loading... |
303 // Invoke the callback with full_hashes, even if there was a parse error or | 294 // Invoke the callback with full_hashes, even if there was a parse error or |
304 // an error response code (in which case full_hashes will be empty). The | 295 // an error response code (in which case full_hashes will be empty). The |
305 // caller can't be blocked indefinitely. | 296 // caller can't be blocked indefinitely. |
306 details.callback.Run(full_hashes, cache_lifetime); | 297 details.callback.Run(full_hashes, cache_lifetime); |
307 | 298 |
308 hash_requests_.erase(it); | 299 hash_requests_.erase(it); |
309 } else { | 300 } else { |
310 // Update or chunk response. | 301 // Update or chunk response. |
311 RecordHttpResponseOrErrorCode(kGetChunkUmaResponseMetricName, status, | 302 RecordHttpResponseOrErrorCode(kGetChunkUmaResponseMetricName, status, |
312 response_code); | 303 response_code); |
313 fetcher.reset(request_.release()); | 304 std::unique_ptr<net::URLFetcher> fetcher = std::move(request_); |
314 | 305 |
315 if (request_type_ == UPDATE_REQUEST || | 306 if (request_type_ == UPDATE_REQUEST || |
316 request_type_ == BACKUP_UPDATE_REQUEST) { | 307 request_type_ == BACKUP_UPDATE_REQUEST) { |
317 if (!fetcher.get()) { | 308 if (!fetcher.get()) { |
318 // We've timed out waiting for an update response, so we've cancelled | 309 // We've timed out waiting for an update response, so we've cancelled |
319 // the update request and scheduled a new one. Ignore this response. | 310 // the update request and scheduled a new one. Ignore this response. |
320 return; | 311 return; |
321 } | 312 } |
322 | 313 |
323 // Cancel the update response timeout now that we have the response. | 314 // Cancel the update response timeout now that we have the response. |
(...skipping 473 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
797 : callback(callback), is_download(is_download) {} | 788 : callback(callback), is_download(is_download) {} |
798 | 789 |
799 SafeBrowsingProtocolManager::FullHashDetails::FullHashDetails( | 790 SafeBrowsingProtocolManager::FullHashDetails::FullHashDetails( |
800 const FullHashDetails& other) = default; | 791 const FullHashDetails& other) = default; |
801 | 792 |
802 SafeBrowsingProtocolManager::FullHashDetails::~FullHashDetails() {} | 793 SafeBrowsingProtocolManager::FullHashDetails::~FullHashDetails() {} |
803 | 794 |
804 SafeBrowsingProtocolManagerDelegate::~SafeBrowsingProtocolManagerDelegate() {} | 795 SafeBrowsingProtocolManagerDelegate::~SafeBrowsingProtocolManagerDelegate() {} |
805 | 796 |
806 } // namespace safe_browsing | 797 } // namespace safe_browsing |
OLD | NEW |