1 // Copyright 2020 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "net/base/scheme_host_port_matcher.h"
6
7 #include "base/strings/string_tokenizer.h"
8 #include "base/strings/string_util.h"
9
10 namespace net {
11
12 // Declares SchemeHostPortMatcher::kParseRuleListDelimiterList[], not a
13 // redefinition. This is needed for link.
14 // static
15 constexpr char SchemeHostPortMatcher::kParseRuleListDelimiterList[];
16
17 // Declares SchemeHostPortMatcher::kPrintRuleListDelimiter, not a
18 // redefinition. This is needed for link.
19 // static
20 constexpr char SchemeHostPortMatcher::kPrintRuleListDelimiter;
21
22 // static
FromRawString(const std::string & raw)23 SchemeHostPortMatcher SchemeHostPortMatcher::FromRawString(
24 const std::string& raw) {
25 SchemeHostPortMatcher result;
26
27 base::StringTokenizer entries(raw, kParseRuleListDelimiterList);
28 while (entries.GetNext()) {
29 auto rule =
30 SchemeHostPortMatcherRule::FromUntrimmedRawString(entries.token());
31 if (rule) {
32 result.AddAsLastRule(std::move(rule));
33 }
34 }
35
36 return result;
37 }
38
AddAsFirstRule(std::unique_ptr<SchemeHostPortMatcherRule> rule)39 void SchemeHostPortMatcher::AddAsFirstRule(
40 std::unique_ptr<SchemeHostPortMatcherRule> rule) {
41 DCHECK(rule);
42 rules_.insert(rules_.begin(), std::move(rule));
43 }
44
AddAsLastRule(std::unique_ptr<SchemeHostPortMatcherRule> rule)45 void SchemeHostPortMatcher::AddAsLastRule(
46 std::unique_ptr<SchemeHostPortMatcherRule> rule) {
47 DCHECK(rule);
48 rules_.push_back(std::move(rule));
49 }
50
ReplaceRule(size_t index,std::unique_ptr<SchemeHostPortMatcherRule> rule)51 void SchemeHostPortMatcher::ReplaceRule(
52 size_t index,
53 std::unique_ptr<SchemeHostPortMatcherRule> rule) {
54 DCHECK_LT(index, rules_.size());
55 rules_[index] = std::move(rule);
56 }
57
Includes(const GURL & url) const58 bool SchemeHostPortMatcher::Includes(const GURL& url) const {
59 return Evaluate(url) == SchemeHostPortMatcherResult::kInclude;
60 }
61
Evaluate(const GURL & url) const62 SchemeHostPortMatcherResult SchemeHostPortMatcher::Evaluate(
63 const GURL& url) const {
64 // Later rules override earlier rules, so evaluating the rule list can be
65 // done by iterating over it in reverse and short-circuiting when a match is
66 // found.
67 //
68 // The order of evaluation generally doesn't matter if all the rules are
69 // positive rules, so matches are just additive.
70 //
71 // However when mixing positive and negative rules, evaluation order makes a
72 // difference.
73 for (auto it = rules_.rbegin(); it != rules_.rend(); ++it) {
74 SchemeHostPortMatcherResult result = (*it)->Evaluate(url);
75 if (result != SchemeHostPortMatcherResult::kNoMatch)
76 return result;
77 }
78
79 return SchemeHostPortMatcherResult::kNoMatch;
80 }
81
ToString() const82 std::string SchemeHostPortMatcher::ToString() const {
83 std::string result;
84 for (const auto& rule : rules_) {
85 DCHECK(!base::Contains(rule->ToString(), kParseRuleListDelimiterList));
86 result += rule->ToString();
87 result.push_back(kPrintRuleListDelimiter);
88 }
89 return result;
90 }
91
Clear()92 void SchemeHostPortMatcher::Clear() {
93 rules_.clear();
94 }
95
96 } // namespace net
97