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/renderer_host/safe_browsing_resource_throttle.h" | 5 #include "chrome/browser/renderer_host/safe_browsing_resource_throttle.h" |
6 | 6 |
7 #include "base/logging.h" | 7 #include "base/logging.h" |
8 #include "base/metrics/histogram_macros.h" | 8 #include "base/metrics/histogram_macros.h" |
9 #include "base/values.h" | 9 #include "base/values.h" |
10 #include "chrome/browser/browser_process.h" | 10 #include "chrome/browser/browser_process.h" |
11 #include "chrome/browser/prerender/prerender_contents.h" | 11 #include "chrome/browser/prerender/prerender_contents.h" |
12 #include "chrome/browser/safe_browsing/safe_browsing_service.h" | 12 #include "chrome/browser/safe_browsing/safe_browsing_service.h" |
13 #include "content/public/browser/browser_thread.h" | 13 #include "content/public/browser/browser_thread.h" |
14 #include "content/public/browser/render_view_host.h" | 14 #include "content/public/browser/render_view_host.h" |
15 #include "content/public/browser/resource_controller.h" | 15 #include "content/public/browser/resource_controller.h" |
16 #include "content/public/browser/resource_request_info.h" | 16 #include "content/public/browser/resource_request_info.h" |
17 #include "content/public/browser/web_contents.h" | 17 #include "content/public/browser/web_contents.h" |
18 #include "net/base/load_flags.h" | 18 #include "net/base/load_flags.h" |
19 #include "net/log/net_log.h" | 19 #include "net/log/net_log.h" |
20 #include "net/url_request/redirect_info.h" | 20 #include "net/url_request/redirect_info.h" |
21 #include "net/url_request/url_request.h" | 21 #include "net/url_request/url_request.h" |
22 | 22 |
23 using net::NetLog; | 23 using net::NetLog; |
| 24 using safe_browsing::SafeBrowsingUIManager; |
24 | 25 |
25 namespace { | 26 namespace { |
26 | 27 |
27 // Maximum time in milliseconds to wait for the safe browsing service to | 28 // Maximum time in milliseconds to wait for the safe browsing service to |
28 // verify a URL. After this amount of time the outstanding check will be | 29 // verify a URL. After this amount of time the outstanding check will be |
29 // aborted, and the URL will be treated as if it were safe. | 30 // aborted, and the URL will be treated as if it were safe. |
30 const int kCheckUrlTimeoutMs = 5000; | 31 const int kCheckUrlTimeoutMs = 5000; |
31 | 32 |
32 void RecordHistogramResourceTypeSafe(content::ResourceType resource_type) { | 33 void RecordHistogramResourceTypeSafe(content::ResourceType resource_type) { |
33 UMA_HISTOGRAM_ENUMERATION("SB2.ResourceTypes.Safe", resource_type, | 34 UMA_HISTOGRAM_ENUMERATION("SB2.ResourceTypes.Safe", resource_type, |
(...skipping 30 matching lines...) Expand all Loading... |
64 | 65 |
65 } // namespace | 66 } // namespace |
66 | 67 |
67 // TODO(eroman): Downgrade these CHECK()s to DCHECKs once there is more | 68 // TODO(eroman): Downgrade these CHECK()s to DCHECKs once there is more |
68 // unit test coverage. | 69 // unit test coverage. |
69 | 70 |
70 // static | 71 // static |
71 SafeBrowsingResourceThrottle* SafeBrowsingResourceThrottle::MaybeCreate( | 72 SafeBrowsingResourceThrottle* SafeBrowsingResourceThrottle::MaybeCreate( |
72 net::URLRequest* request, | 73 net::URLRequest* request, |
73 content::ResourceType resource_type, | 74 content::ResourceType resource_type, |
74 SafeBrowsingService* sb_service) { | 75 safe_browsing::SafeBrowsingService* sb_service) { |
75 if (sb_service->database_manager()->IsSupported()) { | 76 if (sb_service->database_manager()->IsSupported()) { |
76 return new SafeBrowsingResourceThrottle(request, resource_type, sb_service); | 77 return new SafeBrowsingResourceThrottle(request, resource_type, sb_service); |
77 } | 78 } |
78 return nullptr; | 79 return nullptr; |
79 } | 80 } |
80 | 81 |
81 SafeBrowsingResourceThrottle::SafeBrowsingResourceThrottle( | 82 SafeBrowsingResourceThrottle::SafeBrowsingResourceThrottle( |
82 const net::URLRequest* request, | 83 const net::URLRequest* request, |
83 content::ResourceType resource_type, | 84 content::ResourceType resource_type, |
84 SafeBrowsingService* sb_service) | 85 safe_browsing::SafeBrowsingService* sb_service) |
85 : state_(STATE_NONE), | 86 : state_(STATE_NONE), |
86 defer_state_(DEFERRED_NONE), | 87 defer_state_(DEFERRED_NONE), |
87 threat_type_(SB_THREAT_TYPE_SAFE), | 88 threat_type_(safe_browsing::SB_THREAT_TYPE_SAFE), |
88 database_manager_(sb_service->database_manager()), | 89 database_manager_(sb_service->database_manager()), |
89 ui_manager_(sb_service->ui_manager()), | 90 ui_manager_(sb_service->ui_manager()), |
90 request_(request), | 91 request_(request), |
91 resource_type_(resource_type), | 92 resource_type_(resource_type), |
92 bound_net_log_(net::BoundNetLog::Make(request->net_log().net_log(), | 93 bound_net_log_(net::BoundNetLog::Make(request->net_log().net_log(), |
93 NetLog::SOURCE_SAFE_BROWSING)) {} | 94 NetLog::SOURCE_SAFE_BROWSING)) {} |
94 | 95 |
95 SafeBrowsingResourceThrottle::~SafeBrowsingResourceThrottle() { | 96 SafeBrowsingResourceThrottle::~SafeBrowsingResourceThrottle() { |
96 if (defer_state_ != DEFERRED_NONE) { | 97 if (defer_state_ != DEFERRED_NONE) { |
97 EndNetLogEvent(NetLog::TYPE_SAFE_BROWSING_DEFERRED, nullptr, nullptr); | 98 EndNetLogEvent(NetLog::TYPE_SAFE_BROWSING_DEFERRED, nullptr, nullptr); |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
194 } | 195 } |
195 | 196 |
196 const char* SafeBrowsingResourceThrottle::GetNameForLogging() const { | 197 const char* SafeBrowsingResourceThrottle::GetNameForLogging() const { |
197 return "SafeBrowsingResourceThrottle"; | 198 return "SafeBrowsingResourceThrottle"; |
198 } | 199 } |
199 | 200 |
200 // SafeBrowsingService::Client implementation, called on the IO thread once | 201 // SafeBrowsingService::Client implementation, called on the IO thread once |
201 // the URL has been classified. | 202 // the URL has been classified. |
202 void SafeBrowsingResourceThrottle::OnCheckBrowseUrlResult( | 203 void SafeBrowsingResourceThrottle::OnCheckBrowseUrlResult( |
203 const GURL& url, | 204 const GURL& url, |
204 SBThreatType threat_type, | 205 safe_browsing::SBThreatType threat_type, |
205 const std::string& metadata) { | 206 const std::string& metadata) { |
206 CHECK_EQ(state_, STATE_CHECKING_URL); | 207 CHECK_EQ(state_, STATE_CHECKING_URL); |
207 CHECK_EQ(url, url_being_checked_); | 208 CHECK_EQ(url, url_being_checked_); |
208 | 209 |
209 timer_.Stop(); // Cancel the timeout timer. | 210 timer_.Stop(); // Cancel the timeout timer. |
210 threat_type_ = threat_type; | 211 threat_type_ = threat_type; |
211 state_ = STATE_NONE; | 212 state_ = STATE_NONE; |
212 | 213 |
213 if (defer_state_ != DEFERRED_NONE) { | 214 if (defer_state_ != DEFERRED_NONE) { |
214 EndNetLogEvent(NetLog::TYPE_SAFE_BROWSING_DEFERRED, nullptr, nullptr); | 215 EndNetLogEvent(NetLog::TYPE_SAFE_BROWSING_DEFERRED, nullptr, nullptr); |
215 } | 216 } |
216 EndNetLogEvent(NetLog::TYPE_SAFE_BROWSING_CHECKING_URL, "result", | 217 EndNetLogEvent( |
217 threat_type_ == SB_THREAT_TYPE_SAFE ? "safe" : "unsafe"); | 218 NetLog::TYPE_SAFE_BROWSING_CHECKING_URL, "result", |
| 219 threat_type_ == safe_browsing::SB_THREAT_TYPE_SAFE ? "safe" : "unsafe"); |
218 | 220 |
219 if (threat_type == SB_THREAT_TYPE_SAFE) { | 221 if (threat_type == safe_browsing::SB_THREAT_TYPE_SAFE) { |
220 RecordHistogramResourceTypeSafe(resource_type_); | 222 RecordHistogramResourceTypeSafe(resource_type_); |
221 if (defer_state_ != DEFERRED_NONE) { | 223 if (defer_state_ != DEFERRED_NONE) { |
222 // Log how much time the safe browsing check cost us. | 224 // Log how much time the safe browsing check cost us. |
223 ui_manager_->LogPauseDelay(base::TimeTicks::Now() - defer_start_time_); | 225 ui_manager_->LogPauseDelay(base::TimeTicks::Now() - defer_start_time_); |
224 ResumeRequest(); | 226 ResumeRequest(); |
225 } else { | 227 } else { |
226 ui_manager_->LogPauseDelay(base::TimeDelta()); | 228 ui_manager_->LogPauseDelay(base::TimeDelta()); |
227 } | 229 } |
228 return; | 230 return; |
229 } | 231 } |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
297 } | 299 } |
298 | 300 |
299 // SafeBrowsingService::UrlCheckCallback implementation, called on the IO | 301 // SafeBrowsingService::UrlCheckCallback implementation, called on the IO |
300 // thread when the user has decided to proceed with the current request, or | 302 // thread when the user has decided to proceed with the current request, or |
301 // go back. | 303 // go back. |
302 void SafeBrowsingResourceThrottle::OnBlockingPageComplete(bool proceed) { | 304 void SafeBrowsingResourceThrottle::OnBlockingPageComplete(bool proceed) { |
303 CHECK_EQ(state_, STATE_DISPLAYING_BLOCKING_PAGE); | 305 CHECK_EQ(state_, STATE_DISPLAYING_BLOCKING_PAGE); |
304 state_ = STATE_NONE; | 306 state_ = STATE_NONE; |
305 | 307 |
306 if (proceed) { | 308 if (proceed) { |
307 threat_type_ = SB_THREAT_TYPE_SAFE; | 309 threat_type_ = safe_browsing::SB_THREAT_TYPE_SAFE; |
308 if (defer_state_ != DEFERRED_NONE) { | 310 if (defer_state_ != DEFERRED_NONE) { |
309 ResumeRequest(); | 311 ResumeRequest(); |
310 } | 312 } |
311 } else { | 313 } else { |
312 controller()->Cancel(); | 314 controller()->Cancel(); |
313 } | 315 } |
314 } | 316 } |
315 | 317 |
316 bool SafeBrowsingResourceThrottle::CheckUrl(const GURL& url) { | 318 bool SafeBrowsingResourceThrottle::CheckUrl(const GURL& url) { |
317 CHECK_EQ(state_, STATE_NONE); | 319 CHECK_EQ(state_, STATE_NONE); |
318 // To reduce aggregate latency on mobile, check only the most dangerous | 320 // To reduce aggregate latency on mobile, check only the most dangerous |
319 // resource types. | 321 // resource types. |
320 if (!database_manager_->CanCheckResourceType(resource_type_)) { | 322 if (!database_manager_->CanCheckResourceType(resource_type_)) { |
321 UMA_HISTOGRAM_ENUMERATION("SB2.ResourceTypes.Skipped", resource_type_, | 323 UMA_HISTOGRAM_ENUMERATION("SB2.ResourceTypes.Skipped", resource_type_, |
322 content::RESOURCE_TYPE_LAST_TYPE); | 324 content::RESOURCE_TYPE_LAST_TYPE); |
323 return true; | 325 return true; |
324 } | 326 } |
325 | 327 |
326 bool succeeded_synchronously = database_manager_->CheckBrowseUrl(url, this); | 328 bool succeeded_synchronously = database_manager_->CheckBrowseUrl(url, this); |
327 UMA_HISTOGRAM_ENUMERATION("SB2.ResourceTypes.Checked", resource_type_, | 329 UMA_HISTOGRAM_ENUMERATION("SB2.ResourceTypes.Checked", resource_type_, |
328 content::RESOURCE_TYPE_LAST_TYPE); | 330 content::RESOURCE_TYPE_LAST_TYPE); |
329 | 331 |
330 if (succeeded_synchronously) { | 332 if (succeeded_synchronously) { |
331 RecordHistogramResourceTypeSafe(resource_type_); | 333 RecordHistogramResourceTypeSafe(resource_type_); |
332 threat_type_ = SB_THREAT_TYPE_SAFE; | 334 threat_type_ = safe_browsing::SB_THREAT_TYPE_SAFE; |
333 ui_manager_->LogPauseDelay(base::TimeDelta()); // No delay. | 335 ui_manager_->LogPauseDelay(base::TimeDelta()); // No delay. |
334 return true; | 336 return true; |
335 } | 337 } |
336 | 338 |
337 state_ = STATE_CHECKING_URL; | 339 state_ = STATE_CHECKING_URL; |
338 url_being_checked_ = url; | 340 url_being_checked_ = url; |
339 BeginNetLogEvent(NetLog::TYPE_SAFE_BROWSING_CHECKING_URL, url, nullptr, | 341 BeginNetLogEvent(NetLog::TYPE_SAFE_BROWSING_CHECKING_URL, url, nullptr, |
340 nullptr); | 342 nullptr); |
341 | 343 |
342 // Start a timer to abort the check if it takes too long. | 344 // Start a timer to abort the check if it takes too long. |
343 // TODO(nparker): Set this only when we defer, based on remaining time, | 345 // TODO(nparker): Set this only when we defer, based on remaining time, |
344 // so we don't cancel earlier than necessary. | 346 // so we don't cancel earlier than necessary. |
345 timer_.Start(FROM_HERE, | 347 timer_.Start(FROM_HERE, |
346 base::TimeDelta::FromMilliseconds(kCheckUrlTimeoutMs), | 348 base::TimeDelta::FromMilliseconds(kCheckUrlTimeoutMs), |
347 this, &SafeBrowsingResourceThrottle::OnCheckUrlTimeout); | 349 this, &SafeBrowsingResourceThrottle::OnCheckUrlTimeout); |
348 | 350 |
349 return false; | 351 return false; |
350 } | 352 } |
351 | 353 |
352 void SafeBrowsingResourceThrottle::OnCheckUrlTimeout() { | 354 void SafeBrowsingResourceThrottle::OnCheckUrlTimeout() { |
353 CHECK_EQ(state_, STATE_CHECKING_URL); | 355 CHECK_EQ(state_, STATE_CHECKING_URL); |
354 | 356 |
355 database_manager_->CancelCheck(this); | 357 database_manager_->CancelCheck(this); |
356 OnCheckBrowseUrlResult( | 358 OnCheckBrowseUrlResult( |
357 url_being_checked_, SB_THREAT_TYPE_SAFE, std::string()); | 359 url_being_checked_, safe_browsing::SB_THREAT_TYPE_SAFE, std::string()); |
358 } | 360 } |
359 | 361 |
360 void SafeBrowsingResourceThrottle::ResumeRequest() { | 362 void SafeBrowsingResourceThrottle::ResumeRequest() { |
361 CHECK_EQ(state_, STATE_NONE); | 363 CHECK_EQ(state_, STATE_NONE); |
362 CHECK_NE(defer_state_, DEFERRED_NONE); | 364 CHECK_NE(defer_state_, DEFERRED_NONE); |
363 | 365 |
364 bool resume = true; | 366 bool resume = true; |
365 if (defer_state_ == DEFERRED_UNCHECKED_REDIRECT) { | 367 if (defer_state_ == DEFERRED_UNCHECKED_REDIRECT) { |
366 // Save the redirect urls for possible malware detail reporting later. | 368 // Save the redirect urls for possible malware detail reporting later. |
367 redirect_urls_.push_back(unchecked_redirect_url_); | 369 redirect_urls_.push_back(unchecked_redirect_url_); |
368 if (!CheckUrl(unchecked_redirect_url_)) { | 370 if (!CheckUrl(unchecked_redirect_url_)) { |
369 // We're now waiting for the unchecked_redirect_url_. | 371 // We're now waiting for the unchecked_redirect_url_. |
370 defer_state_ = DEFERRED_REDIRECT; | 372 defer_state_ = DEFERRED_REDIRECT; |
371 resume = false; | 373 resume = false; |
372 BeginNetLogEvent(NetLog::TYPE_SAFE_BROWSING_DEFERRED, | 374 BeginNetLogEvent(NetLog::TYPE_SAFE_BROWSING_DEFERRED, |
373 unchecked_redirect_url_, "defer_reason", | 375 unchecked_redirect_url_, "defer_reason", |
374 "resumed_redirect"); | 376 "resumed_redirect"); |
375 } | 377 } |
376 } | 378 } |
377 | 379 |
378 if (resume) { | 380 if (resume) { |
379 defer_state_ = DEFERRED_NONE; | 381 defer_state_ = DEFERRED_NONE; |
380 controller()->Resume(); | 382 controller()->Resume(); |
381 } | 383 } |
382 } | 384 } |
OLD | NEW |