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