| 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 |
| (...skipping 19 matching lines...) Expand all Loading... |
| 30 extension_info_map_ = ExtensionSystem::Get(profile)->info_map(); | 30 extension_info_map_ = ExtensionSystem::Get(profile)->info_map(); |
| 31 } | 31 } |
| 32 | 32 |
| 33 std::set<const WebRequestRule*> | 33 std::set<const WebRequestRule*> |
| 34 WebRequestRulesRegistry::GetMatches( | 34 WebRequestRulesRegistry::GetMatches( |
| 35 const DeclarativeWebRequestData& request_data) { | 35 const DeclarativeWebRequestData& request_data) { |
| 36 typedef std::set<const WebRequestRule*> RuleSet; | 36 typedef std::set<const WebRequestRule*> RuleSet; |
| 37 typedef std::set<URLMatcherConditionSet::ID> URLMatches; | 37 typedef std::set<URLMatcherConditionSet::ID> URLMatches; |
| 38 | 38 |
| 39 RuleSet result; | 39 RuleSet result; |
| 40 |
| 40 URLMatches url_matches = url_matcher_.MatchURL(request_data.request->url()); | 41 URLMatches url_matches = url_matcher_.MatchURL(request_data.request->url()); |
| 42 URLMatches first_party = first_party_url_matcher_.MatchURL( |
| 43 request_data.request->first_party_for_cookies()); |
| 44 url_matches.insert(first_party.begin(), first_party.end()); |
| 41 | 45 |
| 42 // 1st phase -- add all rules with some conditions without UrlFilter | 46 // 1st phase -- add all rules with some conditions without UrlFilter |
| 43 // attributes. | 47 // attributes. |
| 44 for (RuleSet::const_iterator it = rules_with_untriggered_conditions_.begin(); | 48 for (RuleSet::const_iterator it = rules_with_untriggered_conditions_.begin(); |
| 45 it != rules_with_untriggered_conditions_.end(); ++it) { | 49 it != rules_with_untriggered_conditions_.end(); ++it) { |
| 46 if ((*it)->conditions().IsFulfilled(-1, url_matches, request_data)) | 50 if ((*it)->conditions().IsFulfilled(-1, url_matches, request_data)) |
| 47 result.insert(*it); | 51 result.insert(*it); |
| 48 } | 52 } |
| 49 | 53 |
| 50 // 2nd phase -- add all rules with some conditions triggered by URL matches. | 54 // 2nd phase -- add all rules with some conditions triggered by URL matches. |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 129 | 133 |
| 130 std::string WebRequestRulesRegistry::AddRulesImpl( | 134 std::string WebRequestRulesRegistry::AddRulesImpl( |
| 131 const std::string& extension_id, | 135 const std::string& extension_id, |
| 132 const std::vector<linked_ptr<RulesRegistry::Rule> >& rules) { | 136 const std::vector<linked_ptr<RulesRegistry::Rule> >& rules) { |
| 133 base::Time extension_installation_time = | 137 base::Time extension_installation_time = |
| 134 GetExtensionInstallationTime(extension_id); | 138 GetExtensionInstallationTime(extension_id); |
| 135 | 139 |
| 136 std::string error; | 140 std::string error; |
| 137 RulesMap new_webrequest_rules; | 141 RulesMap new_webrequest_rules; |
| 138 | 142 |
| 143 std::vector<URLMatcherConditionFactory*> factories; |
| 144 factories.push_back(url_matcher_.condition_factory()); |
| 145 factories.push_back(first_party_url_matcher_.condition_factory()); |
| 146 |
| 139 for (std::vector<linked_ptr<RulesRegistry::Rule> >::const_iterator rule = | 147 for (std::vector<linked_ptr<RulesRegistry::Rule> >::const_iterator rule = |
| 140 rules.begin(); rule != rules.end(); ++rule) { | 148 rules.begin(); rule != rules.end(); ++rule) { |
| 141 WebRequestRule::GlobalRuleId rule_id(extension_id, *(*rule)->id); | 149 WebRequestRule::GlobalRuleId rule_id(extension_id, *(*rule)->id); |
| 142 DCHECK(webrequest_rules_.find(rule_id) == webrequest_rules_.end()); | 150 DCHECK(webrequest_rules_.find(rule_id) == webrequest_rules_.end()); |
| 143 | 151 |
| 144 scoped_ptr<WebRequestRule> webrequest_rule( | 152 scoped_ptr<WebRequestRule> webrequest_rule( |
| 145 WebRequestRule::Create(url_matcher_.condition_factory(), extension_id, | 153 WebRequestRule::Create(factories, |
| 146 extension_installation_time, *rule, | 154 extension_id, extension_installation_time, |
| 147 &CheckConsistency, &error)); | 155 *rule, &CheckConsistency, &error)); |
| 148 if (!error.empty()) { | 156 if (!error.empty()) { |
| 149 // We don't return here, because we want to clear temporary | 157 // We don't return here, because we want to clear temporary |
| 150 // condition sets in the url_matcher_. | 158 // condition sets in |url_matcher_| and |first_party_url_matcher_|. |
| 151 break; | 159 break; |
| 152 } | 160 } |
| 153 | 161 |
| 154 new_webrequest_rules[rule_id] = make_linked_ptr(webrequest_rule.release()); | 162 new_webrequest_rules[rule_id] = make_linked_ptr(webrequest_rule.release()); |
| 155 } | 163 } |
| 156 | 164 |
| 157 if (!error.empty()) { | 165 if (!error.empty()) { |
| 158 // Clean up temporary condition sets created during rule creation. | 166 // Clean up temporary condition sets created during rule creation. |
| 159 url_matcher_.ClearUnusedConditionSets(); | 167 url_matcher_.ClearUnusedConditionSets(); |
| 168 first_party_url_matcher_.ClearUnusedConditionSets(); |
| 160 return error; | 169 return error; |
| 161 } | 170 } |
| 162 | 171 |
| 163 // Wohoo, everything worked fine. | 172 // Wohoo, everything worked fine. |
| 164 webrequest_rules_.insert(new_webrequest_rules.begin(), | 173 webrequest_rules_.insert(new_webrequest_rules.begin(), |
| 165 new_webrequest_rules.end()); | 174 new_webrequest_rules.end()); |
| 166 | 175 |
| 167 // Create the triggers. | 176 // Create the triggers. |
| 168 for (RulesMap::iterator i = new_webrequest_rules.begin(); | 177 for (RulesMap::iterator i = new_webrequest_rules.begin(); |
| 169 i != new_webrequest_rules.end(); ++i) { | 178 i != new_webrequest_rules.end(); ++i) { |
| 170 URLMatcherConditionSet::Vector url_condition_sets; | 179 URLMatcherConditionSet::Vector url_condition_sets; |
| 171 const WebRequestConditionSet& conditions = i->second->conditions(); | 180 const WebRequestConditionSet& conditions = i->second->conditions(); |
| 172 conditions.GetURLMatcherConditionSets(&url_condition_sets); | 181 conditions.GetURLMatcherConditionSets(&url_condition_sets, 0); |
| 182 conditions.GetURLMatcherConditionSets(&url_condition_sets, 1); |
| 173 for (URLMatcherConditionSet::Vector::iterator j = | 183 for (URLMatcherConditionSet::Vector::iterator j = |
| 174 url_condition_sets.begin(); j != url_condition_sets.end(); ++j) { | 184 url_condition_sets.begin(); j != url_condition_sets.end(); ++j) { |
| 175 rule_triggers_[(*j)->id()] = i->second.get(); | 185 rule_triggers_[(*j)->id()] = i->second.get(); |
| 176 } | 186 } |
| 177 } | 187 } |
| 178 | 188 |
| 179 // Register url patterns in |url_matcher_| and | 189 // Register url patterns with both URL matchers and |
| 180 // |rules_with_untriggered_conditions_|. | 190 // |rules_with_untriggered_conditions_|. |
| 181 URLMatcherConditionSet::Vector all_new_condition_sets; | 191 URLMatcherConditionSet::Vector all_new_condition_sets; |
| 192 URLMatcherConditionSet::Vector all_new_condition_sets_first_party; |
| 182 for (RulesMap::iterator i = new_webrequest_rules.begin(); | 193 for (RulesMap::iterator i = new_webrequest_rules.begin(); |
| 183 i != new_webrequest_rules.end(); ++i) { | 194 i != new_webrequest_rules.end(); ++i) { |
| 184 i->second->conditions().GetURLMatcherConditionSets(&all_new_condition_sets); | 195 i->second->conditions().GetURLMatcherConditionSets( |
| 196 &all_new_condition_sets, 0); |
| 197 i->second->conditions().GetURLMatcherConditionSets( |
| 198 &all_new_condition_sets_first_party, 1); |
| 185 if (i->second->conditions().HasConditionsWithoutUrls()) | 199 if (i->second->conditions().HasConditionsWithoutUrls()) |
| 186 rules_with_untriggered_conditions_.insert(i->second.get()); | 200 rules_with_untriggered_conditions_.insert(i->second.get()); |
| 187 } | 201 } |
| 188 url_matcher_.AddConditionSets(all_new_condition_sets); | 202 url_matcher_.AddConditionSets(all_new_condition_sets); |
| 203 first_party_url_matcher_.AddConditionSets(all_new_condition_sets_first_party); |
| 189 | 204 |
| 190 ClearCacheOnNavigation(); | 205 ClearCacheOnNavigation(); |
| 191 | 206 |
| 192 return ""; | 207 return ""; |
| 193 } | 208 } |
| 194 | 209 |
| 195 std::string WebRequestRulesRegistry::RemoveRulesImpl( | 210 std::string WebRequestRulesRegistry::RemoveRulesImpl( |
| 196 const std::string& extension_id, | 211 const std::string& extension_id, |
| 197 const std::vector<std::string>& rule_identifiers) { | 212 const std::vector<std::string>& rule_identifiers) { |
| 198 // URLMatcherConditionSet IDs that can be removed from URLMatcher. | 213 // URLMatcherConditionSet IDs that can be removed from URL matchers. |
| 199 std::vector<URLMatcherConditionSet::ID> remove_from_url_matcher; | 214 std::vector<URLMatcherConditionSet::ID> remove_from_url_matcher; |
| 215 std::vector<URLMatcherConditionSet::ID> remove_from_first_party_url_matcher; |
| 200 | 216 |
| 201 for (std::vector<std::string>::const_iterator i = rule_identifiers.begin(); | 217 for (std::vector<std::string>::const_iterator i = rule_identifiers.begin(); |
| 202 i != rule_identifiers.end(); ++i) { | 218 i != rule_identifiers.end(); ++i) { |
| 203 WebRequestRule::GlobalRuleId rule_id(extension_id, *i); | 219 WebRequestRule::GlobalRuleId rule_id(extension_id, *i); |
| 204 | 220 |
| 205 // Skip unknown rules. | 221 // Skip unknown rules. |
| 206 RulesMap::iterator webrequest_rules_entry = webrequest_rules_.find(rule_id); | 222 RulesMap::iterator webrequest_rules_entry = webrequest_rules_.find(rule_id); |
| 207 if (webrequest_rules_entry == webrequest_rules_.end()) | 223 if (webrequest_rules_entry == webrequest_rules_.end()) |
| 208 continue; | 224 continue; |
| 209 | 225 |
| 210 // Remove all triggers but collect their IDs. | 226 // Remove all triggers but collect their IDs. |
| 211 URLMatcherConditionSet::Vector condition_sets; | 227 URLMatcherConditionSet::Vector condition_sets; |
| 228 URLMatcherConditionSet::Vector condition_sets_first_party; |
| 212 WebRequestRule* rule = webrequest_rules_entry->second.get(); | 229 WebRequestRule* rule = webrequest_rules_entry->second.get(); |
| 213 rule->conditions().GetURLMatcherConditionSets(&condition_sets); | 230 rule->conditions().GetURLMatcherConditionSets(&condition_sets, 0); |
| 231 rule->conditions().GetURLMatcherConditionSets( |
| 232 &condition_sets_first_party, 1); |
| 214 for (URLMatcherConditionSet::Vector::iterator j = condition_sets.begin(); | 233 for (URLMatcherConditionSet::Vector::iterator j = condition_sets.begin(); |
| 215 j != condition_sets.end(); ++j) { | 234 j != condition_sets.end(); ++j) { |
| 216 remove_from_url_matcher.push_back((*j)->id()); | 235 remove_from_url_matcher.push_back((*j)->id()); |
| 217 rule_triggers_.erase((*j)->id()); | 236 rule_triggers_.erase((*j)->id()); |
| 218 } | 237 } |
| 238 for (URLMatcherConditionSet::Vector::iterator j = |
| 239 condition_sets_first_party.begin(); |
| 240 j != condition_sets_first_party.end(); ++j) { |
| 241 remove_from_first_party_url_matcher.push_back((*j)->id()); |
| 242 rule_triggers_.erase((*j)->id()); |
| 243 } |
| 219 | 244 |
| 220 rules_with_untriggered_conditions_.erase(rule); | 245 rules_with_untriggered_conditions_.erase(rule); |
| 221 | 246 |
| 222 // Removes the owning references to (and thus deletes) the rule. | 247 // Removes the owning references to (and thus deletes) the rule. |
| 223 webrequest_rules_.erase(webrequest_rules_entry); | 248 webrequest_rules_.erase(webrequest_rules_entry); |
| 224 } | 249 } |
| 225 | 250 |
| 226 // Clear URLMatcher based on condition_set_ids that are not needed any more. | 251 // Clear URL matchers based on condition_set_ids that are not needed any more. |
| 227 url_matcher_.RemoveConditionSets(remove_from_url_matcher); | 252 url_matcher_.RemoveConditionSets(remove_from_url_matcher); |
| 253 first_party_url_matcher_.RemoveConditionSets( |
| 254 remove_from_first_party_url_matcher); |
| 228 | 255 |
| 229 ClearCacheOnNavigation(); | 256 ClearCacheOnNavigation(); |
| 230 | 257 |
| 231 return ""; | 258 return ""; |
| 232 } | 259 } |
| 233 | 260 |
| 234 std::string WebRequestRulesRegistry::RemoveAllRulesImpl( | 261 std::string WebRequestRulesRegistry::RemoveAllRulesImpl( |
| 235 const std::string& extension_id) { | 262 const std::string& extension_id) { |
| 236 // Search all identifiers of rules that belong to extension |extension_id|. | 263 // Search all identifiers of rules that belong to extension |extension_id|. |
| 237 std::vector<std::string> rule_identifiers; | 264 std::vector<std::string> rule_identifiers; |
| 238 for (RulesMap::iterator i = webrequest_rules_.begin(); | 265 for (RulesMap::iterator i = webrequest_rules_.begin(); |
| 239 i != webrequest_rules_.end(); ++i) { | 266 i != webrequest_rules_.end(); ++i) { |
| 240 const WebRequestRule::GlobalRuleId& global_rule_id = i->first; | 267 const WebRequestRule::GlobalRuleId& global_rule_id = i->first; |
| 241 if (global_rule_id.first == extension_id) | 268 if (global_rule_id.first == extension_id) |
| 242 rule_identifiers.push_back(global_rule_id.second); | 269 rule_identifiers.push_back(global_rule_id.second); |
| 243 } | 270 } |
| 244 | 271 |
| 245 // No need to call ClearCacheOnNavigation() here because RemoveRulesImpl | 272 // No need to call ClearCacheOnNavigation() here because RemoveRulesImpl |
| 246 // takes care of that. | 273 // takes care of that. |
| 247 return RemoveRulesImpl(extension_id, rule_identifiers); | 274 return RemoveRulesImpl(extension_id, rule_identifiers); |
| 248 } | 275 } |
| 249 | 276 |
| 250 content::BrowserThread::ID WebRequestRulesRegistry::GetOwnerThread() const { | 277 content::BrowserThread::ID WebRequestRulesRegistry::GetOwnerThread() const { |
| 251 return content::BrowserThread::IO; | 278 return content::BrowserThread::IO; |
| 252 } | 279 } |
| 253 | 280 |
| 254 bool WebRequestRulesRegistry::IsEmpty() const { | 281 bool WebRequestRulesRegistry::IsEmpty() const { |
| 255 return rule_triggers_.empty() && webrequest_rules_.empty() && | 282 return rule_triggers_.empty() && webrequest_rules_.empty() && |
| 256 url_matcher_.IsEmpty(); | 283 url_matcher_.IsEmpty() && first_party_url_matcher_.IsEmpty(); |
| 257 } | 284 } |
| 258 | 285 |
| 259 WebRequestRulesRegistry::~WebRequestRulesRegistry() {} | 286 WebRequestRulesRegistry::~WebRequestRulesRegistry() {} |
| 260 | 287 |
| 261 base::Time WebRequestRulesRegistry::GetExtensionInstallationTime( | 288 base::Time WebRequestRulesRegistry::GetExtensionInstallationTime( |
| 262 const std::string& extension_id) const { | 289 const std::string& extension_id) const { |
| 263 if (!extension_info_map_.get()) // May be NULL during testing. | 290 if (!extension_info_map_.get()) // May be NULL during testing. |
| 264 return base::Time(); | 291 return base::Time(); |
| 265 | 292 |
| 266 return extension_info_map_->GetInstallTime(extension_id); | 293 return extension_info_map_->GetInstallTime(extension_id); |
| (...skipping 27 matching lines...) Expand all Loading... |
| 294 } | 321 } |
| 295 if (!found_matching_condition) { | 322 if (!found_matching_condition) { |
| 296 *error = kActionCannotBeExecuted; | 323 *error = kActionCannotBeExecuted; |
| 297 return false; | 324 return false; |
| 298 } | 325 } |
| 299 } | 326 } |
| 300 return true; | 327 return true; |
| 301 } | 328 } |
| 302 | 329 |
| 303 } // namespace extensions | 330 } // namespace extensions |
| OLD | NEW |