Chromium Code Reviews| 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/memory/ptr_util.h" | 8 #include "base/memory/ptr_util.h" |
| 9 #include "base/metrics/histogram_macros.h" | 9 #include "base/metrics/histogram_macros.h" |
| 10 #include "base/rand_util.h" | 10 #include "base/rand_util.h" |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 77 | 77 |
| 78 ContentSubresourceFilterDriverFactory::ContentSubresourceFilterDriverFactory( | 78 ContentSubresourceFilterDriverFactory::ContentSubresourceFilterDriverFactory( |
| 79 content::WebContents* web_contents, | 79 content::WebContents* web_contents, |
| 80 SubresourceFilterClient* client) | 80 SubresourceFilterClient* client) |
| 81 : content::WebContentsObserver(web_contents), | 81 : content::WebContentsObserver(web_contents), |
| 82 client_(client), | 82 client_(client), |
| 83 throttle_manager_( | 83 throttle_manager_( |
| 84 base::MakeUnique<ContentSubresourceFilterThrottleManager>( | 84 base::MakeUnique<ContentSubresourceFilterThrottleManager>( |
| 85 this, | 85 this, |
| 86 client_->GetRulesetDealer(), | 86 client_->GetRulesetDealer(), |
| 87 web_contents)), | 87 web_contents)) {} |
| 88 activation_level_(ActivationLevel::DISABLED), | |
| 89 activation_decision_(ActivationDecision::UNKNOWN), | |
| 90 measure_performance_(false) {} | |
| 91 | 88 |
| 92 ContentSubresourceFilterDriverFactory:: | 89 ContentSubresourceFilterDriverFactory:: |
| 93 ~ContentSubresourceFilterDriverFactory() {} | 90 ~ContentSubresourceFilterDriverFactory() {} |
| 94 | 91 |
| 95 void ContentSubresourceFilterDriverFactory:: | 92 void ContentSubresourceFilterDriverFactory:: |
| 96 OnMainResourceMatchedSafeBrowsingBlacklist( | 93 OnMainResourceMatchedSafeBrowsingBlacklist( |
| 97 const GURL& url, | 94 const GURL& url, |
| 98 const std::vector<GURL>& redirect_urls, | 95 const std::vector<GURL>& redirect_urls, |
| 99 safe_browsing::SBThreatType threat_type, | 96 safe_browsing::SBThreatType threat_type, |
| 100 safe_browsing::ThreatPatternType threat_type_metadata) { | 97 safe_browsing::ThreatPatternType threat_type_metadata) { |
| 101 AddActivationListMatch( | 98 AddActivationListMatch( |
| 102 url, GetListForThreatTypeAndMetadata(threat_type, threat_type_metadata)); | 99 url, GetListForThreatTypeAndMetadata(threat_type, threat_type_metadata)); |
| 103 } | 100 } |
| 104 | 101 |
| 105 ContentSubresourceFilterDriverFactory::ActivationDecision | 102 void ContentSubresourceFilterDriverFactory:: |
| 106 ContentSubresourceFilterDriverFactory:: | 103 ComputeActivationForMainFrameNavigation( |
| 107 ComputeActivationDecisionForMainFrameNavigation( | 104 content::NavigationHandle* navigation_handle) { |
| 108 content::NavigationHandle* navigation_handle) const { | |
| 109 const GURL& url(navigation_handle->GetURL()); | 105 const GURL& url(navigation_handle->GetURL()); |
| 110 | 106 |
| 111 const auto configurations = GetActiveConfigurations(); | 107 if (!url.SchemeIsHTTPOrHTTPS()) { |
| 112 if (configurations->the_one_and_only().activation_level == | 108 activation_decision_ = ActivationDecision::UNSUPPORTED_SCHEME; |
| 113 ActivationLevel::DISABLED) | 109 activation_options_ = Configuration::ActivationOptions(); |
| 114 return ActivationDecision::ACTIVATION_DISABLED; | 110 return; |
| 111 } | |
| 115 | 112 |
| 116 if (configurations->the_one_and_only().activation_scope == | 113 const auto config_list = GetEnabledConfigurations(); |
| 117 ActivationScope::NO_SITES) | 114 const auto highest_priority_activated_config = |
| 118 return ActivationDecision::ACTIVATION_DISABLED; | 115 std::find_if(config_list->configs_by_decreasing_priority().begin(), |
| 116 config_list->configs_by_decreasing_priority().end(), | |
| 117 [url, this](const Configuration& config) { | |
|
Charlie Harrison
2017/05/05 21:16:37
Just making sure, does this properly omit the copy
engedy
2017/05/05 21:31:53
I think so, but let's make that explicit.
| |
| 118 return DoesMainFrameURLSatisfyActivationConditions( | |
| 119 url, config.activation_conditions); | |
| 120 }); | |
| 119 | 121 |
| 120 if (!url.SchemeIsHTTPOrHTTPS()) | 122 if (highest_priority_activated_config == |
| 121 return ActivationDecision::UNSUPPORTED_SCHEME; | 123 config_list->configs_by_decreasing_priority().end()) { |
| 124 activation_decision_ = ActivationDecision::ACTIVATION_CONDITIONS_NOT_MET; | |
| 125 activation_options_ = Configuration::ActivationOptions(); | |
| 126 return; | |
| 127 } | |
| 128 | |
| 122 // TODO(csharrison): The throttle manager also performs this check. Remove | 129 // TODO(csharrison): The throttle manager also performs this check. Remove |
| 123 // this one when the activation decision is sent directly to the throttle | 130 // this one when the activation decision is sent directly to the throttle |
| 124 // manager. | 131 // manager. |
| 125 if (client_->ShouldSuppressActivation(navigation_handle)) | 132 if (client_->ShouldSuppressActivation(navigation_handle)) { |
| 126 return ActivationDecision::URL_WHITELISTED; | 133 activation_decision_ = ActivationDecision::URL_WHITELISTED; |
| 134 activation_options_ = Configuration::ActivationOptions(); | |
| 135 return; | |
| 136 } | |
| 127 | 137 |
| 128 switch (configurations->the_one_and_only().activation_scope) { | 138 activation_options_ = highest_priority_activated_config->activation_options; |
| 139 activation_decision_ = | |
| 140 activation_options_.activation_level == ActivationLevel::DISABLED | |
| 141 ? ActivationDecision::ACTIVATION_DISABLED | |
| 142 : ActivationDecision::ACTIVATED; | |
| 143 } | |
| 144 | |
| 145 bool ContentSubresourceFilterDriverFactory:: | |
| 146 DoesMainFrameURLSatisfyActivationConditions( | |
| 147 const GURL& url, | |
| 148 const Configuration::ActivationConditions& conditions) const { | |
| 149 switch (conditions.activation_scope) { | |
| 129 case ActivationScope::ALL_SITES: | 150 case ActivationScope::ALL_SITES: |
| 130 return ActivationDecision::ACTIVATED; | 151 return true; |
| 131 case ActivationScope::ACTIVATION_LIST: { | 152 case ActivationScope::ACTIVATION_LIST: |
| 132 // The logic to ensure only http/https URLs are activated lives in | 153 // The logic to ensure only http/https URLs are activated lives in |
| 133 // AddActivationListMatch to ensure the activation list only has relevant | 154 // AddActivationListMatch to ensure the activation list only has relevant |
| 134 // entries. | 155 // entries. |
| 135 DCHECK(url.SchemeIsHTTPOrHTTPS() || | 156 DCHECK(url.SchemeIsHTTPOrHTTPS() || |
|
Charlie Harrison
2017/05/05 21:16:37
I think this DCHECK is redundant now with the expl
engedy
2017/05/05 21:31:53
Gladly.
| |
| 136 !DidURLMatchActivationList( | 157 !DidURLMatchActivationList(url, conditions.activation_list)); |
| 137 url, configurations->the_one_and_only().activation_list)); | 158 if (DidURLMatchActivationList(url, conditions.activation_list)) |
| 138 bool should_activate = DidURLMatchActivationList( | 159 return true; |
| 139 url, configurations->the_one_and_only().activation_list); | 160 if (conditions.activation_list == ActivationList::PHISHING_INTERSTITIAL && |
| 140 if (configurations->the_one_and_only().activation_list == | 161 DidURLMatchActivationList( |
| 141 ActivationList::PHISHING_INTERSTITIAL) { | 162 url, ActivationList::SOCIAL_ENG_ADS_INTERSTITIAL)) { |
| 142 // Handling special case, where activation on the phishing sites also | 163 // Handling special case, where activation on the phishing sites also |
| 143 // mean the activation on the sites with social engineering metadata. | 164 // mean the activation on the sites with social engineering metadata. |
| 144 should_activate |= DidURLMatchActivationList( | 165 return true; |
| 145 url, ActivationList::SOCIAL_ENG_ADS_INTERSTITIAL); | |
| 146 } | 166 } |
| 147 return should_activate ? ActivationDecision::ACTIVATED | 167 return false; |
| 148 : ActivationDecision::ACTIVATION_LIST_NOT_MATCHED; | 168 case ActivationScope::NO_SITES: |
| 149 } | 169 return false; |
| 150 default: | |
| 151 return ActivationDecision::ACTIVATION_DISABLED; | |
| 152 } | 170 } |
| 171 NOTREACHED(); | |
| 172 return false; | |
| 153 } | 173 } |
| 154 | 174 |
| 155 void ContentSubresourceFilterDriverFactory::OnReloadRequested() { | 175 void ContentSubresourceFilterDriverFactory::OnReloadRequested() { |
| 156 UMA_HISTOGRAM_BOOLEAN("SubresourceFilter.Prompt.NumReloads", true); | 176 UMA_HISTOGRAM_BOOLEAN("SubresourceFilter.Prompt.NumReloads", true); |
| 157 const GURL& whitelist_url = web_contents()->GetLastCommittedURL(); | 177 const GURL& whitelist_url = web_contents()->GetLastCommittedURL(); |
| 158 | 178 |
| 159 // Only whitelist via content settings when using the experimental UI, | 179 // Only whitelist via content settings when using the experimental UI, |
| 160 // otherwise could get into a situation where content settings cannot be | 180 // otherwise could get into a situation where content settings cannot be |
| 161 // adjusted. | 181 // adjusted. |
| 162 if (base::FeatureList::IsEnabled( | 182 if (base::FeatureList::IsEnabled( |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 175 navigation_handle->GetNetErrorCode() != net::OK) { | 195 navigation_handle->GetNetErrorCode() != net::OK) { |
| 176 return; | 196 return; |
| 177 } | 197 } |
| 178 | 198 |
| 179 const GURL& url = navigation_handle->GetURL(); | 199 const GURL& url = navigation_handle->GetURL(); |
| 180 const content::Referrer& referrer = navigation_handle->GetReferrer(); | 200 const content::Referrer& referrer = navigation_handle->GetReferrer(); |
| 181 ui::PageTransition transition = navigation_handle->GetPageTransition(); | 201 ui::PageTransition transition = navigation_handle->GetPageTransition(); |
| 182 | 202 |
| 183 RecordRedirectChainMatchPattern(); | 203 RecordRedirectChainMatchPattern(); |
| 184 | 204 |
| 185 const auto configurations = GetActiveConfigurations(); | 205 if (activation_options_.should_whitelist_site_on_reload && |
| 186 if (configurations->the_one_and_only().should_whitelist_site_on_reload && | |
| 187 NavigationIsPageReload(url, referrer, transition)) { | 206 NavigationIsPageReload(url, referrer, transition)) { |
| 188 // Whitelist this host for the current as well as subsequent navigations. | 207 // Whitelist this host for the current as well as subsequent navigations. |
| 189 client_->WhitelistInCurrentWebContents(url); | 208 client_->WhitelistInCurrentWebContents(url); |
| 190 } | 209 } |
| 191 | 210 |
| 192 activation_decision_ = | 211 ComputeActivationForMainFrameNavigation(navigation_handle); |
| 193 ComputeActivationDecisionForMainFrameNavigation(navigation_handle); | 212 DCHECK_NE(activation_decision_, ActivationDecision::UNKNOWN); |
| 194 DCHECK(activation_decision_ != ActivationDecision::UNKNOWN); | |
| 195 if (activation_decision_ != ActivationDecision::ACTIVATED) { | 213 if (activation_decision_ != ActivationDecision::ACTIVATED) { |
| 196 ResetActivationState(); | 214 DCHECK_EQ(activation_options_.activation_level, ActivationLevel::DISABLED); |
| 197 return; | 215 return; |
| 198 } | 216 } |
| 199 | 217 |
| 200 activation_level_ = configurations->the_one_and_only().activation_level; | 218 DCHECK_NE(activation_options_.activation_level, ActivationLevel::DISABLED); |
| 201 measure_performance_ = | 219 ActivationState state = ActivationState(activation_options_.activation_level); |
| 202 activation_level_ != ActivationLevel::DISABLED && | 220 state.measure_performance = ShouldMeasurePerformanceForPageLoad( |
| 203 ShouldMeasurePerformanceForPageLoad( | 221 activation_options_.performance_measurement_rate); |
| 204 configurations->the_one_and_only().performance_measurement_rate); | |
| 205 ActivationState state = ActivationState(activation_level_); | |
| 206 state.measure_performance = measure_performance_; | |
| 207 throttle_manager_->NotifyPageActivationComputed(navigation_handle, state); | 222 throttle_manager_->NotifyPageActivationComputed(navigation_handle, state); |
| 208 } | 223 } |
| 209 | 224 |
| 210 void ContentSubresourceFilterDriverFactory::OnFirstSubresourceLoadDisallowed() { | 225 void ContentSubresourceFilterDriverFactory::OnFirstSubresourceLoadDisallowed() { |
| 211 const auto configurations = GetActiveConfigurations(); | 226 if (activation_options_.should_suppress_notifications) |
| 212 if (configurations->the_one_and_only().should_suppress_notifications) | |
| 213 return; | 227 return; |
| 214 | 228 client_->ToggleNotificationVisibility(activation_options_.activation_level == |
| 215 client_->ToggleNotificationVisibility(activation_level_ == | |
| 216 ActivationLevel::ENABLED); | 229 ActivationLevel::ENABLED); |
| 217 } | 230 } |
| 218 | 231 |
| 219 bool ContentSubresourceFilterDriverFactory::ShouldSuppressActivation( | 232 bool ContentSubresourceFilterDriverFactory::ShouldSuppressActivation( |
| 220 content::NavigationHandle* navigation_handle) { | 233 content::NavigationHandle* navigation_handle) { |
| 221 return client_->ShouldSuppressActivation(navigation_handle); | 234 return client_->ShouldSuppressActivation(navigation_handle); |
| 222 } | 235 } |
| 223 | 236 |
| 224 void ContentSubresourceFilterDriverFactory::ResetActivationState() { | |
| 225 navigation_chain_.clear(); | |
| 226 activation_list_matches_.clear(); | |
| 227 activation_level_ = ActivationLevel::DISABLED; | |
| 228 measure_performance_ = false; | |
| 229 } | |
| 230 | |
| 231 void ContentSubresourceFilterDriverFactory::DidStartNavigation( | 237 void ContentSubresourceFilterDriverFactory::DidStartNavigation( |
| 232 content::NavigationHandle* navigation_handle) { | 238 content::NavigationHandle* navigation_handle) { |
| 233 if (navigation_handle->IsInMainFrame() && | 239 if (navigation_handle->IsInMainFrame() && |
| 234 !navigation_handle->IsSameDocument()) { | 240 !navigation_handle->IsSameDocument()) { |
| 235 activation_decision_ = ActivationDecision::UNKNOWN; | 241 activation_decision_ = ActivationDecision::UNKNOWN; |
| 236 ResetActivationState(); | 242 activation_list_matches_.clear(); |
| 237 navigation_chain_.push_back(navigation_handle->GetURL()); | 243 navigation_chain_ = {navigation_handle->GetURL()}; |
| 238 client_->ToggleNotificationVisibility(false); | 244 client_->ToggleNotificationVisibility(false); |
| 239 } | 245 } |
| 240 } | 246 } |
| 241 | 247 |
| 242 void ContentSubresourceFilterDriverFactory::DidRedirectNavigation( | 248 void ContentSubresourceFilterDriverFactory::DidRedirectNavigation( |
| 243 content::NavigationHandle* navigation_handle) { | 249 content::NavigationHandle* navigation_handle) { |
| 244 DCHECK(!navigation_handle->IsSameDocument()); | 250 DCHECK(!navigation_handle->IsSameDocument()); |
| 245 if (navigation_handle->IsInMainFrame()) | 251 if (navigation_handle->IsInMainFrame()) |
| 246 navigation_chain_.push_back(navigation_handle->GetURL()); | 252 navigation_chain_.push_back(navigation_handle->GetURL()); |
| 247 } | 253 } |
| 248 | 254 |
| 255 void ContentSubresourceFilterDriverFactory::DidFinishNavigation( | |
| 256 content::NavigationHandle* navigation_handle) { | |
| 257 if (navigation_handle->IsInMainFrame() && | |
| 258 !navigation_handle->IsSameDocument() && | |
| 259 activation_decision_ == ActivationDecision::UNKNOWN && | |
| 260 navigation_handle->HasCommitted()) { | |
| 261 activation_decision_ = ActivationDecision::ACTIVATION_DISABLED; | |
| 262 activation_options_ = Configuration::ActivationOptions(); | |
| 263 } | |
| 264 } | |
| 265 | |
| 249 bool ContentSubresourceFilterDriverFactory::DidURLMatchActivationList( | 266 bool ContentSubresourceFilterDriverFactory::DidURLMatchActivationList( |
| 250 const GURL& url, | 267 const GURL& url, |
| 251 ActivationList activation_list) const { | 268 ActivationList activation_list) const { |
| 252 auto match_types = | 269 auto match_types = |
| 253 activation_list_matches_.find(DistillURLToHostAndPath(url)); | 270 activation_list_matches_.find(DistillURLToHostAndPath(url)); |
| 254 return match_types != activation_list_matches_.end() && | 271 return match_types != activation_list_matches_.end() && |
| 255 match_types->second.find(activation_list) != match_types->second.end(); | 272 match_types->second.find(activation_list) != match_types->second.end(); |
| 256 } | 273 } |
| 257 | 274 |
| 258 void ContentSubresourceFilterDriverFactory::AddActivationListMatch( | 275 void ContentSubresourceFilterDriverFactory::AddActivationListMatch( |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 321 REPORT_REDIRECT_PATTERN_FOR_SUFFIX("SubresourceFilterOnly", hits_pattern, | 338 REPORT_REDIRECT_PATTERN_FOR_SUFFIX("SubresourceFilterOnly", hits_pattern, |
| 322 chain_size); | 339 chain_size); |
| 323 break; | 340 break; |
| 324 default: | 341 default: |
| 325 NOTREACHED(); | 342 NOTREACHED(); |
| 326 break; | 343 break; |
| 327 } | 344 } |
| 328 } | 345 } |
| 329 | 346 |
| 330 } // namespace subresource_filter | 347 } // namespace subresource_filter |
| OLD | NEW |