OLD | NEW |
---|---|
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/subresource_filter/content/browser/content_subresource_filt er_driver_factory.h" | 5 #include "components/subresource_filter/content/browser/content_subresource_filt er_driver_factory.h" |
6 | 6 |
7 #include "base/feature_list.h" | 7 #include "base/feature_list.h" |
8 #include "base/metrics/histogram_macros.h" | 8 #include "base/metrics/histogram_macros.h" |
9 #include "base/rand_util.h" | 9 #include "base/rand_util.h" |
10 #include "base/time/time.h" | 10 #include "base/time/time.h" |
(...skipping 16 matching lines...) Expand all Loading... | |
27 | 27 |
28 namespace { | 28 namespace { |
29 | 29 |
30 const char kWebContentsUserDataKey[] = | 30 const char kWebContentsUserDataKey[] = |
31 "web_contents_subresource_filter_driver_factory"; | 31 "web_contents_subresource_filter_driver_factory"; |
32 | 32 |
33 std::string DistillURLToHostAndPath(const GURL& url) { | 33 std::string DistillURLToHostAndPath(const GURL& url) { |
34 return url.host() + url.path(); | 34 return url.host() + url.path(); |
35 } | 35 } |
36 | 36 |
37 // Returns true with a probability of GetPerformanceMeasurementRate() if | 37 // Returns true with a probability given by |performance_measurement_rate| in |
38 // ThreadTicks is supported, otherwise returns false. | 38 // |configuration| if ThreadTicks is supported, otherwise returns false. |
39 bool ShouldMeasurePerformanceForPageLoad() { | 39 bool ShouldMeasurePerformanceForPageLoad(const Configuration& configuration) { |
40 if (!base::ThreadTicks::IsSupported()) | 40 if (!base::ThreadTicks::IsSupported()) |
41 return false; | 41 return false; |
42 // TODO(pkalinnikov): Cache |rate| and other variation params in | 42 // TODO(pkalinnikov): Cache |rate| and other variation params in |
43 // ContentSubresourceFilterDriverFactory. | 43 // ContentSubresourceFilterDriverFactory. |
44 const double rate = GetPerformanceMeasurementRate(); | 44 const double rate = configuration.performance_measurement_rate; |
45 return rate == 1 || (rate > 0 && base::RandDouble() < rate); | 45 return rate == 1 || (rate > 0 && base::RandDouble() < rate); |
46 } | 46 } |
47 | 47 |
48 // Records histograms about the length of redirect chains, and about the pattern | 48 // Records histograms about the length of redirect chains, and about the pattern |
49 // of whether each URL in the chain matched the activation list. | 49 // of whether each URL in the chain matched the activation list. |
50 #define REPORT_REDIRECT_PATTERN_FOR_SUFFIX(suffix, hits_pattern, chain_size) \ | 50 #define REPORT_REDIRECT_PATTERN_FOR_SUFFIX(suffix, hits_pattern, chain_size) \ |
51 do { \ | 51 do { \ |
52 UMA_HISTOGRAM_ENUMERATION( \ | 52 UMA_HISTOGRAM_ENUMERATION( \ |
53 "SubresourceFilter.PageLoad.RedirectChainMatchPattern." suffix, \ | 53 "SubresourceFilter.PageLoad.RedirectChainMatchPattern." suffix, \ |
54 hits_pattern, 0x10); \ | 54 hits_pattern, 0x10); \ |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
139 | 139 |
140 void ContentSubresourceFilterDriverFactory::AddHostOfURLToWhitelistSet( | 140 void ContentSubresourceFilterDriverFactory::AddHostOfURLToWhitelistSet( |
141 const GURL& url) { | 141 const GURL& url) { |
142 if (url.has_host() && url.SchemeIsHTTPOrHTTPS()) | 142 if (url.has_host() && url.SchemeIsHTTPOrHTTPS()) |
143 whitelisted_hosts_.insert(url.host()); | 143 whitelisted_hosts_.insert(url.host()); |
144 } | 144 } |
145 | 145 |
146 ContentSubresourceFilterDriverFactory::ActivationDecision | 146 ContentSubresourceFilterDriverFactory::ActivationDecision |
147 ContentSubresourceFilterDriverFactory::ComputeActivationDecisionForMainFrameURL( | 147 ContentSubresourceFilterDriverFactory::ComputeActivationDecisionForMainFrameURL( |
148 const GURL& url) const { | 148 const GURL& url) const { |
149 if (GetMaximumActivationLevel() == ActivationLevel::DISABLED) | 149 if (configuration_.activation_level == ActivationLevel::DISABLED) |
150 return ActivationDecision::ACTIVATION_DISABLED; | 150 return ActivationDecision::ACTIVATION_DISABLED; |
151 | 151 |
152 ActivationScope scope = GetCurrentActivationScope(); | 152 if (configuration_.activation_scope == ActivationScope::NO_SITES) |
153 if (scope == ActivationScope::NO_SITES) | |
154 return ActivationDecision::ACTIVATION_DISABLED; | 153 return ActivationDecision::ACTIVATION_DISABLED; |
155 | 154 |
156 if (!url.SchemeIsHTTPOrHTTPS()) | 155 if (!url.SchemeIsHTTPOrHTTPS()) |
157 return ActivationDecision::UNSUPPORTED_SCHEME; | 156 return ActivationDecision::UNSUPPORTED_SCHEME; |
158 if (IsWhitelisted(url)) | 157 if (IsWhitelisted(url)) |
159 return ActivationDecision::URL_WHITELISTED; | 158 return ActivationDecision::URL_WHITELISTED; |
160 | 159 |
161 switch (scope) { | 160 switch (configuration_.activation_scope) { |
162 case ActivationScope::ALL_SITES: | 161 case ActivationScope::ALL_SITES: |
163 return ActivationDecision::ACTIVATED; | 162 return ActivationDecision::ACTIVATED; |
164 case ActivationScope::ACTIVATION_LIST: { | 163 case ActivationScope::ACTIVATION_LIST: { |
165 // The logic to ensure only http/https URLs are activated lives in | 164 // The logic to ensure only http/https URLs are activated lives in |
166 // AddActivationListMatch to ensure the activation list only has relevant | 165 // AddActivationListMatch to ensure the activation list only has relevant |
167 // entries. | 166 // entries. |
168 DCHECK(url.SchemeIsHTTPOrHTTPS() || | 167 DCHECK(url.SchemeIsHTTPOrHTTPS() || |
169 !DidURLMatchActivationList(url, GetCurrentActivationList())); | 168 !DidURLMatchActivationList(url, configuration_.activation_list)); |
170 bool should_activate = | 169 bool should_activate = |
171 DidURLMatchActivationList(url, GetCurrentActivationList()); | 170 DidURLMatchActivationList(url, configuration_.activation_list); |
172 if (GetCurrentActivationList() == ActivationList::PHISHING_INTERSTITIAL) { | 171 if (configuration_.activation_list == |
172 ActivationList::PHISHING_INTERSTITIAL) { | |
173 // Handling special case, where activation on the phishing sites also | 173 // Handling special case, where activation on the phishing sites also |
174 // mean the activation on the sites with social engineering metadata. | 174 // mean the activation on the sites with social engineering metadata. |
175 should_activate |= DidURLMatchActivationList( | 175 should_activate |= DidURLMatchActivationList( |
176 url, ActivationList::SOCIAL_ENG_ADS_INTERSTITIAL); | 176 url, ActivationList::SOCIAL_ENG_ADS_INTERSTITIAL); |
177 } | 177 } |
178 return should_activate ? ActivationDecision::ACTIVATED | 178 return should_activate ? ActivationDecision::ACTIVATED |
179 : ActivationDecision::ACTIVATION_LIST_NOT_MATCHED; | 179 : ActivationDecision::ACTIVATION_LIST_NOT_MATCHED; |
180 } | 180 } |
181 default: | 181 default: |
182 return ActivationDecision::ACTIVATION_DISABLED; | 182 return ActivationDecision::ACTIVATION_DISABLED; |
(...skipping 23 matching lines...) Expand all Loading... | |
206 navigation_handle->GetNetErrorCode() != net::OK) { | 206 navigation_handle->GetNetErrorCode() != net::OK) { |
207 return; | 207 return; |
208 } | 208 } |
209 | 209 |
210 const GURL& url = navigation_handle->GetURL(); | 210 const GURL& url = navigation_handle->GetURL(); |
211 const content::Referrer& referrer = navigation_handle->GetReferrer(); | 211 const content::Referrer& referrer = navigation_handle->GetReferrer(); |
212 ui::PageTransition transition = navigation_handle->GetPageTransition(); | 212 ui::PageTransition transition = navigation_handle->GetPageTransition(); |
213 | 213 |
214 RecordRedirectChainMatchPattern(); | 214 RecordRedirectChainMatchPattern(); |
215 | 215 |
216 if (ShouldWhitelistSiteOnReload() && | 216 if (configuration_.should_whitelist_site_on_reload && |
217 NavigationIsPageReload(url, referrer, transition)) { | 217 NavigationIsPageReload(url, referrer, transition)) { |
218 // Whitelist this host for the current as well as subsequent navigations. | 218 // Whitelist this host for the current as well as subsequent navigations. |
219 AddHostOfURLToWhitelistSet(url); | 219 AddHostOfURLToWhitelistSet(url); |
220 } | 220 } |
221 | 221 |
222 activation_decision_ = ComputeActivationDecisionForMainFrameURL(url); | 222 activation_decision_ = ComputeActivationDecisionForMainFrameURL(url); |
223 DCHECK(activation_decision_ != ActivationDecision::UNKNOWN); | 223 DCHECK(activation_decision_ != ActivationDecision::UNKNOWN); |
224 if (activation_decision_ != ActivationDecision::ACTIVATED) { | 224 if (activation_decision_ != ActivationDecision::ACTIVATED) { |
225 ResetActivationState(); | 225 ResetActivationState(); |
226 return; | 226 return; |
227 } | 227 } |
228 | 228 |
229 activation_level_ = GetMaximumActivationLevel(); | 229 activation_level_ = configuration_.activation_level; |
230 measure_performance_ = activation_level_ != ActivationLevel::DISABLED && | 230 measure_performance_ = activation_level_ != ActivationLevel::DISABLED && |
231 ShouldMeasurePerformanceForPageLoad(); | 231 ShouldMeasurePerformanceForPageLoad(configuration_); |
232 ActivationState state = ActivationState(activation_level_); | 232 ActivationState state = ActivationState(activation_level_); |
233 state.measure_performance = measure_performance_; | 233 state.measure_performance = measure_performance_; |
234 throttle_manager_->NotifyPageActivationComputed(navigation_handle, state); | 234 throttle_manager_->NotifyPageActivationComputed(navigation_handle, state); |
235 } | 235 } |
236 | 236 |
237 void ContentSubresourceFilterDriverFactory::OnFirstSubresourceLoadDisallowed() { | 237 void ContentSubresourceFilterDriverFactory::OnFirstSubresourceLoadDisallowed() { |
238 if (ShouldSuppressNotifications()) | 238 if (configuration_.should_suppress_notifications) |
239 return; | 239 return; |
240 | 240 |
241 client_->ToggleNotificationVisibility(activation_level_ == | 241 client_->ToggleNotificationVisibility(activation_level_ == |
242 ActivationLevel::ENABLED); | 242 ActivationLevel::ENABLED); |
243 } | 243 } |
244 | 244 |
245 bool ContentSubresourceFilterDriverFactory::ShouldSuppressActivation( | 245 bool ContentSubresourceFilterDriverFactory::ShouldSuppressActivation( |
246 content::NavigationHandle* navigation_handle) { | 246 content::NavigationHandle* navigation_handle) { |
247 // Never suppress subframe navigations. | 247 // Never suppress subframe navigations. |
248 return navigation_handle->IsInMainFrame() && | 248 return navigation_handle->IsInMainFrame() && |
249 IsWhitelisted(navigation_handle->GetURL()); | 249 IsWhitelisted(navigation_handle->GetURL()); |
250 } | 250 } |
251 | 251 |
252 void ContentSubresourceFilterDriverFactory::ResetActivationState() { | 252 void ContentSubresourceFilterDriverFactory::ResetActivationState() { |
253 navigation_chain_.clear(); | 253 navigation_chain_.clear(); |
254 activation_list_matches_.clear(); | 254 activation_list_matches_.clear(); |
255 activation_level_ = ActivationLevel::DISABLED; | 255 activation_level_ = ActivationLevel::DISABLED; |
256 measure_performance_ = false; | 256 measure_performance_ = false; |
257 aggregated_document_statistics_ = DocumentLoadStatistics(); | 257 aggregated_document_statistics_ = DocumentLoadStatistics(); |
258 } | 258 } |
259 | 259 |
260 void ContentSubresourceFilterDriverFactory::DidStartNavigation( | 260 void ContentSubresourceFilterDriverFactory::DidStartNavigation( |
261 content::NavigationHandle* navigation_handle) { | 261 content::NavigationHandle* navigation_handle) { |
262 if (navigation_handle->IsInMainFrame() && | 262 if (navigation_handle->IsInMainFrame() && |
263 !navigation_handle->IsSameDocument()) { | 263 !navigation_handle->IsSameDocument()) { |
264 // TODO(https://crbug.com/708181): Somewhat hacky workaround to allow tests | |
265 // to change the configuration after construction. Can be removed once the | |
266 // Safe Browsing navigation throttle handles all activation decisions. | |
267 configuration_ = GetActiveConfiguration(); | |
Charlie Harrison
2017/04/05 20:43:04
Eek this scares me, especially if code accidentall
engedy
2017/04/07 08:40:58
Much relieved. I was worried that it might not sca
| |
264 activation_decision_ = ActivationDecision::UNKNOWN; | 268 activation_decision_ = ActivationDecision::UNKNOWN; |
265 ResetActivationState(); | 269 ResetActivationState(); |
266 navigation_chain_.push_back(navigation_handle->GetURL()); | 270 navigation_chain_.push_back(navigation_handle->GetURL()); |
267 client_->ToggleNotificationVisibility(false); | 271 client_->ToggleNotificationVisibility(false); |
268 } | 272 } |
269 } | 273 } |
270 | 274 |
271 void ContentSubresourceFilterDriverFactory::DidRedirectNavigation( | 275 void ContentSubresourceFilterDriverFactory::DidRedirectNavigation( |
272 content::NavigationHandle* navigation_handle) { | 276 content::NavigationHandle* navigation_handle) { |
273 DCHECK(!navigation_handle->IsSameDocument()); | 277 DCHECK(!navigation_handle->IsSameDocument()); |
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
403 REPORT_REDIRECT_PATTERN_FOR_SUFFIX("SubresourceFilterOnly", hits_pattern, | 407 REPORT_REDIRECT_PATTERN_FOR_SUFFIX("SubresourceFilterOnly", hits_pattern, |
404 chain_size); | 408 chain_size); |
405 break; | 409 break; |
406 default: | 410 default: |
407 NOTREACHED(); | 411 NOTREACHED(); |
408 break; | 412 break; |
409 } | 413 } |
410 } | 414 } |
411 | 415 |
412 } // namespace subresource_filter | 416 } // namespace subresource_filter |
OLD | NEW |