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 232 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
243 | 243 |
244 // | 244 // |
245 // URLMatcherConditionFactory | 245 // URLMatcherConditionFactory |
246 // | 246 // |
247 | 247 |
248 namespace { | 248 namespace { |
249 // These are symbols that are not contained in 7-bit ASCII used in GURLs. | 249 // These are symbols that are not contained in 7-bit ASCII used in GURLs. |
250 const char kBeginningOfURL[] = {static_cast<char>(-1), 0}; | 250 const char kBeginningOfURL[] = {static_cast<char>(-1), 0}; |
251 const char kEndOfDomain[] = {static_cast<char>(-2), 0}; | 251 const char kEndOfDomain[] = {static_cast<char>(-2), 0}; |
252 const char kEndOfPath[] = {static_cast<char>(-3), 0}; | 252 const char kEndOfPath[] = {static_cast<char>(-3), 0}; |
253 const char kEndOfURL[] = {static_cast<char>(-4), 0}; | 253 const char kQueryComponentDelimiter[] = {static_cast<char>(-4), 0}; |
| 254 const char kEndOfURL[] = {static_cast<char>(-5), 0}; |
| 255 const char kQuerySeparator = '&'; |
254 } // namespace | 256 } // namespace |
255 | 257 |
256 URLMatcherConditionFactory::URLMatcherConditionFactory() : id_counter_(0) {} | 258 URLMatcherConditionFactory::URLMatcherConditionFactory() : id_counter_(0) {} |
257 | 259 |
258 URLMatcherConditionFactory::~URLMatcherConditionFactory() { | 260 URLMatcherConditionFactory::~URLMatcherConditionFactory() { |
259 STLDeleteElements(&substring_pattern_singletons_); | 261 STLDeleteElements(&substring_pattern_singletons_); |
260 STLDeleteElements(®ex_pattern_singletons_); | 262 STLDeleteElements(®ex_pattern_singletons_); |
261 STLDeleteElements(&origin_and_path_regex_pattern_singletons_); | 263 STLDeleteElements(&origin_and_path_regex_pattern_singletons_); |
262 } | 264 } |
263 | 265 |
264 std::string URLMatcherConditionFactory::CanonicalizeURLForComponentSearches( | 266 std::string URLMatcherConditionFactory::CanonicalizeURLForComponentSearches( |
265 const GURL& url) const { | 267 const GURL& url) const { |
266 return kBeginningOfURL + CanonicalizeHostname(url.host()) + kEndOfDomain + | 268 return kBeginningOfURL + CanonicalizeHostname(url.host()) + kEndOfDomain + |
267 url.path() + kEndOfPath + | 269 url.path() + kEndOfPath + |
268 (url.has_query() ? "?" + url.query() : std::string()) + kEndOfURL; | 270 (url.has_query() ? CanonicalizeQuery(url.query(), true, true) |
| 271 : std::string()) + |
| 272 kEndOfURL; |
269 } | 273 } |
270 | 274 |
271 URLMatcherCondition URLMatcherConditionFactory::CreateHostPrefixCondition( | 275 URLMatcherCondition URLMatcherConditionFactory::CreateHostPrefixCondition( |
272 const std::string& prefix) { | 276 const std::string& prefix) { |
273 return CreateCondition(URLMatcherCondition::HOST_PREFIX, | 277 return CreateCondition(URLMatcherCondition::HOST_PREFIX, |
274 kBeginningOfURL + CanonicalizeHostname(prefix)); | 278 kBeginningOfURL + CanonicalizeHostname(prefix)); |
275 } | 279 } |
276 | 280 |
277 URLMatcherCondition URLMatcherConditionFactory::CreateHostSuffixCondition( | 281 URLMatcherCondition URLMatcherConditionFactory::CreateHostSuffixCondition( |
278 const std::string& suffix) { | 282 const std::string& suffix) { |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
310 URLMatcherCondition URLMatcherConditionFactory::CreatePathEqualsCondition( | 314 URLMatcherCondition URLMatcherConditionFactory::CreatePathEqualsCondition( |
311 const std::string& str) { | 315 const std::string& str) { |
312 return CreateCondition(URLMatcherCondition::PATH_EQUALS, | 316 return CreateCondition(URLMatcherCondition::PATH_EQUALS, |
313 kEndOfDomain + str + kEndOfPath); | 317 kEndOfDomain + str + kEndOfPath); |
314 } | 318 } |
315 | 319 |
316 URLMatcherCondition URLMatcherConditionFactory::CreateQueryPrefixCondition( | 320 URLMatcherCondition URLMatcherConditionFactory::CreateQueryPrefixCondition( |
317 const std::string& prefix) { | 321 const std::string& prefix) { |
318 std::string pattern; | 322 std::string pattern; |
319 if (!prefix.empty() && prefix[0] == '?') | 323 if (!prefix.empty() && prefix[0] == '?') |
320 pattern = kEndOfPath + prefix; | 324 pattern = kEndOfPath + CanonicalizeQuery(prefix.substr(1), true, false); |
321 else | 325 else |
322 pattern = kEndOfPath + ('?' + prefix); | 326 pattern = kEndOfPath + CanonicalizeQuery(prefix, true, false); |
323 | 327 |
324 return CreateCondition(URLMatcherCondition::QUERY_PREFIX, pattern); | 328 return CreateCondition(URLMatcherCondition::QUERY_PREFIX, pattern); |
325 } | 329 } |
326 | 330 |
327 URLMatcherCondition URLMatcherConditionFactory::CreateQuerySuffixCondition( | 331 URLMatcherCondition URLMatcherConditionFactory::CreateQuerySuffixCondition( |
328 const std::string& suffix) { | 332 const std::string& suffix) { |
329 if (!suffix.empty() && suffix[0] == '?') { | 333 if (!suffix.empty() && suffix[0] == '?') { |
330 return CreateQueryEqualsCondition(suffix); | 334 return CreateQueryEqualsCondition(suffix); |
331 } else { | 335 } else { |
332 return CreateCondition(URLMatcherCondition::QUERY_SUFFIX, | 336 return CreateCondition(URLMatcherCondition::QUERY_SUFFIX, |
333 suffix + kEndOfURL); | 337 CanonicalizeQuery(suffix, false, true) + kEndOfURL); |
334 } | 338 } |
335 } | 339 } |
336 | 340 |
337 URLMatcherCondition URLMatcherConditionFactory::CreateQueryContainsCondition( | 341 URLMatcherCondition URLMatcherConditionFactory::CreateQueryContainsCondition( |
338 const std::string& str) { | 342 const std::string& str) { |
339 if (!str.empty() && str[0] == '?') | 343 if (!str.empty() && str[0] == '?') |
340 return CreateQueryPrefixCondition(str); | 344 return CreateQueryPrefixCondition(str); |
341 else | 345 else |
342 return CreateCondition(URLMatcherCondition::QUERY_CONTAINS, str); | 346 return CreateCondition(URLMatcherCondition::QUERY_CONTAINS, str); |
343 } | 347 } |
344 | 348 |
345 URLMatcherCondition URLMatcherConditionFactory::CreateQueryEqualsCondition( | 349 URLMatcherCondition URLMatcherConditionFactory::CreateQueryEqualsCondition( |
346 const std::string& str) { | 350 const std::string& str) { |
347 std::string pattern; | 351 std::string pattern; |
348 if (!str.empty() && str[0] == '?') | 352 if (!str.empty() && str[0] == '?') |
349 pattern = kEndOfPath + str + kEndOfURL; | 353 pattern = |
| 354 kEndOfPath + CanonicalizeQuery(str.substr(1), true, true) + kEndOfURL; |
350 else | 355 else |
351 pattern = kEndOfPath + ('?' + str) + kEndOfURL; | 356 pattern = kEndOfPath + CanonicalizeQuery(str, true, true) + kEndOfURL; |
352 | 357 |
353 return CreateCondition(URLMatcherCondition::QUERY_EQUALS, pattern); | 358 return CreateCondition(URLMatcherCondition::QUERY_EQUALS, pattern); |
354 } | 359 } |
355 | 360 |
356 URLMatcherCondition | 361 URLMatcherCondition |
357 URLMatcherConditionFactory::CreateHostSuffixPathPrefixCondition( | 362 URLMatcherConditionFactory::CreateHostSuffixPathPrefixCondition( |
358 const std::string& host_suffix, | 363 const std::string& host_suffix, |
359 const std::string& path_prefix) { | 364 const std::string& path_prefix) { |
360 return CreateCondition(URLMatcherCondition::HOST_SUFFIX_PATH_PREFIX, | 365 return CreateCondition(URLMatcherCondition::HOST_SUFFIX_PATH_PREFIX, |
361 host_suffix + kEndOfDomain + path_prefix); | 366 host_suffix + kEndOfDomain + path_prefix); |
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
515 } | 520 } |
516 | 521 |
517 std::string URLMatcherConditionFactory::CanonicalizeHostname( | 522 std::string URLMatcherConditionFactory::CanonicalizeHostname( |
518 const std::string& hostname) const { | 523 const std::string& hostname) const { |
519 if (!hostname.empty() && hostname[0] == '.') | 524 if (!hostname.empty() && hostname[0] == '.') |
520 return hostname; | 525 return hostname; |
521 else | 526 else |
522 return "." + hostname; | 527 return "." + hostname; |
523 } | 528 } |
524 | 529 |
| 530 // This function prepares the query string by replacing query separator with a |
| 531 // magic value (|kQueryComponentDelimiter|). When the boolean |
| 532 // |prepend_beginning_of_query_component| is true the function prepends the |
| 533 // query with the same magic. This is done to locate the start of a key value |
| 534 // pair in the query string. The parameter |query| is passed by value |
| 535 // intentionally, since it is locally modified. |
| 536 std::string URLMatcherConditionFactory::CanonicalizeQuery( |
| 537 std::string query, |
| 538 bool prepend_beginning_of_query_component, |
| 539 bool append_end_of_query_component) const { |
| 540 for (std::string::iterator it = query.begin(); it != query.end(); ++it) { |
| 541 if (*it == kQuerySeparator) |
| 542 *it = kQueryComponentDelimiter[0]; |
| 543 } |
| 544 if (prepend_beginning_of_query_component) |
| 545 query = kQueryComponentDelimiter + query; |
| 546 if (append_end_of_query_component) |
| 547 query += kQueryComponentDelimiter; |
| 548 return query; |
| 549 } |
| 550 |
525 bool URLMatcherConditionFactory::StringPatternPointerCompare::operator()( | 551 bool URLMatcherConditionFactory::StringPatternPointerCompare::operator()( |
526 StringPattern* lhs, | 552 StringPattern* lhs, |
527 StringPattern* rhs) const { | 553 StringPattern* rhs) const { |
528 if (lhs == NULL && rhs != NULL) return true; | 554 if (lhs == NULL && rhs != NULL) return true; |
529 if (lhs != NULL && rhs != NULL) | 555 if (lhs != NULL && rhs != NULL) |
530 return lhs->pattern() < rhs->pattern(); | 556 return lhs->pattern() < rhs->pattern(); |
531 // Either both are NULL or only rhs is NULL. | 557 // Either both are NULL or only rhs is NULL. |
532 return false; | 558 return false; |
533 } | 559 } |
534 | 560 |
535 // | 561 // |
| 562 // URLQueryElementMatcherCondition |
| 563 // |
| 564 |
| 565 URLQueryElementMatcherCondition::URLQueryElementMatcherCondition( |
| 566 const std::string& key, |
| 567 const std::string& value, |
| 568 QueryValueMatchType query_value_match_type, |
| 569 QueryElementType query_element_type, |
| 570 Type match_type, |
| 571 URLMatcherConditionFactory* factory) { |
| 572 match_type_ = match_type; |
| 573 |
| 574 if (query_element_type == ELEMENT_TYPE_KEY_VALUE) { |
| 575 key_ = kQueryComponentDelimiter + key + std::string("="); |
| 576 value_ = value; |
| 577 } else { |
| 578 key_ = kQueryComponentDelimiter + key; |
| 579 value_ = std::string(); |
| 580 } |
| 581 |
| 582 if (query_value_match_type == QUERY_VALUE_MATCH_EXACT) |
| 583 value_ += kQueryComponentDelimiter; |
| 584 |
| 585 URLMatcherCondition condition = factory->CreateQueryContainsCondition(key_); |
| 586 string_pattern_ = condition.string_pattern(); |
| 587 |
| 588 key_length_ = key_.length(); |
| 589 value_length_ = value_.length(); |
| 590 } |
| 591 |
| 592 URLQueryElementMatcherCondition::~URLQueryElementMatcherCondition() {} |
| 593 |
| 594 bool URLQueryElementMatcherCondition::operator<( |
| 595 const URLQueryElementMatcherCondition& rhs) const { |
| 596 if (match_type_ < rhs.match_type_) |
| 597 return true; |
| 598 if (match_type_ > rhs.match_type_) |
| 599 return false; |
| 600 if (string_pattern_ != NULL && rhs.string_pattern_ != NULL) |
| 601 return *string_pattern_ < *rhs.string_pattern_; |
| 602 if (string_pattern_ == NULL && rhs.string_pattern_ != NULL) |
| 603 return true; |
| 604 // Either string_pattern_ != NULL && rhs.string_pattern_ == NULL, |
| 605 // or both are NULL. |
| 606 return false; |
| 607 } |
| 608 |
| 609 bool URLQueryElementMatcherCondition::IsMatch( |
| 610 const std::string& url_for_component_searches) const { |
| 611 switch (match_type_) { |
| 612 case MATCH_ANY: { |
| 613 return url_for_component_searches.find(key_ + value_) != |
| 614 std::string::npos; |
| 615 } |
| 616 case MATCH_ALL: { |
| 617 size_t start = 0; |
| 618 int found = 0; |
| 619 size_t offset; |
| 620 while ((offset = url_for_component_searches.find(key_, start)) != |
| 621 std::string::npos) { |
| 622 if (url_for_component_searches.compare( |
| 623 offset + key_length_, value_length_, value_) != 0) { |
| 624 return false; |
| 625 } else { |
| 626 ++found; |
| 627 } |
| 628 start = offset + key_length_ + value_length_; |
| 629 } |
| 630 return found != 0; |
| 631 } |
| 632 case MATCH_FIRST: { |
| 633 size_t offset = url_for_component_searches.find(key_); |
| 634 return url_for_component_searches.compare( |
| 635 offset + key_length_, value_length_, value_) == 0; |
| 636 } |
| 637 case MATCH_LAST: { |
| 638 size_t offset = url_for_component_searches.rfind(key_); |
| 639 return url_for_component_searches.compare( |
| 640 offset + key_length_, value_length_, value_) == 0; |
| 641 } |
| 642 } |
| 643 NOTREACHED(); |
| 644 return false; |
| 645 } |
| 646 |
| 647 // |
536 // URLMatcherSchemeFilter | 648 // URLMatcherSchemeFilter |
537 // | 649 // |
538 | 650 |
539 URLMatcherSchemeFilter::URLMatcherSchemeFilter(const std::string& filter) | 651 URLMatcherSchemeFilter::URLMatcherSchemeFilter(const std::string& filter) |
540 : filters_(1) { | 652 : filters_(1) { |
541 filters_.push_back(filter); | 653 filters_.push_back(filter); |
542 } | 654 } |
543 | 655 |
544 URLMatcherSchemeFilter::URLMatcherSchemeFilter( | 656 URLMatcherSchemeFilter::URLMatcherSchemeFilter( |
545 const std::vector<std::string>& filters) | 657 const std::vector<std::string>& filters) |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
598 URLMatcherConditionSet::URLMatcherConditionSet( | 710 URLMatcherConditionSet::URLMatcherConditionSet( |
599 ID id, | 711 ID id, |
600 const Conditions& conditions, | 712 const Conditions& conditions, |
601 scoped_ptr<URLMatcherSchemeFilter> scheme_filter, | 713 scoped_ptr<URLMatcherSchemeFilter> scheme_filter, |
602 scoped_ptr<URLMatcherPortFilter> port_filter) | 714 scoped_ptr<URLMatcherPortFilter> port_filter) |
603 : id_(id), | 715 : id_(id), |
604 conditions_(conditions), | 716 conditions_(conditions), |
605 scheme_filter_(scheme_filter.Pass()), | 717 scheme_filter_(scheme_filter.Pass()), |
606 port_filter_(port_filter.Pass()) {} | 718 port_filter_(port_filter.Pass()) {} |
607 | 719 |
| 720 URLMatcherConditionSet::URLMatcherConditionSet( |
| 721 ID id, |
| 722 const Conditions& conditions, |
| 723 const QueryConditions& query_conditions, |
| 724 scoped_ptr<URLMatcherSchemeFilter> scheme_filter, |
| 725 scoped_ptr<URLMatcherPortFilter> port_filter) |
| 726 : id_(id), |
| 727 conditions_(conditions), |
| 728 query_conditions_(query_conditions), |
| 729 scheme_filter_(scheme_filter.Pass()), |
| 730 port_filter_(port_filter.Pass()) {} |
| 731 |
608 bool URLMatcherConditionSet::IsMatch( | 732 bool URLMatcherConditionSet::IsMatch( |
609 const std::set<StringPattern::ID>& matching_patterns, | 733 const std::set<StringPattern::ID>& matching_patterns, |
610 const GURL& url) const { | 734 const GURL& url) const { |
| 735 return IsMatch(matching_patterns, url, std::string()); |
| 736 } |
| 737 |
| 738 bool URLMatcherConditionSet::IsMatch( |
| 739 const std::set<StringPattern::ID>& matching_patterns, |
| 740 const GURL& url, |
| 741 const std::string url_for_component_searches) const { |
611 for (Conditions::const_iterator i = conditions_.begin(); | 742 for (Conditions::const_iterator i = conditions_.begin(); |
612 i != conditions_.end(); ++i) { | 743 i != conditions_.end(); ++i) { |
613 if (!i->IsMatch(matching_patterns, url)) | 744 if (!i->IsMatch(matching_patterns, url)) |
614 return false; | 745 return false; |
615 } | 746 } |
616 if (scheme_filter_.get() && !scheme_filter_->IsMatch(url)) | 747 if (scheme_filter_.get() && !scheme_filter_->IsMatch(url)) |
617 return false; | 748 return false; |
618 if (port_filter_.get() && !port_filter_->IsMatch(url)) | 749 if (port_filter_.get() && !port_filter_->IsMatch(url)) |
619 return false; | 750 return false; |
| 751 if (query_conditions_.empty()) |
| 752 return true; |
| 753 // The loop is duplicated below for performance reasons. If all query elements |
| 754 // are not found, no need to verify match that is expected to take more |
| 755 // cycles. |
| 756 for (QueryConditions::const_iterator i = query_conditions_.begin(); |
| 757 i != query_conditions_.end(); |
| 758 ++i) { |
| 759 if (!ContainsKey(matching_patterns, i->string_pattern()->id())) |
| 760 return false; |
| 761 } |
| 762 for (QueryConditions::const_iterator i = query_conditions_.begin(); |
| 763 i != query_conditions_.end(); |
| 764 ++i) { |
| 765 if (!i->IsMatch(url_for_component_searches)) |
| 766 return false; |
| 767 } |
620 return true; | 768 return true; |
621 } | 769 } |
622 | 770 |
623 // | 771 // |
624 // URLMatcher | 772 // URLMatcher |
625 // | 773 // |
626 | 774 |
627 URLMatcher::URLMatcher() {} | 775 URLMatcher::URLMatcher() {} |
628 | 776 |
629 URLMatcher::~URLMatcher() {} | 777 URLMatcher::~URLMatcher() {} |
(...skipping 23 matching lines...) Expand all Loading... |
653 void URLMatcher::ClearUnusedConditionSets() { | 801 void URLMatcher::ClearUnusedConditionSets() { |
654 UpdateConditionFactory(); | 802 UpdateConditionFactory(); |
655 } | 803 } |
656 | 804 |
657 std::set<URLMatcherConditionSet::ID> URLMatcher::MatchURL( | 805 std::set<URLMatcherConditionSet::ID> URLMatcher::MatchURL( |
658 const GURL& url) const { | 806 const GURL& url) const { |
659 // Find all IDs of StringPatterns that match |url|. | 807 // Find all IDs of StringPatterns that match |url|. |
660 // See URLMatcherConditionFactory for the canonicalization of URLs and the | 808 // See URLMatcherConditionFactory for the canonicalization of URLs and the |
661 // distinction between full url searches and url component searches. | 809 // distinction between full url searches and url component searches. |
662 std::set<StringPattern::ID> matches; | 810 std::set<StringPattern::ID> matches; |
| 811 std::string url_for_component_searches; |
| 812 |
663 if (!full_url_matcher_.IsEmpty()) { | 813 if (!full_url_matcher_.IsEmpty()) { |
664 full_url_matcher_.Match( | 814 full_url_matcher_.Match( |
665 condition_factory_.CanonicalizeURLForFullSearches(url), &matches); | 815 condition_factory_.CanonicalizeURLForFullSearches(url), &matches); |
666 } | 816 } |
667 if (!url_component_matcher_.IsEmpty()) { | 817 if (!url_component_matcher_.IsEmpty()) { |
668 url_component_matcher_.Match( | 818 url_for_component_searches = |
669 condition_factory_.CanonicalizeURLForComponentSearches(url), &matches); | 819 condition_factory_.CanonicalizeURLForComponentSearches(url); |
| 820 url_component_matcher_.Match(url_for_component_searches, &matches); |
670 } | 821 } |
671 if (!regex_set_matcher_.IsEmpty()) { | 822 if (!regex_set_matcher_.IsEmpty()) { |
672 regex_set_matcher_.Match( | 823 regex_set_matcher_.Match( |
673 condition_factory_.CanonicalizeURLForRegexSearches(url), &matches); | 824 condition_factory_.CanonicalizeURLForRegexSearches(url), &matches); |
674 } | 825 } |
675 if (!origin_and_path_regex_set_matcher_.IsEmpty()) { | 826 if (!origin_and_path_regex_set_matcher_.IsEmpty()) { |
676 origin_and_path_regex_set_matcher_.Match( | 827 origin_and_path_regex_set_matcher_.Match( |
677 condition_factory_.CanonicalizeURLForOriginAndPathRegexSearches(url), | 828 condition_factory_.CanonicalizeURLForOriginAndPathRegexSearches(url), |
678 &matches); | 829 &matches); |
679 } | 830 } |
(...skipping 11 matching lines...) Expand all Loading... |
691 substring_match_triggers_.find(*i); | 842 substring_match_triggers_.find(*i); |
692 if (triggered_condition_sets_iter == substring_match_triggers_.end()) | 843 if (triggered_condition_sets_iter == substring_match_triggers_.end()) |
693 continue; // Not all substring matches are triggers for a condition set. | 844 continue; // Not all substring matches are triggers for a condition set. |
694 const std::set<URLMatcherConditionSet::ID>& condition_sets = | 845 const std::set<URLMatcherConditionSet::ID>& condition_sets = |
695 triggered_condition_sets_iter->second; | 846 triggered_condition_sets_iter->second; |
696 for (std::set<URLMatcherConditionSet::ID>::const_iterator j = | 847 for (std::set<URLMatcherConditionSet::ID>::const_iterator j = |
697 condition_sets.begin(); j != condition_sets.end(); ++j) { | 848 condition_sets.begin(); j != condition_sets.end(); ++j) { |
698 URLMatcherConditionSets::const_iterator condition_set_iter = | 849 URLMatcherConditionSets::const_iterator condition_set_iter = |
699 url_matcher_condition_sets_.find(*j); | 850 url_matcher_condition_sets_.find(*j); |
700 DCHECK(condition_set_iter != url_matcher_condition_sets_.end()); | 851 DCHECK(condition_set_iter != url_matcher_condition_sets_.end()); |
701 if (condition_set_iter->second->IsMatch(matches, url)) | 852 if (condition_set_iter->second->IsMatch( |
| 853 matches, url, url_for_component_searches)) |
702 result.insert(*j); | 854 result.insert(*j); |
703 } | 855 } |
704 } | 856 } |
705 | 857 |
706 return result; | 858 return result; |
707 } | 859 } |
708 | 860 |
709 bool URLMatcher::IsEmpty() const { | 861 bool URLMatcher::IsEmpty() const { |
710 return condition_factory_.IsEmpty() && | 862 return condition_factory_.IsEmpty() && |
711 url_matcher_condition_sets_.empty() && | 863 url_matcher_condition_sets_.empty() && |
(...skipping 23 matching lines...) Expand all Loading... |
735 for (URLMatcherConditionSet::Conditions::const_iterator condition_iter = | 887 for (URLMatcherConditionSet::Conditions::const_iterator condition_iter = |
736 conditions.begin(); condition_iter != conditions.end(); | 888 conditions.begin(); condition_iter != conditions.end(); |
737 ++condition_iter) { | 889 ++condition_iter) { |
738 // If we are called to process Full URL searches, ignore others, and | 890 // If we are called to process Full URL searches, ignore others, and |
739 // vice versa. (Regex conditions are updated in UpdateRegexSetMatcher.) | 891 // vice versa. (Regex conditions are updated in UpdateRegexSetMatcher.) |
740 if (!condition_iter->IsRegexCondition() && | 892 if (!condition_iter->IsRegexCondition() && |
741 !condition_iter->IsOriginAndPathRegexCondition() && | 893 !condition_iter->IsOriginAndPathRegexCondition() && |
742 full_url_conditions == condition_iter->IsFullURLCondition()) | 894 full_url_conditions == condition_iter->IsFullURLCondition()) |
743 new_patterns.insert(condition_iter->string_pattern()); | 895 new_patterns.insert(condition_iter->string_pattern()); |
744 } | 896 } |
| 897 |
| 898 if (full_url_conditions) |
| 899 continue; |
| 900 |
| 901 const URLMatcherConditionSet::QueryConditions& query_conditions = |
| 902 condition_set_iter->second->query_conditions(); |
| 903 for (URLMatcherConditionSet::QueryConditions::const_iterator |
| 904 query_condition_iter = query_conditions.begin(); |
| 905 query_condition_iter != query_conditions.end(); |
| 906 ++query_condition_iter) { |
| 907 new_patterns.insert(query_condition_iter->string_pattern()); |
| 908 } |
745 } | 909 } |
746 | 910 |
747 // This is the set of patterns that were registered before this function | 911 // This is the set of patterns that were registered before this function |
748 // is called. | 912 // is called. |
749 std::set<const StringPattern*>& registered_patterns = | 913 std::set<const StringPattern*>& registered_patterns = |
750 full_url_conditions ? registered_full_url_patterns_ | 914 full_url_conditions ? registered_full_url_patterns_ |
751 : registered_url_component_patterns_; | 915 : registered_url_component_patterns_; |
752 | 916 |
753 // Add all patterns that are in new_patterns but not in registered_patterns. | 917 // Add all patterns that are in new_patterns but not in registered_patterns. |
754 std::vector<const StringPattern*> patterns_to_register = | 918 std::vector<const StringPattern*> patterns_to_register = |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
810 condition_set_iter != url_matcher_condition_sets_.end(); | 974 condition_set_iter != url_matcher_condition_sets_.end(); |
811 ++condition_set_iter) { | 975 ++condition_set_iter) { |
812 const URLMatcherConditionSet::Conditions& conditions = | 976 const URLMatcherConditionSet::Conditions& conditions = |
813 condition_set_iter->second->conditions(); | 977 condition_set_iter->second->conditions(); |
814 for (URLMatcherConditionSet::Conditions::const_iterator condition_iter = | 978 for (URLMatcherConditionSet::Conditions::const_iterator condition_iter = |
815 conditions.begin(); condition_iter != conditions.end(); | 979 conditions.begin(); condition_iter != conditions.end(); |
816 ++condition_iter) { | 980 ++condition_iter) { |
817 const StringPattern* pattern = condition_iter->string_pattern(); | 981 const StringPattern* pattern = condition_iter->string_pattern(); |
818 substring_pattern_frequencies[pattern->id()]++; | 982 substring_pattern_frequencies[pattern->id()]++; |
819 } | 983 } |
| 984 |
| 985 const URLMatcherConditionSet::QueryConditions& query_conditions = |
| 986 condition_set_iter->second->query_conditions(); |
| 987 for (URLMatcherConditionSet::QueryConditions::const_iterator |
| 988 query_condition_iter = query_conditions.begin(); |
| 989 query_condition_iter != query_conditions.end(); |
| 990 ++query_condition_iter) { |
| 991 const StringPattern* pattern = query_condition_iter->string_pattern(); |
| 992 substring_pattern_frequencies[pattern->id()]++; |
| 993 } |
820 } | 994 } |
821 | 995 |
822 // Update trigger conditions: Determine for each URLMatcherConditionSet which | 996 // Update trigger conditions: Determine for each URLMatcherConditionSet which |
823 // URLMatcherCondition contains a StringPattern that occurs least | 997 // URLMatcherCondition contains a StringPattern that occurs least |
824 // frequently in this URLMatcher. We assume that this condition is very | 998 // frequently in this URLMatcher. We assume that this condition is very |
825 // specific and occurs rarely in URLs. If a match occurs for this | 999 // specific and occurs rarely in URLs. If a match occurs for this |
826 // URLMatcherCondition, we want to test all other URLMatcherCondition in the | 1000 // URLMatcherCondition, we want to test all other URLMatcherCondition in the |
827 // respective URLMatcherConditionSet as well to see whether the entire | 1001 // respective URLMatcherConditionSet as well to see whether the entire |
828 // URLMatcherConditionSet is considered matching. | 1002 // URLMatcherConditionSet is considered matching. |
829 substring_match_triggers_.clear(); | 1003 substring_match_triggers_.clear(); |
(...skipping 11 matching lines...) Expand all Loading... |
841 // We skip the first element in the following loop. | 1015 // We skip the first element in the following loop. |
842 ++condition_iter; | 1016 ++condition_iter; |
843 for (; condition_iter != conditions.end(); ++condition_iter) { | 1017 for (; condition_iter != conditions.end(); ++condition_iter) { |
844 StringPattern::ID current_id = | 1018 StringPattern::ID current_id = |
845 condition_iter->string_pattern()->id(); | 1019 condition_iter->string_pattern()->id(); |
846 if (substring_pattern_frequencies[trigger] > | 1020 if (substring_pattern_frequencies[trigger] > |
847 substring_pattern_frequencies[current_id]) { | 1021 substring_pattern_frequencies[current_id]) { |
848 trigger = current_id; | 1022 trigger = current_id; |
849 } | 1023 } |
850 } | 1024 } |
| 1025 |
| 1026 const URLMatcherConditionSet::QueryConditions& query_conditions = |
| 1027 condition_set_iter->second->query_conditions(); |
| 1028 for (URLMatcherConditionSet::QueryConditions::const_iterator |
| 1029 query_condition_iter = query_conditions.begin(); |
| 1030 query_condition_iter != query_conditions.end(); |
| 1031 ++query_condition_iter) { |
| 1032 StringPattern::ID current_id = |
| 1033 query_condition_iter->string_pattern()->id(); |
| 1034 if (substring_pattern_frequencies[trigger] > |
| 1035 substring_pattern_frequencies[current_id]) { |
| 1036 trigger = current_id; |
| 1037 } |
| 1038 } |
| 1039 |
851 substring_match_triggers_[trigger].insert(condition_set_iter->second->id()); | 1040 substring_match_triggers_[trigger].insert(condition_set_iter->second->id()); |
852 } | 1041 } |
853 } | 1042 } |
854 | 1043 |
855 void URLMatcher::UpdateConditionFactory() { | 1044 void URLMatcher::UpdateConditionFactory() { |
856 std::set<StringPattern::ID> used_patterns; | 1045 std::set<StringPattern::ID> used_patterns; |
857 for (URLMatcherConditionSets::const_iterator condition_set_iter = | 1046 for (URLMatcherConditionSets::const_iterator condition_set_iter = |
858 url_matcher_condition_sets_.begin(); | 1047 url_matcher_condition_sets_.begin(); |
859 condition_set_iter != url_matcher_condition_sets_.end(); | 1048 condition_set_iter != url_matcher_condition_sets_.end(); |
860 ++condition_set_iter) { | 1049 ++condition_set_iter) { |
861 const URLMatcherConditionSet::Conditions& conditions = | 1050 const URLMatcherConditionSet::Conditions& conditions = |
862 condition_set_iter->second->conditions(); | 1051 condition_set_iter->second->conditions(); |
863 for (URLMatcherConditionSet::Conditions::const_iterator condition_iter = | 1052 for (URLMatcherConditionSet::Conditions::const_iterator condition_iter = |
864 conditions.begin(); condition_iter != conditions.end(); | 1053 conditions.begin(); condition_iter != conditions.end(); |
865 ++condition_iter) { | 1054 ++condition_iter) { |
866 used_patterns.insert(condition_iter->string_pattern()->id()); | 1055 used_patterns.insert(condition_iter->string_pattern()->id()); |
867 } | 1056 } |
| 1057 const URLMatcherConditionSet::QueryConditions& query_conditions = |
| 1058 condition_set_iter->second->query_conditions(); |
| 1059 for (URLMatcherConditionSet::QueryConditions::const_iterator |
| 1060 query_condition_iter = query_conditions.begin(); |
| 1061 query_condition_iter != query_conditions.end(); |
| 1062 ++query_condition_iter) { |
| 1063 used_patterns.insert(query_condition_iter->string_pattern()->id()); |
| 1064 } |
868 } | 1065 } |
869 condition_factory_.ForgetUnusedPatterns(used_patterns); | 1066 condition_factory_.ForgetUnusedPatterns(used_patterns); |
870 } | 1067 } |
871 | 1068 |
872 void URLMatcher::UpdateInternalDatastructures() { | 1069 void URLMatcher::UpdateInternalDatastructures() { |
873 UpdateSubstringSetMatcher(false); | 1070 UpdateSubstringSetMatcher(false); |
874 UpdateSubstringSetMatcher(true); | 1071 UpdateSubstringSetMatcher(true); |
875 UpdateRegexSetMatcher(); | 1072 UpdateRegexSetMatcher(); |
876 UpdateTriggers(); | 1073 UpdateTriggers(); |
877 UpdateConditionFactory(); | 1074 UpdateConditionFactory(); |
878 } | 1075 } |
879 | 1076 |
880 } // namespace url_matcher | 1077 } // namespace url_matcher |
OLD | NEW |