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 <limits> | 8 #include <limits> |
| 9 #include <utility> |
8 | 10 |
| 11 #include "base/stl_util.h" |
9 #include "chrome/browser/extensions/api/declarative_webrequest/webrequest_condit
ion.h" | 12 #include "chrome/browser/extensions/api/declarative_webrequest/webrequest_condit
ion.h" |
10 #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" |
11 #include "chrome/browser/extensions/api/web_request/web_request_permissions.h" | 14 #include "chrome/browser/extensions/api/web_request/web_request_permissions.h" |
12 #include "chrome/browser/extensions/extension_system.h" | 15 #include "chrome/browser/extensions/extension_system.h" |
13 #include "net/url_request/url_request.h" | 16 #include "net/url_request/url_request.h" |
14 | 17 |
15 namespace extensions { | 18 namespace extensions { |
16 | 19 |
17 WebRequestRulesRegistry::WebRequestRulesRegistry(Profile* profile, | 20 WebRequestRulesRegistry::WebRequestRulesRegistry(Profile* profile, |
18 Delegate* delegate) | 21 Delegate* delegate) |
19 : RulesRegistryWithCache(delegate) { | 22 : RulesRegistryWithCache(delegate) { |
20 if (profile) | 23 if (profile) |
21 extension_info_map_ = ExtensionSystem::Get(profile)->info_map(); | 24 extension_info_map_ = ExtensionSystem::Get(profile)->info_map(); |
22 } | 25 } |
23 | 26 |
24 std::set<WebRequestRule::GlobalRuleId> | 27 std::set<const WebRequestRule*> |
25 WebRequestRulesRegistry::GetMatches( | 28 WebRequestRulesRegistry::GetMatches( |
26 const WebRequestRule::RequestData& request_data) { | 29 const WebRequestRule::RequestData& request_data) { |
27 std::set<WebRequestRule::GlobalRuleId> result; | 30 typedef std::set<const WebRequestRule*> RuleSet; |
| 31 typedef std::set<URLMatcherConditionSet::ID> URLMatches; |
28 | 32 |
29 // Figure out for which rules the URL match conditions were fulfilled. | 33 RuleSet result; |
30 typedef std::set<URLMatcherConditionSet::ID> URLMatches; | |
31 URLMatches url_matches = url_matcher_.MatchURL(request_data.request->url()); | 34 URLMatches url_matches = url_matcher_.MatchURL(request_data.request->url()); |
32 | 35 |
33 // Then we need to check for each of these, whether the other | 36 // 1st phase -- add all rules with some conditions without UrlFilter |
34 // WebRequestConditionAttributes are also fulfilled. | 37 // attributes. |
35 for (URLMatches::iterator url_match = url_matches.begin(); | 38 for (RuleSet::const_iterator it = rules_with_untriggered_conditions_.begin(); |
| 39 it != rules_with_untriggered_conditions_.end(); ++it) { |
| 40 if ((*it)->conditions().IsFulfilled(-1, url_matches, request_data)) |
| 41 result.insert(*it); |
| 42 } |
| 43 |
| 44 // 2nd phase -- add all rules with some conditions triggered by URL matches. |
| 45 for (URLMatches::const_iterator url_match = url_matches.begin(); |
36 url_match != url_matches.end(); ++url_match) { | 46 url_match != url_matches.end(); ++url_match) { |
37 RuleTriggers::iterator rule_trigger = rule_triggers_.find(*url_match); | 47 RuleTriggers::const_iterator rule_trigger = rule_triggers_.find(*url_match); |
38 CHECK(rule_trigger != rule_triggers_.end()); | 48 CHECK(rule_trigger != rule_triggers_.end()); |
| 49 if (!ContainsKey(result, rule_trigger->second) && |
| 50 rule_trigger->second->conditions().IsFulfilled(*url_match, url_matches, |
| 51 request_data)) |
| 52 result.insert(rule_trigger->second); |
| 53 } |
39 | 54 |
40 WebRequestRule* rule = rule_trigger->second; | |
41 if (rule->conditions().IsFulfilled(*url_match, request_data)) | |
42 result.insert(rule->id()); | |
43 } | |
44 return result; | 55 return result; |
45 } | 56 } |
46 | 57 |
47 std::list<LinkedPtrEventResponseDelta> WebRequestRulesRegistry::CreateDeltas( | 58 std::list<LinkedPtrEventResponseDelta> WebRequestRulesRegistry::CreateDeltas( |
48 const ExtensionInfoMap* extension_info_map, | 59 const ExtensionInfoMap* extension_info_map, |
49 const WebRequestRule::RequestData& request_data, | 60 const WebRequestRule::RequestData& request_data, |
50 bool crosses_incognito) { | 61 bool crosses_incognito) { |
51 if (webrequest_rules_.empty()) | 62 if (webrequest_rules_.empty()) |
52 return std::list<LinkedPtrEventResponseDelta>(); | 63 return std::list<LinkedPtrEventResponseDelta>(); |
53 | 64 |
54 std::set<WebRequestRule::GlobalRuleId> matches = | 65 std::set<const WebRequestRule*> matches = GetMatches(request_data); |
55 GetMatches(request_data); | |
56 | 66 |
57 // Sort all matching rules by their priority so that they can be processed | 67 // Sort all matching rules by their priority so that they can be processed |
58 // in decreasing order. | 68 // in decreasing order. |
59 typedef std::pair<WebRequestRule::Priority, WebRequestRule::GlobalRuleId> | 69 typedef std::pair<WebRequestRule::Priority, WebRequestRule::GlobalRuleId> |
60 PriorityRuleIdPair; | 70 PriorityRuleIdPair; |
61 std::vector<PriorityRuleIdPair> ordered_matches; | 71 std::vector<PriorityRuleIdPair> ordered_matches; |
62 ordered_matches.reserve(matches.size()); | 72 ordered_matches.reserve(matches.size()); |
63 for (std::set<WebRequestRule::GlobalRuleId>::iterator i = matches.begin(); | 73 for (std::set<const WebRequestRule*>::iterator i = matches.begin(); |
64 i != matches.end(); ++i) { | 74 i != matches.end(); ++i) { |
65 RulesMap::const_iterator rule = webrequest_rules_.find(*i); | 75 ordered_matches.push_back(make_pair((*i)->priority(), (*i)->id())); |
66 CHECK(rule != webrequest_rules_.end()); | |
67 ordered_matches.push_back(make_pair(rule->second->priority(), *i)); | |
68 } | 76 } |
69 // Sort from rbegin to rend in order to get descending priority order. | 77 // Sort from rbegin to rend in order to get descending priority order. |
70 std::sort(ordered_matches.rbegin(), ordered_matches.rend()); | 78 std::sort(ordered_matches.rbegin(), ordered_matches.rend()); |
71 | 79 |
72 // Build a map that maps each extension id to the minimum required priority | 80 // Build a map that maps each extension id to the minimum required priority |
73 // for rules of that extension. Initially, this priority is -infinite and | 81 // for rules of that extension. Initially, this priority is -infinite and |
74 // will be increased when the rules are processed and raise the bar via | 82 // will be increased when the rules are processed and raise the bar via |
75 // WebRequestIgnoreRulesActions. | 83 // WebRequestIgnoreRulesActions. |
76 typedef std::string ExtensionId; | 84 typedef std::string ExtensionId; |
77 typedef std::map<ExtensionId, WebRequestRule::Priority> MinPriorities; | 85 typedef std::map<ExtensionId, WebRequestRule::Priority> MinPriorities; |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
150 i != new_webrequest_rules.end(); ++i) { | 158 i != new_webrequest_rules.end(); ++i) { |
151 URLMatcherConditionSet::Vector url_condition_sets; | 159 URLMatcherConditionSet::Vector url_condition_sets; |
152 const WebRequestConditionSet& conditions = i->second->conditions(); | 160 const WebRequestConditionSet& conditions = i->second->conditions(); |
153 conditions.GetURLMatcherConditionSets(&url_condition_sets); | 161 conditions.GetURLMatcherConditionSets(&url_condition_sets); |
154 for (URLMatcherConditionSet::Vector::iterator j = | 162 for (URLMatcherConditionSet::Vector::iterator j = |
155 url_condition_sets.begin(); j != url_condition_sets.end(); ++j) { | 163 url_condition_sets.begin(); j != url_condition_sets.end(); ++j) { |
156 rule_triggers_[(*j)->id()] = i->second.get(); | 164 rule_triggers_[(*j)->id()] = i->second.get(); |
157 } | 165 } |
158 } | 166 } |
159 | 167 |
160 // Register url patterns in url_matcher_. | 168 // Register url patterns in |url_matcher_| and |
| 169 // |rules_with_untriggered_conditions_|. |
161 URLMatcherConditionSet::Vector all_new_condition_sets; | 170 URLMatcherConditionSet::Vector all_new_condition_sets; |
162 for (RulesMap::iterator i = new_webrequest_rules.begin(); | 171 for (RulesMap::iterator i = new_webrequest_rules.begin(); |
163 i != new_webrequest_rules.end(); ++i) { | 172 i != new_webrequest_rules.end(); ++i) { |
164 i->second->conditions().GetURLMatcherConditionSets(&all_new_condition_sets); | 173 i->second->conditions().GetURLMatcherConditionSets(&all_new_condition_sets); |
| 174 if (i->second->conditions().HasConditionsWithoutUrls()) |
| 175 rules_with_untriggered_conditions_.insert(i->second.get()); |
165 } | 176 } |
166 url_matcher_.AddConditionSets(all_new_condition_sets); | 177 url_matcher_.AddConditionSets(all_new_condition_sets); |
167 | 178 |
168 ClearCacheOnNavigation(); | 179 ClearCacheOnNavigation(); |
169 | 180 |
170 return ""; | 181 return ""; |
171 } | 182 } |
172 | 183 |
173 std::string WebRequestRulesRegistry::RemoveRulesImpl( | 184 std::string WebRequestRulesRegistry::RemoveRulesImpl( |
174 const std::string& extension_id, | 185 const std::string& extension_id, |
(...skipping 13 matching lines...) Expand all Loading... |
188 // Remove all triggers but collect their IDs. | 199 // Remove all triggers but collect their IDs. |
189 URLMatcherConditionSet::Vector condition_sets; | 200 URLMatcherConditionSet::Vector condition_sets; |
190 WebRequestRule* rule = webrequest_rules_entry->second.get(); | 201 WebRequestRule* rule = webrequest_rules_entry->second.get(); |
191 rule->conditions().GetURLMatcherConditionSets(&condition_sets); | 202 rule->conditions().GetURLMatcherConditionSets(&condition_sets); |
192 for (URLMatcherConditionSet::Vector::iterator j = condition_sets.begin(); | 203 for (URLMatcherConditionSet::Vector::iterator j = condition_sets.begin(); |
193 j != condition_sets.end(); ++j) { | 204 j != condition_sets.end(); ++j) { |
194 remove_from_url_matcher.push_back((*j)->id()); | 205 remove_from_url_matcher.push_back((*j)->id()); |
195 rule_triggers_.erase((*j)->id()); | 206 rule_triggers_.erase((*j)->id()); |
196 } | 207 } |
197 | 208 |
198 // Remove reference to actual rule. | 209 rules_with_untriggered_conditions_.erase(rule); |
| 210 |
| 211 // Removes the owning references to (and thus deletes) the rule. |
199 webrequest_rules_.erase(webrequest_rules_entry); | 212 webrequest_rules_.erase(webrequest_rules_entry); |
200 } | 213 } |
201 | 214 |
202 // Clear URLMatcher based on condition_set_ids that are not needed any more. | 215 // Clear URLMatcher based on condition_set_ids that are not needed any more. |
203 url_matcher_.RemoveConditionSets(remove_from_url_matcher); | 216 url_matcher_.RemoveConditionSets(remove_from_url_matcher); |
204 | 217 |
205 ClearCacheOnNavigation(); | 218 ClearCacheOnNavigation(); |
206 | 219 |
207 return ""; | 220 return ""; |
208 } | 221 } |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
240 return base::Time(); | 253 return base::Time(); |
241 | 254 |
242 return extension_info_map_->GetInstallTime(extension_id); | 255 return extension_info_map_->GetInstallTime(extension_id); |
243 } | 256 } |
244 | 257 |
245 void WebRequestRulesRegistry::ClearCacheOnNavigation() { | 258 void WebRequestRulesRegistry::ClearCacheOnNavigation() { |
246 extension_web_request_api_helpers::ClearCacheOnNavigation(); | 259 extension_web_request_api_helpers::ClearCacheOnNavigation(); |
247 } | 260 } |
248 | 261 |
249 } // namespace extensions | 262 } // namespace extensions |
OLD | NEW |