| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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 "components/url_matcher/url_matcher.h" | 5 #include "components/url_matcher/url_matcher.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <iterator> | 8 #include <iterator> |
| 9 | 9 |
| 10 #include "base/logging.h" | 10 #include "base/logging.h" |
| (...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 189 return false; | 189 return false; |
| 190 } | 190 } |
| 191 | 191 |
| 192 bool URLMatcherCondition::IsFullURLCondition() const { | 192 bool URLMatcherCondition::IsFullURLCondition() const { |
| 193 // For these criteria the SubstringMatcher needs to be executed on the | 193 // For these criteria the SubstringMatcher needs to be executed on the |
| 194 // GURL that is canonicalized with | 194 // GURL that is canonicalized with |
| 195 // URLMatcherConditionFactory::CanonicalizeURLForFullSearches. | 195 // URLMatcherConditionFactory::CanonicalizeURLForFullSearches. |
| 196 switch (criterion_) { | 196 switch (criterion_) { |
| 197 case HOST_CONTAINS: | 197 case HOST_CONTAINS: |
| 198 case PATH_CONTAINS: | 198 case PATH_CONTAINS: |
| 199 case QUERY_CONTAINS: | |
| 200 case URL_PREFIX: | 199 case URL_PREFIX: |
| 201 case URL_SUFFIX: | 200 case URL_SUFFIX: |
| 202 case URL_CONTAINS: | 201 case URL_CONTAINS: |
| 203 case URL_EQUALS: | 202 case URL_EQUALS: |
| 204 return true; | 203 return true; |
| 205 default: | 204 default: |
| 206 break; | 205 break; |
| 207 } | 206 } |
| 208 return false; | 207 return false; |
| 209 } | 208 } |
| 210 | 209 |
| 211 bool URLMatcherCondition::IsRegexCondition() const { | 210 bool URLMatcherCondition::IsRegexCondition() const { |
| 212 return IsRegexCriterion(criterion_); | 211 return IsRegexCriterion(criterion_); |
| 213 } | 212 } |
| 214 | 213 |
| 215 bool URLMatcherCondition::IsOriginAndPathRegexCondition() const { | 214 bool URLMatcherCondition::IsOriginAndPathRegexCondition() const { |
| 216 return IsOriginAndPathRegexCriterion(criterion_); | 215 return IsOriginAndPathRegexCriterion(criterion_); |
| 217 } | 216 } |
| 218 | 217 |
| 219 bool URLMatcherCondition::IsMatch( | 218 bool URLMatcherCondition::IsMatch( |
| 220 const std::set<StringPattern::ID>& matching_patterns, | 219 const std::set<StringPattern::ID>& matching_patterns, |
| 221 const GURL& url) const { | 220 const GURL& url) const { |
| 222 DCHECK(string_pattern_); | 221 DCHECK(string_pattern_); |
| 223 if (!ContainsKey(matching_patterns, string_pattern_->id())) | 222 if (!ContainsKey(matching_patterns, string_pattern_->id())) |
| 224 return false; | 223 return false; |
| 225 // The criteria HOST_CONTAINS, PATH_CONTAINS, QUERY_CONTAINS are based on | 224 // The criteria HOST_CONTAINS, PATH_CONTAINS are based on a substring match on |
| 226 // a substring match on the raw URL. In case of a match, we need to verify | 225 // the raw URL. In case of a match, we need to verify that the match was found |
| 227 // that the match was found in the correct component of the URL. | 226 // in the correct component of the URL. |
| 228 switch (criterion_) { | 227 switch (criterion_) { |
| 229 case HOST_CONTAINS: | 228 case HOST_CONTAINS: |
| 230 return url.host().find(string_pattern_->pattern()) != | 229 return url.host().find(string_pattern_->pattern()) != |
| 231 std::string::npos; | 230 std::string::npos; |
| 232 case PATH_CONTAINS: | 231 case PATH_CONTAINS: |
| 233 return url.path().find(string_pattern_->pattern()) != | 232 return url.path().find(string_pattern_->pattern()) != |
| 234 std::string::npos; | 233 std::string::npos; |
| 235 case QUERY_CONTAINS: | |
| 236 return url.query().find(string_pattern_->pattern()) != | |
| 237 std::string::npos; | |
| 238 default: | 234 default: |
| 239 break; | 235 break; |
| 240 } | 236 } |
| 241 return true; | 237 return true; |
| 242 } | 238 } |
| 243 | 239 |
| 244 // | 240 // |
| 245 // URLMatcherConditionFactory | 241 // URLMatcherConditionFactory |
| 246 // | 242 // |
| 247 | 243 |
| 248 namespace { | 244 namespace { |
| 249 // These are symbols that are not contained in 7-bit ASCII used in GURLs. | 245 // These are symbols that are not contained in 7-bit ASCII used in GURLs. |
| 250 const char kBeginningOfURL[] = {static_cast<char>(-1), 0}; | 246 const char kBeginningOfURL[] = {static_cast<char>(-1), 0}; |
| 251 const char kEndOfDomain[] = {static_cast<char>(-2), 0}; | 247 const char kEndOfDomain[] = {static_cast<char>(-2), 0}; |
| 252 const char kEndOfPath[] = {static_cast<char>(-3), 0}; | 248 const char kEndOfPath[] = {static_cast<char>(-3), 0}; |
| 253 const char kEndOfURL[] = {static_cast<char>(-4), 0}; | 249 const char kBeginningOfQueryComponent[] = {static_cast<char>(-4), 0}; |
| 250 const char kEndOfURL[] = {static_cast<char>(-5), 0}; |
| 251 const char kQuerySeperator = '&'; |
| 252 |
| 253 // This function prepares the query string by replacing query separator with a |
| 254 // magic value (|kBeginningOfQueryComponent|). When the boolean |
| 255 // |prepend_beginning_of_query_component| is true the function prepends the |
| 256 // query with the same magic. This is done to locate the start of a key value |
| 257 // pair in the query string. The parameter |query| is passed by value |
| 258 // intentionally, since it is locally modified. |
| 259 std::string PrepareQuery(std::string query, |
| 260 bool prepend_beginning_of_query_component) { |
| 261 for (std::string::iterator it = query.begin(); it != query.end(); ++it) { |
| 262 if (*it == kQuerySeperator) |
| 263 *it = kBeginningOfQueryComponent[0]; |
| 264 } |
| 265 return prepend_beginning_of_query_component |
| 266 ? kBeginningOfQueryComponent + query |
| 267 : query; |
| 268 } |
| 254 } // namespace | 269 } // namespace |
| 255 | 270 |
| 256 URLMatcherConditionFactory::URLMatcherConditionFactory() : id_counter_(0) {} | 271 URLMatcherConditionFactory::URLMatcherConditionFactory() : id_counter_(0) {} |
| 257 | 272 |
| 258 URLMatcherConditionFactory::~URLMatcherConditionFactory() { | 273 URLMatcherConditionFactory::~URLMatcherConditionFactory() { |
| 259 STLDeleteElements(&substring_pattern_singletons_); | 274 STLDeleteElements(&substring_pattern_singletons_); |
| 260 STLDeleteElements(®ex_pattern_singletons_); | 275 STLDeleteElements(®ex_pattern_singletons_); |
| 261 STLDeleteElements(&origin_and_path_regex_pattern_singletons_); | 276 STLDeleteElements(&origin_and_path_regex_pattern_singletons_); |
| 262 } | 277 } |
| 263 | 278 |
| 264 std::string URLMatcherConditionFactory::CanonicalizeURLForComponentSearches( | 279 std::string URLMatcherConditionFactory::CanonicalizeURLForComponentSearches( |
| 265 const GURL& url) const { | 280 const GURL& url) const { |
| 266 return kBeginningOfURL + CanonicalizeHostname(url.host()) + kEndOfDomain + | 281 return kBeginningOfURL + CanonicalizeHostname(url.host()) + kEndOfDomain + |
| 267 url.path() + kEndOfPath + | 282 url.path() + kEndOfPath + |
| 268 (url.has_query() ? "?" + url.query() : std::string()) + kEndOfURL; | 283 (url.has_query() ? PrepareQuery(url.query(), true) : std::string()) + |
| 284 kEndOfURL; |
| 269 } | 285 } |
| 270 | 286 |
| 271 URLMatcherCondition URLMatcherConditionFactory::CreateHostPrefixCondition( | 287 URLMatcherCondition URLMatcherConditionFactory::CreateHostPrefixCondition( |
| 272 const std::string& prefix) { | 288 const std::string& prefix) { |
| 273 return CreateCondition(URLMatcherCondition::HOST_PREFIX, | 289 return CreateCondition(URLMatcherCondition::HOST_PREFIX, |
| 274 kBeginningOfURL + CanonicalizeHostname(prefix)); | 290 kBeginningOfURL + CanonicalizeHostname(prefix)); |
| 275 } | 291 } |
| 276 | 292 |
| 277 URLMatcherCondition URLMatcherConditionFactory::CreateHostSuffixCondition( | 293 URLMatcherCondition URLMatcherConditionFactory::CreateHostSuffixCondition( |
| 278 const std::string& suffix) { | 294 const std::string& suffix) { |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 310 URLMatcherCondition URLMatcherConditionFactory::CreatePathEqualsCondition( | 326 URLMatcherCondition URLMatcherConditionFactory::CreatePathEqualsCondition( |
| 311 const std::string& str) { | 327 const std::string& str) { |
| 312 return CreateCondition(URLMatcherCondition::PATH_EQUALS, | 328 return CreateCondition(URLMatcherCondition::PATH_EQUALS, |
| 313 kEndOfDomain + str + kEndOfPath); | 329 kEndOfDomain + str + kEndOfPath); |
| 314 } | 330 } |
| 315 | 331 |
| 316 URLMatcherCondition URLMatcherConditionFactory::CreateQueryPrefixCondition( | 332 URLMatcherCondition URLMatcherConditionFactory::CreateQueryPrefixCondition( |
| 317 const std::string& prefix) { | 333 const std::string& prefix) { |
| 318 std::string pattern; | 334 std::string pattern; |
| 319 if (!prefix.empty() && prefix[0] == '?') | 335 if (!prefix.empty() && prefix[0] == '?') |
| 320 pattern = kEndOfPath + prefix; | 336 pattern = kEndOfPath + PrepareQuery(prefix.substr(1), true); |
| 321 else | 337 else |
| 322 pattern = kEndOfPath + ('?' + prefix); | 338 pattern = kEndOfPath + PrepareQuery(prefix, true); |
| 323 | 339 |
| 324 return CreateCondition(URLMatcherCondition::QUERY_PREFIX, pattern); | 340 return CreateCondition(URLMatcherCondition::QUERY_PREFIX, pattern); |
| 325 } | 341 } |
| 326 | 342 |
| 327 URLMatcherCondition URLMatcherConditionFactory::CreateQuerySuffixCondition( | 343 URLMatcherCondition URLMatcherConditionFactory::CreateQuerySuffixCondition( |
| 328 const std::string& suffix) { | 344 const std::string& suffix) { |
| 329 if (!suffix.empty() && suffix[0] == '?') { | 345 if (!suffix.empty() && suffix[0] == '?') { |
| 330 return CreateQueryEqualsCondition(suffix); | 346 return CreateQueryEqualsCondition(suffix); |
| 331 } else { | 347 } else { |
| 332 return CreateCondition(URLMatcherCondition::QUERY_SUFFIX, | 348 return CreateCondition(URLMatcherCondition::QUERY_SUFFIX, |
| 333 suffix + kEndOfURL); | 349 PrepareQuery(suffix, false) + kEndOfURL); |
| 334 } | 350 } |
| 335 } | 351 } |
| 336 | 352 |
| 337 URLMatcherCondition URLMatcherConditionFactory::CreateQueryContainsCondition( | 353 URLMatcherCondition URLMatcherConditionFactory::CreateQueryContainsCondition( |
| 338 const std::string& str) { | 354 const std::string& str) { |
| 355 std::string pattern; |
| 339 if (!str.empty() && str[0] == '?') | 356 if (!str.empty() && str[0] == '?') |
| 340 return CreateQueryPrefixCondition(str); | 357 pattern = str.substr(1); |
| 341 else | 358 else |
| 342 return CreateCondition(URLMatcherCondition::QUERY_CONTAINS, str); | 359 pattern = str; |
| 360 return CreateCondition(URLMatcherCondition::QUERY_CONTAINS, |
| 361 PrepareQuery(pattern, true)); |
| 343 } | 362 } |
| 344 | 363 |
| 345 URLMatcherCondition URLMatcherConditionFactory::CreateQueryEqualsCondition( | 364 URLMatcherCondition URLMatcherConditionFactory::CreateQueryEqualsCondition( |
| 346 const std::string& str) { | 365 const std::string& str) { |
| 347 std::string pattern; | 366 std::string pattern; |
| 348 if (!str.empty() && str[0] == '?') | 367 if (!str.empty() && str[0] == '?') |
| 349 pattern = kEndOfPath + str + kEndOfURL; | 368 pattern = kEndOfPath + PrepareQuery(str.substr(1), true) + kEndOfURL; |
| 350 else | 369 else |
| 351 pattern = kEndOfPath + ('?' + str) + kEndOfURL; | 370 pattern = kEndOfPath + PrepareQuery(str, true) + kEndOfURL; |
| 352 | 371 |
| 353 return CreateCondition(URLMatcherCondition::QUERY_EQUALS, pattern); | 372 return CreateCondition(URLMatcherCondition::QUERY_EQUALS, pattern); |
| 354 } | 373 } |
| 355 | 374 |
| 356 URLMatcherCondition | 375 URLMatcherCondition |
| 357 URLMatcherConditionFactory::CreateHostSuffixPathPrefixCondition( | 376 URLMatcherConditionFactory::CreateHostSuffixPathPrefixCondition( |
| 358 const std::string& host_suffix, | 377 const std::string& host_suffix, |
| 359 const std::string& path_prefix) { | 378 const std::string& path_prefix) { |
| 360 return CreateCondition(URLMatcherCondition::HOST_SUFFIX_PATH_PREFIX, | 379 return CreateCondition(URLMatcherCondition::HOST_SUFFIX_PATH_PREFIX, |
| 361 host_suffix + kEndOfDomain + path_prefix); | 380 host_suffix + kEndOfDomain + path_prefix); |
| (...skipping 509 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 871 | 890 |
| 872 void URLMatcher::UpdateInternalDatastructures() { | 891 void URLMatcher::UpdateInternalDatastructures() { |
| 873 UpdateSubstringSetMatcher(false); | 892 UpdateSubstringSetMatcher(false); |
| 874 UpdateSubstringSetMatcher(true); | 893 UpdateSubstringSetMatcher(true); |
| 875 UpdateRegexSetMatcher(); | 894 UpdateRegexSetMatcher(); |
| 876 UpdateTriggers(); | 895 UpdateTriggers(); |
| 877 UpdateConditionFactory(); | 896 UpdateConditionFactory(); |
| 878 } | 897 } |
| 879 | 898 |
| 880 } // namespace url_matcher | 899 } // namespace url_matcher |
| OLD | NEW |