| // Copyright 2020 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "net/base/scheme_host_port_matcher.h" |
| |
| #include "base/containers/adapters.h" |
| #include "base/containers/contains.h" |
| #include "base/strings/string_tokenizer.h" |
| #include "base/strings/string_util.h" |
| |
| namespace net { |
| |
| SchemeHostPortMatcher::SchemeHostPortMatcher() = default; |
| SchemeHostPortMatcher::SchemeHostPortMatcher(SchemeHostPortMatcher&& rhs) = |
| default; |
| SchemeHostPortMatcher& SchemeHostPortMatcher::operator=( |
| SchemeHostPortMatcher&& rhs) = default; |
| SchemeHostPortMatcher::~SchemeHostPortMatcher() = default; |
| |
| // Declares SchemeHostPortMatcher::kParseRuleListDelimiterList[], not a |
| // redefinition. This is needed for link. |
| // static |
| constexpr char SchemeHostPortMatcher::kParseRuleListDelimiterList[]; |
| |
| // Declares SchemeHostPortMatcher::kPrintRuleListDelimiter, not a |
| // redefinition. This is needed for link. |
| // static |
| constexpr char SchemeHostPortMatcher::kPrintRuleListDelimiter; |
| |
| // static |
| SchemeHostPortMatcher SchemeHostPortMatcher::FromRawString( |
| const std::string& raw) { |
| SchemeHostPortMatcher result; |
| |
| base::StringTokenizer entries(raw, kParseRuleListDelimiterList); |
| while (entries.GetNext()) { |
| auto rule = SchemeHostPortMatcherRule::FromUntrimmedRawString( |
| entries.token_piece()); |
| if (rule) { |
| result.AddAsLastRule(std::move(rule)); |
| } |
| } |
| |
| return result; |
| } |
| |
| void SchemeHostPortMatcher::AddAsFirstRule( |
| std::unique_ptr<SchemeHostPortMatcherRule> rule) { |
| DCHECK(rule); |
| rules_.insert(rules_.begin(), std::move(rule)); |
| } |
| |
| void SchemeHostPortMatcher::AddAsLastRule( |
| std::unique_ptr<SchemeHostPortMatcherRule> rule) { |
| DCHECK(rule); |
| rules_.push_back(std::move(rule)); |
| } |
| |
| void SchemeHostPortMatcher::ReplaceRule( |
| size_t index, |
| std::unique_ptr<SchemeHostPortMatcherRule> rule) { |
| DCHECK_LT(index, rules_.size()); |
| rules_[index] = std::move(rule); |
| } |
| |
| bool SchemeHostPortMatcher::Includes(const GURL& url) const { |
| return Evaluate(url) == SchemeHostPortMatcherResult::kInclude; |
| } |
| |
| SchemeHostPortMatcherResult SchemeHostPortMatcher::Evaluate( |
| const GURL& url) const { |
| // Later rules override earlier rules, so evaluating the rule list can be |
| // done by iterating over it in reverse and short-circuiting when a match is |
| // found. |
| // |
| // The order of evaluation generally doesn't matter if all the rules are |
| // positive rules, so matches are just additive. |
| // |
| // However when mixing positive and negative rules, evaluation order makes a |
| // difference. |
| for (const auto& rule : base::Reversed(rules_)) { |
| SchemeHostPortMatcherResult result = rule->Evaluate(url); |
| if (result != SchemeHostPortMatcherResult::kNoMatch) |
| return result; |
| } |
| |
| return SchemeHostPortMatcherResult::kNoMatch; |
| } |
| |
| std::string SchemeHostPortMatcher::ToString() const { |
| std::string result; |
| for (const auto& rule : rules_) { |
| DCHECK(!base::Contains(rule->ToString(), kParseRuleListDelimiterList)); |
| result += rule->ToString(); |
| result.push_back(kPrintRuleListDelimiter); |
| } |
| return result; |
| } |
| |
| void SchemeHostPortMatcher::Clear() { |
| rules_.clear(); |
| } |
| |
| } // namespace net |