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<WebRequestRule::GlobalRuleId> | 30 std::set<WebRequestRule::GlobalRuleId> |
25 WebRequestRulesRegistry::GetMatches( | 31 WebRequestRulesRegistry::GetMatches( |
26 const WebRequestRule::RequestData& request_data) { | 32 const DeclarativeWebRequestData& request_data) { |
27 std::set<WebRequestRule::GlobalRuleId> result; | 33 std::set<WebRequestRule::GlobalRuleId> result; |
28 | 34 |
29 // Figure out for which rules the URL match conditions were fulfilled. | 35 // Figure out for which rules the URL match conditions were fulfilled. |
30 typedef std::set<URLMatcherConditionSet::ID> URLMatches; | 36 typedef std::set<URLMatcherConditionSet::ID> URLMatches; |
31 URLMatches url_matches = url_matcher_.MatchURL(request_data.request->url()); | 37 URLMatches url_matches = url_matcher_.MatchURL(request_data.request->url()); |
32 | 38 |
33 // Then we need to check for each of these, whether the other | 39 // Then we need to check for each of these, whether the other |
34 // WebRequestConditionAttributes are also fulfilled. | 40 // WebRequestConditionAttributes are also fulfilled. |
35 for (URLMatches::iterator url_match = url_matches.begin(); | 41 for (URLMatches::iterator url_match = url_matches.begin(); |
36 url_match != url_matches.end(); ++url_match) { | 42 url_match != url_matches.end(); ++url_match) { |
37 RuleTriggers::iterator rule_trigger = rule_triggers_.find(*url_match); | 43 RuleTriggers::iterator rule_trigger = rule_triggers_.find(*url_match); |
38 CHECK(rule_trigger != rule_triggers_.end()); | 44 CHECK(rule_trigger != rule_triggers_.end()); |
39 | 45 |
40 WebRequestRule* rule = rule_trigger->second; | 46 WebRequestRule* rule = rule_trigger->second; |
41 if (rule->conditions().IsFulfilled(*url_match, request_data)) | 47 if (rule->conditions().IsFulfilled(*url_match, request_data)) |
42 result.insert(rule->id()); | 48 result.insert(rule->id()); |
43 } | 49 } |
44 return result; | 50 return result; |
45 } | 51 } |
46 | 52 |
47 std::list<LinkedPtrEventResponseDelta> WebRequestRulesRegistry::CreateDeltas( | 53 std::list<LinkedPtrEventResponseDelta> WebRequestRulesRegistry::CreateDeltas( |
48 const ExtensionInfoMap* extension_info_map, | 54 const ExtensionInfoMap* extension_info_map, |
49 const WebRequestRule::RequestData& request_data, | 55 const DeclarativeWebRequestData& request_data, |
50 bool crosses_incognito) { | 56 bool crosses_incognito) { |
51 if (webrequest_rules_.empty()) | 57 if (webrequest_rules_.empty()) |
52 return std::list<LinkedPtrEventResponseDelta>(); | 58 return std::list<LinkedPtrEventResponseDelta>(); |
53 | 59 |
54 std::set<WebRequestRule::GlobalRuleId> matches = | 60 std::set<WebRequestRule::GlobalRuleId> matches = |
55 GetMatches(request_data); | 61 GetMatches(request_data); |
56 | 62 |
57 // Sort all matching rules by their priority so that they can be processed | 63 // Sort all matching rules by their priority so that they can be processed |
58 // in decreasing order. | 64 // in decreasing order. |
59 typedef std::pair<WebRequestRule::Priority, WebRequestRule::GlobalRuleId> | 65 typedef std::pair<WebRequestRule::Priority, WebRequestRule::GlobalRuleId> |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
92 const ExtensionId& extension_id = rule_id.first; | 98 const ExtensionId& extension_id = rule_id.first; |
93 const WebRequestRule* rule = webrequest_rules_[rule_id].get(); | 99 const WebRequestRule* rule = webrequest_rules_[rule_id].get(); |
94 CHECK(rule); | 100 CHECK(rule); |
95 | 101 |
96 // Skip rule if a previous rule of this extension instructed to ignore | 102 // Skip rule if a previous rule of this extension instructed to ignore |
97 // all rules with a lower priority than min_priorities[extension_id]. | 103 // all rules with a lower priority than min_priorities[extension_id]. |
98 int current_min_priority = min_priorities[extension_id]; | 104 int current_min_priority = min_priorities[extension_id]; |
99 if (priority_of_rule < current_min_priority) | 105 if (priority_of_rule < current_min_priority) |
100 continue; | 106 continue; |
101 | 107 |
102 std::list<LinkedPtrEventResponseDelta> rule_result = | 108 |
103 rule->CreateDeltas(extension_info_map, request_data, crosses_incognito); | 109 std::list<LinkedPtrEventResponseDelta> rule_result; |
| 110 WebRequestAction::ApplyInfo apply_info = { |
| 111 extension_info_map, request_data, crosses_incognito, &rule_result |
| 112 }; |
| 113 rule->Apply(apply_info); |
104 result.splice(result.begin(), rule_result); | 114 result.splice(result.begin(), rule_result); |
105 | 115 |
106 min_priorities[extension_id] = std::max(current_min_priority, | 116 min_priorities[extension_id] = std::max(current_min_priority, |
107 rule->GetMinimumPriority()); | 117 rule->GetMinimumPriority()); |
108 } | 118 } |
109 return result; | 119 return result; |
110 } | 120 } |
111 | 121 |
112 std::string WebRequestRulesRegistry::AddRulesImpl( | 122 std::string WebRequestRulesRegistry::AddRulesImpl( |
113 const std::string& extension_id, | 123 const std::string& extension_id, |
114 const std::vector<linked_ptr<RulesRegistry::Rule> >& rules) { | 124 const std::vector<linked_ptr<RulesRegistry::Rule> >& rules) { |
115 base::Time extension_installation_time = | 125 base::Time extension_installation_time = |
116 GetExtensionInstallationTime(extension_id); | 126 GetExtensionInstallationTime(extension_id); |
117 | 127 |
118 std::string error; | 128 std::string error; |
119 RulesMap new_webrequest_rules; | 129 RulesMap new_webrequest_rules; |
120 | 130 |
121 for (std::vector<linked_ptr<RulesRegistry::Rule> >::const_iterator rule = | 131 for (std::vector<linked_ptr<RulesRegistry::Rule> >::const_iterator rule = |
122 rules.begin(); rule != rules.end(); ++rule) { | 132 rules.begin(); rule != rules.end(); ++rule) { |
123 WebRequestRule::GlobalRuleId rule_id(extension_id, *(*rule)->id); | 133 WebRequestRule::GlobalRuleId rule_id(extension_id, *(*rule)->id); |
124 DCHECK(webrequest_rules_.find(rule_id) == webrequest_rules_.end()); | 134 DCHECK(webrequest_rules_.find(rule_id) == webrequest_rules_.end()); |
125 | 135 |
126 scoped_ptr<WebRequestRule> webrequest_rule( | 136 scoped_ptr<WebRequestRule> webrequest_rule( |
127 WebRequestRule::Create(url_matcher_.condition_factory(), extension_id, | 137 WebRequestRule::Create(url_matcher_.condition_factory(), extension_id, |
128 extension_installation_time, *rule, &error)); | 138 extension_installation_time, *rule, |
| 139 &CheckConsistency, &error)); |
129 if (!error.empty()) { | 140 if (!error.empty()) { |
130 // We don't return here, because we want to clear temporary | 141 // We don't return here, because we want to clear temporary |
131 // condition sets in the url_matcher_. | 142 // condition sets in the url_matcher_. |
132 break; | 143 break; |
133 } | 144 } |
134 | 145 |
135 new_webrequest_rules[rule_id] = make_linked_ptr(webrequest_rule.release()); | 146 new_webrequest_rules[rule_id] = make_linked_ptr(webrequest_rule.release()); |
136 } | 147 } |
137 | 148 |
138 if (!error.empty()) { | 149 if (!error.empty()) { |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
239 if (!extension_info_map_.get()) // May be NULL during testing. | 250 if (!extension_info_map_.get()) // May be NULL during testing. |
240 return base::Time(); | 251 return base::Time(); |
241 | 252 |
242 return extension_info_map_->GetInstallTime(extension_id); | 253 return extension_info_map_->GetInstallTime(extension_id); |
243 } | 254 } |
244 | 255 |
245 void WebRequestRulesRegistry::ClearCacheOnNavigation() { | 256 void WebRequestRulesRegistry::ClearCacheOnNavigation() { |
246 extension_web_request_api_helpers::ClearCacheOnNavigation(); | 257 extension_web_request_api_helpers::ClearCacheOnNavigation(); |
247 } | 258 } |
248 | 259 |
| 260 // static |
| 261 bool WebRequestRulesRegistry::CheckConsistency( |
| 262 WebRequestConditionSet* conditions, |
| 263 WebRequestActionSet* actions, |
| 264 std::string* error) { |
| 265 // Actions and conditions can be checked and executed in specific phases |
| 266 // of each web request. We consider a rule inconsistent if there is an action |
| 267 // that cannot be triggered by any condition. |
| 268 for (WebRequestActionSet::Actions::const_iterator action_iter = |
| 269 actions->actions().begin(); |
| 270 action_iter != actions->actions().end(); |
| 271 ++action_iter) { |
| 272 bool found_matching_condition = false; |
| 273 for (WebRequestConditionSet::Conditions::const_iterator condition_iter = |
| 274 conditions->conditions().begin(); |
| 275 condition_iter != conditions->conditions().end() && |
| 276 !found_matching_condition; |
| 277 ++condition_iter) { |
| 278 // Test the intersection of bit masks, this is intentionally & and not &&. |
| 279 if ((*action_iter)->GetStages() & (*condition_iter)->stages()) |
| 280 found_matching_condition = true; |
| 281 } |
| 282 if (!found_matching_condition) { |
| 283 *error = kActionCannotBeExecuted; |
| 284 return false; |
| 285 } |
| 286 } |
| 287 return true; |
| 288 } |
| 289 |
249 } // namespace extensions | 290 } // namespace extensions |
OLD | NEW |