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 |