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 <utility> | 7 #include <utility> |
8 | 8 |
9 #include "base/logging.h" | 9 #include "base/logging.h" |
10 #include "base/metrics/histogram_macros.h" | 10 #include "base/metrics/histogram_macros.h" |
11 #include "base/trace_event/trace_event.h" | 11 #include "base/trace_event/trace_event.h" |
12 #include "base/values.h" | 12 #include "base/values.h" |
13 #include "chrome/browser/browser_process.h" | 13 #include "chrome/browser/browser_process.h" |
14 #include "chrome/browser/prerender/prerender_contents.h" | 14 #include "chrome/browser/prerender/prerender_contents.h" |
15 #include "chrome/browser/safe_browsing/safe_browsing_service.h" | 15 #include "chrome/browser/safe_browsing/safe_browsing_service.h" |
16 #include "components/safe_browsing_db/util.h" | 16 #include "components/safe_browsing_db/util.h" |
17 #include "components/subresource_filter/content/browser/content_subresource_filt er_driver_factory.h" | 17 #include "components/subresource_filter/content/browser/content_subresource_filt er_driver_factory.h" |
18 #include "content/public/browser/browser_thread.h" | 18 #include "content/public/browser/browser_thread.h" |
19 #include "content/public/browser/render_frame_host.h" | 19 #include "content/public/browser/render_frame_host.h" |
20 #include "content/public/browser/resource_controller.h" | 20 #include "content/public/browser/resource_controller.h" |
21 #include "content/public/browser/resource_request_info.h" | 21 #include "content/public/browser/resource_request_info.h" |
22 #include "content/public/browser/web_contents.h" | 22 #include "content/public/browser/web_contents.h" |
23 #include "net/base/load_flags.h" | 23 #include "net/base/load_flags.h" |
24 #include "net/log/net_log.h" | 24 #include "net/log/net_log.h" |
25 #include "net/log/net_log_source_type.h" | |
25 #include "net/url_request/redirect_info.h" | 26 #include "net/url_request/redirect_info.h" |
26 #include "net/url_request/url_request.h" | 27 #include "net/url_request/url_request.h" |
27 | 28 |
28 using net::NetLog; | 29 using net::NetLogEventType; |
30 using net::NetLogSourceType; | |
29 using safe_browsing::SafeBrowsingUIManager; | 31 using safe_browsing::SafeBrowsingUIManager; |
30 | 32 |
31 namespace { | 33 namespace { |
32 | 34 |
33 // Maximum time in milliseconds to wait for the safe browsing service to | 35 // Maximum time in milliseconds to wait for the safe browsing service to |
34 // verify a URL. After this amount of time the outstanding check will be | 36 // verify a URL. After this amount of time the outstanding check will be |
35 // aborted, and the URL will be treated as if it were safe. | 37 // aborted, and the URL will be treated as if it were safe. |
36 const int kCheckUrlTimeoutMs = 5000; | 38 const int kCheckUrlTimeoutMs = 5000; |
37 | 39 |
38 void RecordHistogramResourceTypeSafe(content::ResourceType resource_type) { | 40 void RecordHistogramResourceTypeSafe(content::ResourceType resource_type) { |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
90 content::ResourceType resource_type, | 92 content::ResourceType resource_type, |
91 safe_browsing::SafeBrowsingService* sb_service) | 93 safe_browsing::SafeBrowsingService* sb_service) |
92 : state_(STATE_NONE), | 94 : state_(STATE_NONE), |
93 defer_state_(DEFERRED_NONE), | 95 defer_state_(DEFERRED_NONE), |
94 threat_type_(safe_browsing::SB_THREAT_TYPE_SAFE), | 96 threat_type_(safe_browsing::SB_THREAT_TYPE_SAFE), |
95 database_manager_(sb_service->database_manager()), | 97 database_manager_(sb_service->database_manager()), |
96 ui_manager_(sb_service->ui_manager()), | 98 ui_manager_(sb_service->ui_manager()), |
97 request_(request), | 99 request_(request), |
98 resource_type_(resource_type), | 100 resource_type_(resource_type), |
99 bound_net_log_(net::BoundNetLog::Make(request->net_log().net_log(), | 101 bound_net_log_(net::BoundNetLog::Make(request->net_log().net_log(), |
100 NetLog::SOURCE_SAFE_BROWSING)) {} | 102 NetLogSourceType::SAFE_BROWSING)) {} |
101 | 103 |
102 SafeBrowsingResourceThrottle::~SafeBrowsingResourceThrottle() { | 104 SafeBrowsingResourceThrottle::~SafeBrowsingResourceThrottle() { |
103 if (defer_state_ != DEFERRED_NONE) { | 105 if (defer_state_ != DEFERRED_NONE) { |
104 EndNetLogEvent(NetLog::TYPE_SAFE_BROWSING_DEFERRED, nullptr, nullptr); | 106 EndNetLogEvent(NetLogEventType::SAFE_BROWSING_DEFERRED, nullptr, nullptr); |
105 } | 107 } |
106 | 108 |
107 if (state_ == STATE_CHECKING_URL) { | 109 if (state_ == STATE_CHECKING_URL) { |
108 database_manager_->CancelCheck(this); | 110 database_manager_->CancelCheck(this); |
109 EndNetLogEvent(NetLog::TYPE_SAFE_BROWSING_CHECKING_URL, "result", | 111 EndNetLogEvent(NetLogEventType::SAFE_BROWSING_CHECKING_URL, "result", |
110 "request_canceled"); | 112 "request_canceled"); |
111 } | 113 } |
112 } | 114 } |
113 | 115 |
114 // Note on net_log calls: TYPE_SAFE_BROWSING_DEFERRED events must be wholly | 116 // Note on net_log calls: TYPE_SAFE_BROWSING_DEFERRED events must be wholly |
eroman
2016/09/06 19:32:20
Please update this comment to reference the new ev
mikecirone
2016/09/07 21:35:41
Done.
| |
115 // nested within TYPE_SAFE_BROWSING_CHECKING_URL events. Synchronous checks | 117 // nested within TYPE_SAFE_BROWSING_CHECKING_URL events. Synchronous checks |
eroman
2016/09/06 19:32:20
Same here.
mikecirone
2016/09/07 21:35:41
Done.
| |
116 // are not logged at all. | 118 // are not logged at all. |
117 void SafeBrowsingResourceThrottle::BeginNetLogEvent(NetLog::EventType type, | 119 void SafeBrowsingResourceThrottle::BeginNetLogEvent(NetLogEventType type, |
118 const GURL& url, | 120 const GURL& url, |
119 const char* name, | 121 const char* name, |
120 const char* value) { | 122 const char* value) { |
121 bound_net_log_.BeginEvent( | 123 bound_net_log_.BeginEvent( |
122 type, base::Bind(&NetLogUrlCallback, request_, url, name, value)); | 124 type, base::Bind(&NetLogUrlCallback, request_, url, name, value)); |
123 request_->net_log().AddEvent( | 125 request_->net_log().AddEvent( |
124 type, bound_net_log_.source().ToEventParametersCallback()); | 126 type, bound_net_log_.source().ToEventParametersCallback()); |
125 } | 127 } |
126 | 128 |
127 void SafeBrowsingResourceThrottle::EndNetLogEvent(NetLog::EventType type, | 129 void SafeBrowsingResourceThrottle::EndNetLogEvent(NetLogEventType type, |
128 const char* name, | 130 const char* name, |
129 const char* value) { | 131 const char* value) { |
130 bound_net_log_.EndEvent( | 132 bound_net_log_.EndEvent( |
131 type, base::Bind(&NetLogStringCallback, name, value)); | 133 type, base::Bind(&NetLogStringCallback, name, value)); |
132 request_->net_log().AddEvent( | 134 request_->net_log().AddEvent( |
133 type, bound_net_log_.source().ToEventParametersCallback()); | 135 type, bound_net_log_.source().ToEventParametersCallback()); |
134 } | 136 } |
135 | 137 |
136 void SafeBrowsingResourceThrottle::WillStartRequest(bool* defer) { | 138 void SafeBrowsingResourceThrottle::WillStartRequest(bool* defer) { |
137 // We need to check the new URL before starting the request. | 139 // We need to check the new URL before starting the request. |
138 if (CheckUrl(request_->url())) | 140 if (CheckUrl(request_->url())) |
139 return; | 141 return; |
140 | 142 |
141 // We let the check run in parallel with resource load only if this | 143 // We let the check run in parallel with resource load only if this |
142 // db_manager only supports asynchronous checks, like on mobile. | 144 // db_manager only supports asynchronous checks, like on mobile. |
143 // Otherwise, we defer now. | 145 // Otherwise, we defer now. |
144 if (database_manager_->ChecksAreAlwaysAsync()) | 146 if (database_manager_->ChecksAreAlwaysAsync()) |
145 return; | 147 return; |
146 | 148 |
147 // If the URL couldn't be verified synchronously, defer starting the | 149 // If the URL couldn't be verified synchronously, defer starting the |
148 // request until the check has completed. | 150 // request until the check has completed. |
149 defer_state_ = DEFERRED_START; | 151 defer_state_ = DEFERRED_START; |
150 defer_start_time_ = base::TimeTicks::Now(); | 152 defer_start_time_ = base::TimeTicks::Now(); |
151 *defer = true; | 153 *defer = true; |
152 BeginNetLogEvent(NetLog::TYPE_SAFE_BROWSING_DEFERRED, request_->url(), | 154 BeginNetLogEvent(NetLogEventType::SAFE_BROWSING_DEFERRED, request_->url(), |
153 "defer_reason", "at_start"); | 155 "defer_reason", "at_start"); |
154 } | 156 } |
155 | 157 |
156 void SafeBrowsingResourceThrottle::WillProcessResponse(bool* defer) { | 158 void SafeBrowsingResourceThrottle::WillProcessResponse(bool* defer) { |
157 CHECK_EQ(defer_state_, DEFERRED_NONE); | 159 CHECK_EQ(defer_state_, DEFERRED_NONE); |
158 // TODO(nparker): Maybe remove this check, since it should have no effect. | 160 // TODO(nparker): Maybe remove this check, since it should have no effect. |
159 if (!database_manager_->ChecksAreAlwaysAsync()) | 161 if (!database_manager_->ChecksAreAlwaysAsync()) |
160 return; | 162 return; |
161 | 163 |
162 if (state_ == STATE_CHECKING_URL || | 164 if (state_ == STATE_CHECKING_URL || |
163 state_ == STATE_DISPLAYING_BLOCKING_PAGE) { | 165 state_ == STATE_DISPLAYING_BLOCKING_PAGE) { |
164 defer_state_ = DEFERRED_PROCESSING; | 166 defer_state_ = DEFERRED_PROCESSING; |
165 defer_start_time_ = base::TimeTicks::Now(); | 167 defer_start_time_ = base::TimeTicks::Now(); |
166 *defer = true; | 168 *defer = true; |
167 BeginNetLogEvent(NetLog::TYPE_SAFE_BROWSING_DEFERRED, request_->url(), | 169 BeginNetLogEvent(NetLogEventType::SAFE_BROWSING_DEFERRED, request_->url(), |
168 "defer_reason", "at_response"); | 170 "defer_reason", "at_response"); |
169 } | 171 } |
170 } | 172 } |
171 | 173 |
172 void SafeBrowsingResourceThrottle::WillRedirectRequest( | 174 void SafeBrowsingResourceThrottle::WillRedirectRequest( |
173 const net::RedirectInfo& redirect_info, | 175 const net::RedirectInfo& redirect_info, |
174 bool* defer) { | 176 bool* defer) { |
175 CHECK_EQ(defer_state_, DEFERRED_NONE); | 177 CHECK_EQ(defer_state_, DEFERRED_NONE); |
176 | 178 |
177 // Prev check completed and was safe. | 179 // Prev check completed and was safe. |
(...skipping 10 matching lines...) Expand all Loading... | |
188 state_ == STATE_DISPLAYING_BLOCKING_PAGE); | 190 state_ == STATE_DISPLAYING_BLOCKING_PAGE); |
189 // We can't check this new URL until we have finished checking | 191 // We can't check this new URL until we have finished checking |
190 // the prev one, or resumed from the blocking page. | 192 // the prev one, or resumed from the blocking page. |
191 unchecked_redirect_url_ = redirect_info.new_url; | 193 unchecked_redirect_url_ = redirect_info.new_url; |
192 defer_state_ = DEFERRED_UNCHECKED_REDIRECT; | 194 defer_state_ = DEFERRED_UNCHECKED_REDIRECT; |
193 } | 195 } |
194 | 196 |
195 defer_start_time_ = base::TimeTicks::Now(); | 197 defer_start_time_ = base::TimeTicks::Now(); |
196 *defer = true; | 198 *defer = true; |
197 BeginNetLogEvent( | 199 BeginNetLogEvent( |
198 NetLog::TYPE_SAFE_BROWSING_DEFERRED, redirect_info.new_url, | 200 NetLogEventType::SAFE_BROWSING_DEFERRED, redirect_info.new_url, |
199 "defer_reason", | 201 "defer_reason", |
200 defer_state_ == DEFERRED_REDIRECT ? "redirect" : "unchecked_redirect"); | 202 defer_state_ == DEFERRED_REDIRECT ? "redirect" : "unchecked_redirect"); |
201 } | 203 } |
202 | 204 |
203 const char* SafeBrowsingResourceThrottle::GetNameForLogging() const { | 205 const char* SafeBrowsingResourceThrottle::GetNameForLogging() const { |
204 return "SafeBrowsingResourceThrottle"; | 206 return "SafeBrowsingResourceThrottle"; |
205 } | 207 } |
206 | 208 |
207 // SafeBrowsingService::Client implementation, called on the IO thread once | 209 // SafeBrowsingService::Client implementation, called on the IO thread once |
208 // the URL has been classified. | 210 // the URL has been classified. |
209 void SafeBrowsingResourceThrottle::OnCheckBrowseUrlResult( | 211 void SafeBrowsingResourceThrottle::OnCheckBrowseUrlResult( |
210 const GURL& url, | 212 const GURL& url, |
211 safe_browsing::SBThreatType threat_type, | 213 safe_browsing::SBThreatType threat_type, |
212 const safe_browsing::ThreatMetadata& metadata) { | 214 const safe_browsing::ThreatMetadata& metadata) { |
213 CHECK_EQ(state_, STATE_CHECKING_URL); | 215 CHECK_EQ(state_, STATE_CHECKING_URL); |
214 CHECK_EQ(url, url_being_checked_); | 216 CHECK_EQ(url, url_being_checked_); |
215 | 217 |
216 timer_.Stop(); // Cancel the timeout timer. | 218 timer_.Stop(); // Cancel the timeout timer. |
217 threat_type_ = threat_type; | 219 threat_type_ = threat_type; |
218 state_ = STATE_NONE; | 220 state_ = STATE_NONE; |
219 | 221 |
220 if (defer_state_ != DEFERRED_NONE) { | 222 if (defer_state_ != DEFERRED_NONE) { |
221 EndNetLogEvent(NetLog::TYPE_SAFE_BROWSING_DEFERRED, nullptr, nullptr); | 223 EndNetLogEvent(NetLogEventType::SAFE_BROWSING_DEFERRED, nullptr, nullptr); |
222 } | 224 } |
223 EndNetLogEvent( | 225 EndNetLogEvent( |
224 NetLog::TYPE_SAFE_BROWSING_CHECKING_URL, "result", | 226 NetLogEventType::SAFE_BROWSING_CHECKING_URL, "result", |
225 threat_type_ == safe_browsing::SB_THREAT_TYPE_SAFE ? "safe" : "unsafe"); | 227 threat_type_ == safe_browsing::SB_THREAT_TYPE_SAFE ? "safe" : "unsafe"); |
226 | 228 |
227 if (threat_type == safe_browsing::SB_THREAT_TYPE_SAFE) { | 229 if (threat_type == safe_browsing::SB_THREAT_TYPE_SAFE) { |
228 RecordHistogramResourceTypeSafe(resource_type_); | 230 RecordHistogramResourceTypeSafe(resource_type_); |
229 if (defer_state_ != DEFERRED_NONE) { | 231 if (defer_state_ != DEFERRED_NONE) { |
230 // Log how much time the safe browsing check cost us. | 232 // Log how much time the safe browsing check cost us. |
231 ui_manager_->LogPauseDelay(base::TimeTicks::Now() - defer_start_time_); | 233 ui_manager_->LogPauseDelay(base::TimeTicks::Now() - defer_start_time_); |
232 ResumeRequest(); | 234 ResumeRequest(); |
233 } else { | 235 } else { |
234 ui_manager_->LogPauseDelay(base::TimeDelta()); | 236 ui_manager_->LogPauseDelay(base::TimeDelta()); |
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
344 | 346 |
345 if (succeeded_synchronously) { | 347 if (succeeded_synchronously) { |
346 RecordHistogramResourceTypeSafe(resource_type_); | 348 RecordHistogramResourceTypeSafe(resource_type_); |
347 threat_type_ = safe_browsing::SB_THREAT_TYPE_SAFE; | 349 threat_type_ = safe_browsing::SB_THREAT_TYPE_SAFE; |
348 ui_manager_->LogPauseDelay(base::TimeDelta()); // No delay. | 350 ui_manager_->LogPauseDelay(base::TimeDelta()); // No delay. |
349 return true; | 351 return true; |
350 } | 352 } |
351 | 353 |
352 state_ = STATE_CHECKING_URL; | 354 state_ = STATE_CHECKING_URL; |
353 url_being_checked_ = url; | 355 url_being_checked_ = url; |
354 BeginNetLogEvent(NetLog::TYPE_SAFE_BROWSING_CHECKING_URL, url, nullptr, | 356 BeginNetLogEvent(NetLogEventType::SAFE_BROWSING_CHECKING_URL, url, nullptr, |
355 nullptr); | 357 nullptr); |
356 | 358 |
357 // Start a timer to abort the check if it takes too long. | 359 // Start a timer to abort the check if it takes too long. |
358 // TODO(nparker): Set this only when we defer, based on remaining time, | 360 // TODO(nparker): Set this only when we defer, based on remaining time, |
359 // so we don't cancel earlier than necessary. | 361 // so we don't cancel earlier than necessary. |
360 timer_.Start(FROM_HERE, | 362 timer_.Start(FROM_HERE, |
361 base::TimeDelta::FromMilliseconds(kCheckUrlTimeoutMs), | 363 base::TimeDelta::FromMilliseconds(kCheckUrlTimeoutMs), |
362 this, &SafeBrowsingResourceThrottle::OnCheckUrlTimeout); | 364 this, &SafeBrowsingResourceThrottle::OnCheckUrlTimeout); |
363 | 365 |
364 return false; | 366 return false; |
(...skipping 12 matching lines...) Expand all Loading... | |
377 CHECK_NE(defer_state_, DEFERRED_NONE); | 379 CHECK_NE(defer_state_, DEFERRED_NONE); |
378 | 380 |
379 bool resume = true; | 381 bool resume = true; |
380 if (defer_state_ == DEFERRED_UNCHECKED_REDIRECT) { | 382 if (defer_state_ == DEFERRED_UNCHECKED_REDIRECT) { |
381 // Save the redirect urls for possible malware detail reporting later. | 383 // Save the redirect urls for possible malware detail reporting later. |
382 redirect_urls_.push_back(unchecked_redirect_url_); | 384 redirect_urls_.push_back(unchecked_redirect_url_); |
383 if (!CheckUrl(unchecked_redirect_url_)) { | 385 if (!CheckUrl(unchecked_redirect_url_)) { |
384 // We're now waiting for the unchecked_redirect_url_. | 386 // We're now waiting for the unchecked_redirect_url_. |
385 defer_state_ = DEFERRED_REDIRECT; | 387 defer_state_ = DEFERRED_REDIRECT; |
386 resume = false; | 388 resume = false; |
387 BeginNetLogEvent(NetLog::TYPE_SAFE_BROWSING_DEFERRED, | 389 BeginNetLogEvent(NetLogEventType::SAFE_BROWSING_DEFERRED, |
388 unchecked_redirect_url_, "defer_reason", | 390 unchecked_redirect_url_, "defer_reason", |
389 "resumed_redirect"); | 391 "resumed_redirect"); |
390 } | 392 } |
391 } | 393 } |
392 | 394 |
393 if (resume) { | 395 if (resume) { |
394 defer_state_ = DEFERRED_NONE; | 396 defer_state_ = DEFERRED_NONE; |
395 controller()->Resume(); | 397 controller()->Resume(); |
396 } | 398 } |
397 } | 399 } |
OLD | NEW |