| 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> |
| 8 | 9 |
| 9 #include "chrome/browser/extensions/api/declarative_webrequest/webrequest_condit
ion.h" | 10 #include "chrome/browser/extensions/api/declarative_webrequest/webrequest_condit
ion.h" |
| 10 #include "chrome/browser/extensions/api/web_request/web_request_api_helpers.h" | 11 #include "chrome/browser/extensions/api/web_request/web_request_api_helpers.h" |
| 11 #include "chrome/browser/extensions/api/web_request/web_request_permissions.h" | 12 #include "chrome/browser/extensions/api/web_request/web_request_permissions.h" |
| 12 #include "chrome/browser/extensions/extension_system.h" | 13 #include "chrome/browser/extensions/extension_system.h" |
| 13 #include "net/url_request/url_request.h" | 14 #include "net/url_request/url_request.h" |
| 14 | 15 |
| 15 namespace extensions { | 16 namespace extensions { |
| 16 | 17 |
| 17 WebRequestRulesRegistry::WebRequestRulesRegistry(Profile* profile, | 18 WebRequestRulesRegistry::WebRequestRulesRegistry(Profile* profile, |
| 18 Delegate* delegate) | 19 Delegate* delegate) |
| 19 : RulesRegistryWithCache(delegate) { | 20 : RulesRegistryWithCache(delegate) { |
| 20 if (profile) | 21 if (profile) |
| 21 extension_info_map_ = ExtensionSystem::Get(profile)->info_map(); | 22 extension_info_map_ = ExtensionSystem::Get(profile)->info_map(); |
| 22 } | 23 } |
| 23 | 24 |
| 24 std::set<WebRequestRule::GlobalRuleId> | 25 std::set<WebRequestRule::GlobalRuleId> |
| 25 WebRequestRulesRegistry::GetMatches( | 26 WebRequestRulesRegistry::GetMatches( |
| 26 const WebRequestRule::RequestData& request_data) { | 27 const WebRequestRule::RequestData& request_data) { |
| 27 std::set<WebRequestRule::GlobalRuleId> result; | 28 std::set<WebRequestRule::GlobalRuleId> result; |
| 28 | 29 |
| 29 // Figure out for which rules the URL match conditions were fulfilled. | 30 // Figure out for which rules the URL match conditions were fulfilled. |
| 30 typedef std::set<URLMatcherConditionSet::ID> URLMatches; | 31 typedef std::set<URLMatcherConditionSet::ID> URLMatches; |
| 31 URLMatches url_matches = url_matcher_.MatchURL(request_data.request->url()); | 32 URLMatches url_matches = url_matcher_.MatchURL(request_data.request->url()); |
| 33 std::set<const WebRequestRule*> url_matched_rules; |
| 34 std::transform(url_matches.begin(), url_matches.end(), |
| 35 std::inserter(url_matched_rules, url_matched_rules.begin()), |
| 36 RuleTriggersOperator(rule_triggers_)); |
| 37 |
| 38 URLMatches first_party_url_matches = first_party_url_matcher_.MatchURL( |
| 39 request_data.request->first_party_for_cookies()); |
| 32 | 40 |
| 33 // Then we need to check for each of these, whether the other | 41 // Then we need to check for each of these, whether the other |
| 34 // WebRequestConditionAttributes are also fulfilled. | 42 // WebRequestConditionAttributes are also fulfilled. |
| 35 for (URLMatches::iterator url_match = url_matches.begin(); | 43 for (URLMatches::iterator url_match = first_party_url_matches.begin(); |
| 36 url_match != url_matches.end(); ++url_match) { | 44 url_match != first_party_url_matches.end(); ++url_match) { |
| 37 RuleTriggers::iterator rule_trigger = rule_triggers_.find(*url_match); | 45 RuleTriggers::iterator rule_trigger = rule_triggers_.find(*url_match); |
| 38 CHECK(rule_trigger != rule_triggers_.end()); | 46 CHECK(rule_trigger != rule_triggers_.end()); |
| 39 | 47 |
| 40 WebRequestRule* rule = rule_trigger->second; | 48 WebRequestRule* rule = rule_trigger->second; |
| 41 if (rule->conditions().IsFulfilled(*url_match, request_data)) | 49 // We already iterate over rules which have the first-party URL condition |
| 50 // satisfied. Now check that the request URL is also satisfied, and finally |
| 51 // check the rest of the attributes. |
| 52 if (url_matched_rules.find(rule) != url_matched_rules.end() && |
| 53 rule->conditions().IsFulfilled(*url_match, request_data)) |
| 42 result.insert(rule->id()); | 54 result.insert(rule->id()); |
| 43 } | 55 } |
| 44 return result; | 56 return result; |
| 45 } | 57 } |
| 46 | 58 |
| 47 std::list<LinkedPtrEventResponseDelta> WebRequestRulesRegistry::CreateDeltas( | 59 std::list<LinkedPtrEventResponseDelta> WebRequestRulesRegistry::CreateDeltas( |
| 48 const ExtensionInfoMap* extension_info_map, | 60 const ExtensionInfoMap* extension_info_map, |
| 49 const WebRequestRule::RequestData& request_data, | 61 const WebRequestRule::RequestData& request_data, |
| 50 bool crosses_incognito) { | 62 bool crosses_incognito) { |
| 51 if (webrequest_rules_.empty()) | 63 if (webrequest_rules_.empty()) |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 117 | 129 |
| 118 std::string error; | 130 std::string error; |
| 119 RulesMap new_webrequest_rules; | 131 RulesMap new_webrequest_rules; |
| 120 | 132 |
| 121 for (std::vector<linked_ptr<RulesRegistry::Rule> >::const_iterator rule = | 133 for (std::vector<linked_ptr<RulesRegistry::Rule> >::const_iterator rule = |
| 122 rules.begin(); rule != rules.end(); ++rule) { | 134 rules.begin(); rule != rules.end(); ++rule) { |
| 123 WebRequestRule::GlobalRuleId rule_id(extension_id, *(*rule)->id); | 135 WebRequestRule::GlobalRuleId rule_id(extension_id, *(*rule)->id); |
| 124 DCHECK(webrequest_rules_.find(rule_id) == webrequest_rules_.end()); | 136 DCHECK(webrequest_rules_.find(rule_id) == webrequest_rules_.end()); |
| 125 | 137 |
| 126 scoped_ptr<WebRequestRule> webrequest_rule( | 138 scoped_ptr<WebRequestRule> webrequest_rule( |
| 127 WebRequestRule::Create(url_matcher_.condition_factory(), extension_id, | 139 WebRequestRule::Create(url_matcher_.condition_factory(), |
| 140 first_party_url_matcher_.condition_factory(), |
| 141 extension_id, |
| 128 extension_installation_time, *rule, &error)); | 142 extension_installation_time, *rule, &error)); |
| 129 if (!error.empty()) { | 143 if (!error.empty()) { |
| 130 // We don't return here, because we want to clear temporary | 144 // We don't return here, because we want to clear temporary |
| 131 // condition sets in the url_matcher_. | 145 // condition sets in |url_matcher_| and |first_party_url_matcher_|. |
| 132 break; | 146 break; |
| 133 } | 147 } |
| 134 | 148 |
| 135 new_webrequest_rules[rule_id] = make_linked_ptr(webrequest_rule.release()); | 149 new_webrequest_rules[rule_id] = make_linked_ptr(webrequest_rule.release()); |
| 136 } | 150 } |
| 137 | 151 |
| 138 if (!error.empty()) { | 152 if (!error.empty()) { |
| 139 // Clean up temporary condition sets created during rule creation. | 153 // Clean up temporary condition sets created during rule creation. |
| 140 url_matcher_.ClearUnusedConditionSets(); | 154 url_matcher_.ClearUnusedConditionSets(); |
| 155 first_party_url_matcher_.ClearUnusedConditionSets(); |
| 141 return error; | 156 return error; |
| 142 } | 157 } |
| 143 | 158 |
| 144 // Wohoo, everything worked fine. | 159 // Wohoo, everything worked fine. |
| 145 webrequest_rules_.insert(new_webrequest_rules.begin(), | 160 webrequest_rules_.insert(new_webrequest_rules.begin(), |
| 146 new_webrequest_rules.end()); | 161 new_webrequest_rules.end()); |
| 147 | 162 |
| 148 // Create the triggers. | 163 // Create the triggers. |
| 149 for (RulesMap::iterator i = new_webrequest_rules.begin(); | 164 for (RulesMap::iterator i = new_webrequest_rules.begin(); |
| 150 i != new_webrequest_rules.end(); ++i) { | 165 i != new_webrequest_rules.end(); ++i) { |
| 151 URLMatcherConditionSet::Vector url_condition_sets; | 166 URLMatcherConditionSet::Vector url_condition_sets; |
| 152 const WebRequestConditionSet& conditions = i->second->conditions(); | 167 const WebRequestConditionSet& conditions = i->second->conditions(); |
| 153 conditions.GetURLMatcherConditionSets(&url_condition_sets); | 168 conditions.GetURLMatcherConditionSets(&url_condition_sets); |
| 169 conditions.GetFirstPartyURLMatcherConditionSets(&url_condition_sets); |
| 154 for (URLMatcherConditionSet::Vector::iterator j = | 170 for (URLMatcherConditionSet::Vector::iterator j = |
| 155 url_condition_sets.begin(); j != url_condition_sets.end(); ++j) { | 171 url_condition_sets.begin(); j != url_condition_sets.end(); ++j) { |
| 156 rule_triggers_[(*j)->id()] = i->second.get(); | 172 rule_triggers_[(*j)->id()] = i->second.get(); |
| 157 } | 173 } |
| 158 } | 174 } |
| 159 | 175 |
| 160 // Register url patterns in url_matcher_. | 176 // Register url patterns in |url_matcher_| and |first_party_url_matcher_|. |
| 161 URLMatcherConditionSet::Vector all_new_condition_sets; | 177 URLMatcherConditionSet::Vector all_new_condition_sets; |
| 178 URLMatcherConditionSet::Vector all_new_condition_sets_first_party; |
| 162 for (RulesMap::iterator i = new_webrequest_rules.begin(); | 179 for (RulesMap::iterator i = new_webrequest_rules.begin(); |
| 163 i != new_webrequest_rules.end(); ++i) { | 180 i != new_webrequest_rules.end(); ++i) { |
| 164 i->second->conditions().GetURLMatcherConditionSets(&all_new_condition_sets); | 181 i->second->conditions().GetURLMatcherConditionSets(&all_new_condition_sets); |
| 182 i->second->conditions().GetFirstPartyURLMatcherConditionSets( |
| 183 &all_new_condition_sets_first_party); |
| 165 } | 184 } |
| 166 url_matcher_.AddConditionSets(all_new_condition_sets); | 185 url_matcher_.AddConditionSets(all_new_condition_sets); |
| 186 first_party_url_matcher_.AddConditionSets(all_new_condition_sets_first_party); |
| 167 | 187 |
| 168 ClearCacheOnNavigation(); | 188 ClearCacheOnNavigation(); |
| 169 | 189 |
| 170 return ""; | 190 return ""; |
| 171 } | 191 } |
| 172 | 192 |
| 173 std::string WebRequestRulesRegistry::RemoveRulesImpl( | 193 std::string WebRequestRulesRegistry::RemoveRulesImpl( |
| 174 const std::string& extension_id, | 194 const std::string& extension_id, |
| 175 const std::vector<std::string>& rule_identifiers) { | 195 const std::vector<std::string>& rule_identifiers) { |
| 176 // URLMatcherConditionSet IDs that can be removed from URLMatcher. | 196 // URLMatcherConditionSet IDs that can be removed from URL matchers. |
| 177 std::vector<URLMatcherConditionSet::ID> remove_from_url_matcher; | 197 std::vector<URLMatcherConditionSet::ID> remove_from_url_matcher; |
| 198 std::vector<URLMatcherConditionSet::ID> remove_from_first_party_url_matcher; |
| 178 | 199 |
| 179 for (std::vector<std::string>::const_iterator i = rule_identifiers.begin(); | 200 for (std::vector<std::string>::const_iterator i = rule_identifiers.begin(); |
| 180 i != rule_identifiers.end(); ++i) { | 201 i != rule_identifiers.end(); ++i) { |
| 181 WebRequestRule::GlobalRuleId rule_id(extension_id, *i); | 202 WebRequestRule::GlobalRuleId rule_id(extension_id, *i); |
| 182 | 203 |
| 183 // Skip unknown rules. | 204 // Skip unknown rules. |
| 184 RulesMap::iterator webrequest_rules_entry = webrequest_rules_.find(rule_id); | 205 RulesMap::iterator webrequest_rules_entry = webrequest_rules_.find(rule_id); |
| 185 if (webrequest_rules_entry == webrequest_rules_.end()) | 206 if (webrequest_rules_entry == webrequest_rules_.end()) |
| 186 continue; | 207 continue; |
| 187 | 208 |
| 188 // Remove all triggers but collect their IDs. | 209 // Remove all triggers but collect their IDs. |
| 189 URLMatcherConditionSet::Vector condition_sets; | 210 URLMatcherConditionSet::Vector condition_sets; |
| 211 URLMatcherConditionSet::Vector condition_sets_first_party; |
| 190 WebRequestRule* rule = webrequest_rules_entry->second.get(); | 212 WebRequestRule* rule = webrequest_rules_entry->second.get(); |
| 191 rule->conditions().GetURLMatcherConditionSets(&condition_sets); | 213 rule->conditions().GetURLMatcherConditionSets(&condition_sets); |
| 214 rule->conditions().GetFirstPartyURLMatcherConditionSets( |
| 215 &condition_sets_first_party); |
| 192 for (URLMatcherConditionSet::Vector::iterator j = condition_sets.begin(); | 216 for (URLMatcherConditionSet::Vector::iterator j = condition_sets.begin(); |
| 193 j != condition_sets.end(); ++j) { | 217 j != condition_sets.end(); ++j) { |
| 194 remove_from_url_matcher.push_back((*j)->id()); | 218 remove_from_url_matcher.push_back((*j)->id()); |
| 195 rule_triggers_.erase((*j)->id()); | 219 rule_triggers_.erase((*j)->id()); |
| 196 } | 220 } |
| 221 for (URLMatcherConditionSet::Vector::iterator j = |
| 222 condition_sets_first_party.begin(); |
| 223 j != condition_sets_first_party.end(); ++j) { |
| 224 remove_from_first_party_url_matcher.push_back((*j)->id()); |
| 225 rule_triggers_.erase((*j)->id()); |
| 226 } |
| 197 | 227 |
| 198 // Remove reference to actual rule. | 228 // Remove reference to actual rule. |
| 199 webrequest_rules_.erase(webrequest_rules_entry); | 229 webrequest_rules_.erase(webrequest_rules_entry); |
| 200 } | 230 } |
| 201 | 231 |
| 202 // Clear URLMatcher based on condition_set_ids that are not needed any more. | 232 // Clear URL matchers based on condition_set_ids that are not needed any more. |
| 203 url_matcher_.RemoveConditionSets(remove_from_url_matcher); | 233 url_matcher_.RemoveConditionSets(remove_from_url_matcher); |
| 234 first_party_url_matcher_.RemoveConditionSets( |
| 235 remove_from_first_party_url_matcher); |
| 204 | 236 |
| 205 ClearCacheOnNavigation(); | 237 ClearCacheOnNavigation(); |
| 206 | 238 |
| 207 return ""; | 239 return ""; |
| 208 } | 240 } |
| 209 | 241 |
| 210 std::string WebRequestRulesRegistry::RemoveAllRulesImpl( | 242 std::string WebRequestRulesRegistry::RemoveAllRulesImpl( |
| 211 const std::string& extension_id) { | 243 const std::string& extension_id) { |
| 212 // Search all identifiers of rules that belong to extension |extension_id|. | 244 // Search all identifiers of rules that belong to extension |extension_id|. |
| 213 std::vector<std::string> rule_identifiers; | 245 std::vector<std::string> rule_identifiers; |
| 214 for (RulesMap::iterator i = webrequest_rules_.begin(); | 246 for (RulesMap::iterator i = webrequest_rules_.begin(); |
| 215 i != webrequest_rules_.end(); ++i) { | 247 i != webrequest_rules_.end(); ++i) { |
| 216 const WebRequestRule::GlobalRuleId& global_rule_id = i->first; | 248 const WebRequestRule::GlobalRuleId& global_rule_id = i->first; |
| 217 if (global_rule_id.first == extension_id) | 249 if (global_rule_id.first == extension_id) |
| 218 rule_identifiers.push_back(global_rule_id.second); | 250 rule_identifiers.push_back(global_rule_id.second); |
| 219 } | 251 } |
| 220 | 252 |
| 221 // No need to call ClearCacheOnNavigation() here because RemoveRulesImpl | 253 // No need to call ClearCacheOnNavigation() here because RemoveRulesImpl |
| 222 // takes care of that. | 254 // takes care of that. |
| 223 return RemoveRulesImpl(extension_id, rule_identifiers); | 255 return RemoveRulesImpl(extension_id, rule_identifiers); |
| 224 } | 256 } |
| 225 | 257 |
| 226 content::BrowserThread::ID WebRequestRulesRegistry::GetOwnerThread() const { | 258 content::BrowserThread::ID WebRequestRulesRegistry::GetOwnerThread() const { |
| 227 return content::BrowserThread::IO; | 259 return content::BrowserThread::IO; |
| 228 } | 260 } |
| 229 | 261 |
| 230 bool WebRequestRulesRegistry::IsEmpty() const { | 262 bool WebRequestRulesRegistry::IsEmpty() const { |
| 231 return rule_triggers_.empty() && webrequest_rules_.empty() && | 263 return rule_triggers_.empty() && webrequest_rules_.empty() && |
| 232 url_matcher_.IsEmpty(); | 264 url_matcher_.IsEmpty() && first_party_url_matcher_.IsEmpty(); |
| 233 } | 265 } |
| 234 | 266 |
| 235 WebRequestRulesRegistry::~WebRequestRulesRegistry() {} | 267 WebRequestRulesRegistry::~WebRequestRulesRegistry() {} |
| 236 | 268 |
| 237 base::Time WebRequestRulesRegistry::GetExtensionInstallationTime( | 269 base::Time WebRequestRulesRegistry::GetExtensionInstallationTime( |
| 238 const std::string& extension_id) const { | 270 const std::string& extension_id) const { |
| 239 if (!extension_info_map_.get()) // May be NULL during testing. | 271 if (!extension_info_map_.get()) // May be NULL during testing. |
| 240 return base::Time(); | 272 return base::Time(); |
| 241 | 273 |
| 242 return extension_info_map_->GetInstallTime(extension_id); | 274 return extension_info_map_->GetInstallTime(extension_id); |
| 243 } | 275 } |
| 244 | 276 |
| 245 void WebRequestRulesRegistry::ClearCacheOnNavigation() { | 277 void WebRequestRulesRegistry::ClearCacheOnNavigation() { |
| 246 extension_web_request_api_helpers::ClearCacheOnNavigation(); | 278 extension_web_request_api_helpers::ClearCacheOnNavigation(); |
| 247 } | 279 } |
| 248 | 280 |
| 281 WebRequestRulesRegistry::RuleTriggersOperator::RuleTriggersOperator( |
| 282 const RuleTriggers& triggers) |
| 283 : triggers_(triggers) { |
| 284 } |
| 285 |
| 286 WebRequestRulesRegistry::RuleTriggersOperator::~RuleTriggersOperator() { |
| 287 } |
| 288 |
| 249 } // namespace extensions | 289 } // namespace extensions |
| OLD | NEW |