| 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/extensions/api/declarative_webrequest/webrequest_rules_
registry.h" | 5 #include "chrome/browser/extensions/api/declarative_webrequest/webrequest_rules_
registry.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <limits> | 8 #include <limits> |
| 9 #include <utility> | 9 #include <utility> |
| 10 | 10 |
| 11 #include "base/stl_util.h" | 11 #include "base/stl_util.h" |
| 12 #include "chrome/browser/extensions/api/declarative_webrequest/webrequest_condit
ion.h" | 12 #include "chrome/browser/extensions/api/declarative_webrequest/webrequest_condit
ion.h" |
| 13 #include "chrome/browser/extensions/api/web_request/web_request_api_helpers.h" | 13 #include "chrome/browser/extensions/api/web_request/web_request_api_helpers.h" |
| 14 #include "chrome/browser/extensions/api/web_request/web_request_permissions.h" | 14 #include "chrome/browser/extensions/api/web_request/web_request_permissions.h" |
| 15 #include "chrome/browser/extensions/extension_system.h" | 15 #include "chrome/browser/extensions/extension_system.h" |
| 16 #include "net/url_request/url_request.h" | 16 #include "net/url_request/url_request.h" |
| 17 | 17 |
| 18 namespace { |
| 19 const char kActionCannotBeExecuted[] = "An action can never be executed " |
| 20 "because there are is no time in the request life-cycle during which the " |
| 21 "conditions can be checked and the action can possibly be executed."; |
| 22 } // namespace |
| 23 |
| 18 namespace extensions { | 24 namespace extensions { |
| 19 | 25 |
| 20 WebRequestRulesRegistry::WebRequestRulesRegistry(Profile* profile, | 26 WebRequestRulesRegistry::WebRequestRulesRegistry(Profile* profile, |
| 21 Delegate* delegate) | 27 Delegate* delegate) |
| 22 : RulesRegistryWithCache(delegate) { | 28 : RulesRegistryWithCache(delegate) { |
| 23 if (profile) | 29 if (profile) |
| 24 extension_info_map_ = ExtensionSystem::Get(profile)->info_map(); | 30 extension_info_map_ = ExtensionSystem::Get(profile)->info_map(); |
| 25 } | 31 } |
| 26 | 32 |
| 27 std::set<const WebRequestRule*> | 33 std::set<const WebRequestRule*> |
| 28 WebRequestRulesRegistry::GetMatches( | 34 WebRequestRulesRegistry::GetMatches( |
| 29 const WebRequestRule::RequestData& request_data) { | 35 const DeclarativeWebRequestData& request_data) { |
| 30 typedef std::set<const WebRequestRule*> RuleSet; | 36 typedef std::set<const WebRequestRule*> RuleSet; |
| 31 typedef std::set<URLMatcherConditionSet::ID> URLMatches; | 37 typedef std::set<URLMatcherConditionSet::ID> URLMatches; |
| 32 | 38 |
| 33 RuleSet result; | 39 RuleSet result; |
| 34 URLMatches url_matches = url_matcher_.MatchURL(request_data.request->url()); | 40 URLMatches url_matches = url_matcher_.MatchURL(request_data.request->url()); |
| 35 | 41 |
| 36 // 1st phase -- add all rules with some conditions without UrlFilter | 42 // 1st phase -- add all rules with some conditions without UrlFilter |
| 37 // attributes. | 43 // attributes. |
| 38 for (RuleSet::const_iterator it = rules_with_untriggered_conditions_.begin(); | 44 for (RuleSet::const_iterator it = rules_with_untriggered_conditions_.begin(); |
| 39 it != rules_with_untriggered_conditions_.end(); ++it) { | 45 it != rules_with_untriggered_conditions_.end(); ++it) { |
| (...skipping 10 matching lines...) Expand all Loading... |
| 50 rule_trigger->second->conditions().IsFulfilled(*url_match, url_matches, | 56 rule_trigger->second->conditions().IsFulfilled(*url_match, url_matches, |
| 51 request_data)) | 57 request_data)) |
| 52 result.insert(rule_trigger->second); | 58 result.insert(rule_trigger->second); |
| 53 } | 59 } |
| 54 | 60 |
| 55 return result; | 61 return result; |
| 56 } | 62 } |
| 57 | 63 |
| 58 std::list<LinkedPtrEventResponseDelta> WebRequestRulesRegistry::CreateDeltas( | 64 std::list<LinkedPtrEventResponseDelta> WebRequestRulesRegistry::CreateDeltas( |
| 59 const ExtensionInfoMap* extension_info_map, | 65 const ExtensionInfoMap* extension_info_map, |
| 60 const WebRequestRule::RequestData& request_data, | 66 const DeclarativeWebRequestData& request_data, |
| 61 bool crosses_incognito) { | 67 bool crosses_incognito) { |
| 62 if (webrequest_rules_.empty()) | 68 if (webrequest_rules_.empty()) |
| 63 return std::list<LinkedPtrEventResponseDelta>(); | 69 return std::list<LinkedPtrEventResponseDelta>(); |
| 64 | 70 |
| 65 std::set<const WebRequestRule*> matches = GetMatches(request_data); | 71 std::set<const WebRequestRule*> matches = GetMatches(request_data); |
| 66 | 72 |
| 67 // Sort all matching rules by their priority so that they can be processed | 73 // Sort all matching rules by their priority so that they can be processed |
| 68 // in decreasing order. | 74 // in decreasing order. |
| 69 typedef std::pair<WebRequestRule::Priority, WebRequestRule::GlobalRuleId> | 75 typedef std::pair<WebRequestRule::Priority, WebRequestRule::GlobalRuleId> |
| 70 PriorityRuleIdPair; | 76 PriorityRuleIdPair; |
| (...skipping 29 matching lines...) Expand all Loading... |
| 100 const ExtensionId& extension_id = rule_id.first; | 106 const ExtensionId& extension_id = rule_id.first; |
| 101 const WebRequestRule* rule = webrequest_rules_[rule_id].get(); | 107 const WebRequestRule* rule = webrequest_rules_[rule_id].get(); |
| 102 CHECK(rule); | 108 CHECK(rule); |
| 103 | 109 |
| 104 // Skip rule if a previous rule of this extension instructed to ignore | 110 // Skip rule if a previous rule of this extension instructed to ignore |
| 105 // all rules with a lower priority than min_priorities[extension_id]. | 111 // all rules with a lower priority than min_priorities[extension_id]. |
| 106 int current_min_priority = min_priorities[extension_id]; | 112 int current_min_priority = min_priorities[extension_id]; |
| 107 if (priority_of_rule < current_min_priority) | 113 if (priority_of_rule < current_min_priority) |
| 108 continue; | 114 continue; |
| 109 | 115 |
| 110 std::list<LinkedPtrEventResponseDelta> rule_result = | 116 |
| 111 rule->CreateDeltas(extension_info_map, request_data, crosses_incognito); | 117 std::list<LinkedPtrEventResponseDelta> rule_result; |
| 118 WebRequestAction::ApplyInfo apply_info = { |
| 119 extension_info_map, request_data, crosses_incognito, &rule_result |
| 120 }; |
| 121 rule->Apply(&apply_info); |
| 112 result.splice(result.begin(), rule_result); | 122 result.splice(result.begin(), rule_result); |
| 113 | 123 |
| 114 min_priorities[extension_id] = std::max(current_min_priority, | 124 min_priorities[extension_id] = std::max(current_min_priority, |
| 115 rule->GetMinimumPriority()); | 125 rule->GetMinimumPriority()); |
| 116 } | 126 } |
| 117 return result; | 127 return result; |
| 118 } | 128 } |
| 119 | 129 |
| 120 std::string WebRequestRulesRegistry::AddRulesImpl( | 130 std::string WebRequestRulesRegistry::AddRulesImpl( |
| 121 const std::string& extension_id, | 131 const std::string& extension_id, |
| 122 const std::vector<linked_ptr<RulesRegistry::Rule> >& rules) { | 132 const std::vector<linked_ptr<RulesRegistry::Rule> >& rules) { |
| 123 base::Time extension_installation_time = | 133 base::Time extension_installation_time = |
| 124 GetExtensionInstallationTime(extension_id); | 134 GetExtensionInstallationTime(extension_id); |
| 125 | 135 |
| 126 std::string error; | 136 std::string error; |
| 127 RulesMap new_webrequest_rules; | 137 RulesMap new_webrequest_rules; |
| 128 | 138 |
| 129 for (std::vector<linked_ptr<RulesRegistry::Rule> >::const_iterator rule = | 139 for (std::vector<linked_ptr<RulesRegistry::Rule> >::const_iterator rule = |
| 130 rules.begin(); rule != rules.end(); ++rule) { | 140 rules.begin(); rule != rules.end(); ++rule) { |
| 131 WebRequestRule::GlobalRuleId rule_id(extension_id, *(*rule)->id); | 141 WebRequestRule::GlobalRuleId rule_id(extension_id, *(*rule)->id); |
| 132 DCHECK(webrequest_rules_.find(rule_id) == webrequest_rules_.end()); | 142 DCHECK(webrequest_rules_.find(rule_id) == webrequest_rules_.end()); |
| 133 | 143 |
| 134 scoped_ptr<WebRequestRule> webrequest_rule( | 144 scoped_ptr<WebRequestRule> webrequest_rule( |
| 135 WebRequestRule::Create(url_matcher_.condition_factory(), extension_id, | 145 WebRequestRule::Create(url_matcher_.condition_factory(), extension_id, |
| 136 extension_installation_time, *rule, &error)); | 146 extension_installation_time, *rule, |
| 147 &CheckConsistency, &error)); |
| 137 if (!error.empty()) { | 148 if (!error.empty()) { |
| 138 // We don't return here, because we want to clear temporary | 149 // We don't return here, because we want to clear temporary |
| 139 // condition sets in the url_matcher_. | 150 // condition sets in the url_matcher_. |
| 140 break; | 151 break; |
| 141 } | 152 } |
| 142 | 153 |
| 143 new_webrequest_rules[rule_id] = make_linked_ptr(webrequest_rule.release()); | 154 new_webrequest_rules[rule_id] = make_linked_ptr(webrequest_rule.release()); |
| 144 } | 155 } |
| 145 | 156 |
| 146 if (!error.empty()) { | 157 if (!error.empty()) { |
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 252 if (!extension_info_map_.get()) // May be NULL during testing. | 263 if (!extension_info_map_.get()) // May be NULL during testing. |
| 253 return base::Time(); | 264 return base::Time(); |
| 254 | 265 |
| 255 return extension_info_map_->GetInstallTime(extension_id); | 266 return extension_info_map_->GetInstallTime(extension_id); |
| 256 } | 267 } |
| 257 | 268 |
| 258 void WebRequestRulesRegistry::ClearCacheOnNavigation() { | 269 void WebRequestRulesRegistry::ClearCacheOnNavigation() { |
| 259 extension_web_request_api_helpers::ClearCacheOnNavigation(); | 270 extension_web_request_api_helpers::ClearCacheOnNavigation(); |
| 260 } | 271 } |
| 261 | 272 |
| 273 // static |
| 274 bool WebRequestRulesRegistry::CheckConsistency( |
| 275 const WebRequestConditionSet* conditions, |
| 276 const WebRequestActionSet* actions, |
| 277 std::string* error) { |
| 278 // Actions and conditions can be checked and executed in specific phases |
| 279 // of each web request. We consider a rule inconsistent if there is an action |
| 280 // that cannot be triggered by any condition. |
| 281 for (WebRequestActionSet::Actions::const_iterator action_iter = |
| 282 actions->actions().begin(); |
| 283 action_iter != actions->actions().end(); |
| 284 ++action_iter) { |
| 285 bool found_matching_condition = false; |
| 286 for (WebRequestConditionSet::Conditions::const_iterator condition_iter = |
| 287 conditions->conditions().begin(); |
| 288 condition_iter != conditions->conditions().end() && |
| 289 !found_matching_condition; |
| 290 ++condition_iter) { |
| 291 // Test the intersection of bit masks, this is intentionally & and not &&. |
| 292 if ((*action_iter)->GetStages() & (*condition_iter)->stages()) |
| 293 found_matching_condition = true; |
| 294 } |
| 295 if (!found_matching_condition) { |
| 296 *error = kActionCannotBeExecuted; |
| 297 return false; |
| 298 } |
| 299 } |
| 300 return true; |
| 301 } |
| 302 |
| 262 } // namespace extensions | 303 } // namespace extensions |
| OLD | NEW |