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 |