Commit 3c47f49c authored by Shimi Zhang's avatar Shimi Zhang Committed by Commit Bot

[ProxyBypassRules] Split out SchemeHostPortMatcher from ProxyBypassRules

We want to have a more general SchemeHostPortMatcher to allow a callsite
doesn't need to rely on ProxyBypassRules' specific logics. The user
should either use SchemeHostPortMatcher or create their own rules based
on SchemeHostPortMatcherRule.

Bug: 1030092
Change-Id: I095deb103cb4c3cbecc6e3c454423c805f1977c3
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2030051
Commit-Queue: Shimi Zhang <ctzsm@chromium.org>
Reviewed-by: default avatarMatt Menke <mmenke@chromium.org>
Cr-Commit-Position: refs/heads/master@{#737548}
parent b4020f42
...@@ -478,6 +478,8 @@ component("net") { ...@@ -478,6 +478,8 @@ component("net") {
"base/proxy_server.h", "base/proxy_server.h",
"base/request_priority.cc", "base/request_priority.cc",
"base/request_priority.h", "base/request_priority.h",
"base/scheme_host_port_matcher.cc",
"base/scheme_host_port_matcher.h",
"base/scheme_host_port_matcher_result.h", "base/scheme_host_port_matcher_result.h",
"base/scheme_host_port_matcher_rule.cc", "base/scheme_host_port_matcher_rule.cc",
"base/scheme_host_port_matcher_rule.h", "base/scheme_host_port_matcher_rule.h",
...@@ -4133,6 +4135,7 @@ test("net_unittests") { ...@@ -4133,6 +4135,7 @@ test("net_unittests") {
"base/priority_queue_unittest.cc", "base/priority_queue_unittest.cc",
"base/registry_controlled_domains/registry_controlled_domain_unittest.cc", "base/registry_controlled_domains/registry_controlled_domain_unittest.cc",
"base/scheme_host_port_matcher_rule_unittest.cc", "base/scheme_host_port_matcher_rule_unittest.cc",
"base/scheme_host_port_matcher_unittest.cc",
"base/static_cookie_policy_unittest.cc", "base/static_cookie_policy_unittest.cc",
"base/test_completion_callback_unittest.cc", "base/test_completion_callback_unittest.cc",
"base/test_proxy_delegate.cc", "base/test_proxy_delegate.cc",
......
// Copyright 2020 The Chromium Authors. All rights reserved.
// 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/strings/string_tokenizer.h"
namespace net {
// 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());
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 (auto it = rules_.rbegin(); it != rules_.rend(); ++it) {
SchemeHostPortMatcherResult result = (*it)->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
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef NET_BASE_SCHEME_HOST_PORT_MATCHER_H_
#define NET_BASE_SCHEME_HOST_PORT_MATCHER_H_
#include <string>
#include <vector>
#include "net/base/net_export.h"
#include "net/base/scheme_host_port_matcher_rule.h"
namespace net {
// SchemeHostPortMatcher holds an ordered list of rules for matching URLs, that
// is serializable to a string.
//
// Rules are evaluated in reverse, and each can be either an "include this URL"
// or an "exclude this URL".
//
// In a simple configuration, all rules are "include this URL" so evaluation
// order doesn't matter. When combining include and exclude rules,
// later rules will have precedence over earlier rules.
class NET_EXPORT SchemeHostPortMatcher {
public:
using RuleList = std::vector<std::unique_ptr<SchemeHostPortMatcherRule>>;
// Note: This class is movable but not copiable.
SchemeHostPortMatcher() = default;
SchemeHostPortMatcher(SchemeHostPortMatcher&& rhs) = default;
SchemeHostPortMatcher& operator=(SchemeHostPortMatcher&& rhs) = default;
~SchemeHostPortMatcher() = default;
// The delimiter used by |ToString()|.
constexpr static char kPrintRuleListDelimiter = ';';
// The delimiters to use when parsing rules.
constexpr static char kParseRuleListDelimiterList[] = ",;";
// Creates a SchemeHostPortMatcher by best-effort parsing each of the
// |kParseRuleListDelimiterList| separated rules. Any rules that could not be
// parsed are silently rejected. It only parses all the rule types that appear
// in scheme_host_port_rules.h, types with other serializations will need to
// be handled by the caller.
static SchemeHostPortMatcher FromRawString(const std::string& raw);
// Returns the current list of rules.
const RuleList& rules() const { return rules_; }
// Add rule to the matcher as the first one in the rule list.
void AddAsFirstRule(std::unique_ptr<SchemeHostPortMatcherRule> rule);
// Add rule to the matcher as the last one in the rule list.
void AddAsLastRule(std::unique_ptr<SchemeHostPortMatcherRule> rule);
// Replace rule on |index| in the internal RuleList.
void ReplaceRule(size_t index,
std::unique_ptr<SchemeHostPortMatcherRule> rule);
// Returns true if |url| was positively matched by the rules.
bool Includes(const GURL& url) const;
// Returns the result of evaluating the rule list. Prefer using Includes()
// over this function. Evaluate() can be used when the caller needs to
// distinguish when matches were due to negative rules.
SchemeHostPortMatcherResult Evaluate(const GURL& url) const;
// Serializes the rules to a string representation. The serialized
// representation is a |kPrintRuleListDelimiter| delimited list of rules,
// where each rule defines its own serialization.
std::string ToString() const;
// Removes all the rules.
void Clear();
private:
RuleList rules_;
};
} // namespace net
#endif // NET_BASE_SCHEME_HOST_PORT_MATCHER_H_
...@@ -6,6 +6,9 @@ ...@@ -6,6 +6,9 @@
#include "base/strings/pattern.h" #include "base/strings/pattern.h"
#include "base/strings/stringprintf.h" #include "base/strings/stringprintf.h"
#include "net/base/host_port_pair.h"
#include "net/base/parse_number.h"
#include "net/base/url_util.h"
#include "url/url_util.h" #include "url/url_util.h"
namespace net { namespace net {
...@@ -21,6 +24,79 @@ std::string AddBracketsIfIPv6(const IPAddress& ip_address) { ...@@ -21,6 +24,79 @@ std::string AddBracketsIfIPv6(const IPAddress& ip_address) {
} // namespace } // namespace
// static
std::unique_ptr<SchemeHostPortMatcherRule>
SchemeHostPortMatcherRule::FromUntrimmedRawString(
const std::string& raw_untrimmed) {
std::string raw;
base::TrimWhitespaceASCII(raw_untrimmed, base::TRIM_ALL, &raw);
// Extract any scheme-restriction.
std::string::size_type scheme_pos = raw.find("://");
std::string scheme;
if (scheme_pos != std::string::npos) {
scheme = raw.substr(0, scheme_pos);
raw = raw.substr(scheme_pos + 3);
if (scheme.empty())
return nullptr;
}
if (raw.empty())
return nullptr;
// If there is a forward slash in the input, it is probably a CIDR style
// mask.
if (raw.find('/') != std::string::npos) {
IPAddress ip_prefix;
size_t prefix_length_in_bits;
if (!ParseCIDRBlock(raw, &ip_prefix, &prefix_length_in_bits))
return nullptr;
return std::make_unique<SchemeHostPortMatcherIPBlockRule>(
raw, scheme, ip_prefix, prefix_length_in_bits);
}
// Check if we have an <ip-address>[:port] input. We need to treat this
// separately since the IP literal may not be in a canonical form.
std::string host;
int port;
if (ParseHostAndPort(raw, &host, &port)) {
// TODO(eroman): HostForURL() below DCHECKs() when |host| contains an
// embedded '\0'.
if (host.find('\0') != std::string::npos)
return nullptr;
IPAddress ip_address;
if (ip_address.AssignFromIPLiteral(host)) {
// Instead of -1, 0 is invalid for IPEndPoint.
int adjusted_port = port == -1 ? 0 : port;
return std::make_unique<SchemeHostPortMatcherIPHostRule>(
scheme, IPEndPoint(ip_address, adjusted_port));
}
}
// Otherwise assume we have <hostname-pattern>[:port].
std::string::size_type pos_colon = raw.rfind(':');
port = -1;
if (pos_colon != std::string::npos) {
if (!ParseInt32(base::StringPiece(raw.begin() + pos_colon + 1, raw.end()),
ParseIntFormat::NON_NEGATIVE, &port) ||
port > 0xFFFF) {
return nullptr; // Port was invalid.
}
raw = raw.substr(0, pos_colon);
}
// Special-case hostnames that begin with a period.
// For example, we remap ".google.com" --> "*.google.com".
if (base::StartsWith(raw, ".", base::CompareCase::SENSITIVE))
raw = "*" + raw;
return std::make_unique<SchemeHostPortMatcherHostnamePatternRule>(scheme, raw,
port);
}
bool SchemeHostPortMatcherRule::IsHostnamePatternRule() const { bool SchemeHostPortMatcherRule::IsHostnamePatternRule() const {
return false; return false;
} }
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
#ifndef NET_BASE_SCHEME_HOST_PORT_MATCHER_RULE_H_ #ifndef NET_BASE_SCHEME_HOST_PORT_MATCHER_RULE_H_
#define NET_BASE_SCHEME_HOST_PORT_MATCHER_RULE_H_ #define NET_BASE_SCHEME_HOST_PORT_MATCHER_RULE_H_
#include <memory>
#include <string> #include <string>
#include "net/base/ip_address.h" #include "net/base/ip_address.h"
...@@ -24,6 +25,14 @@ class NET_EXPORT SchemeHostPortMatcherRule { ...@@ -24,6 +25,14 @@ class NET_EXPORT SchemeHostPortMatcherRule {
delete; delete;
virtual ~SchemeHostPortMatcherRule() = default; virtual ~SchemeHostPortMatcherRule() = default;
// Creates a SchemeHostPortMatcherRule by best-effort parsing the string. If
// it can't parse, returns a nullptr. It only parses all the rule types in
// this header file. Types with other serializations will need to be handled
// by the caller.
static std::unique_ptr<SchemeHostPortMatcherRule> FromUntrimmedRawString(
const std::string& raw_untrimmed);
// Evaluates the rule against |url|. // Evaluates the rule against |url|.
virtual SchemeHostPortMatcherResult Evaluate(const GURL& url) const = 0; virtual SchemeHostPortMatcherResult Evaluate(const GURL& url) const = 0;
// Returns a string representation of this rule. The returned string will not // Returns a string representation of this rule. The returned string will not
......
// Copyright 2020 The Chromium Authors. All rights reserved.
// 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 "testing/gtest/include/gtest/gtest.h"
namespace net {
namespace {
TEST(SchemeHostPortMatcherTest, ParseMultipleRules) {
SchemeHostPortMatcher matcher =
SchemeHostPortMatcher::FromRawString(".google.com , .foobar.com:30");
EXPECT_EQ(2u, matcher.rules().size());
EXPECT_TRUE(matcher.Includes(GURL("http://baz.google.com:40")));
EXPECT_FALSE(matcher.Includes(GURL("http://google.com:40")));
EXPECT_TRUE(matcher.Includes(GURL("http://bar.foobar.com:30")));
EXPECT_FALSE(matcher.Includes(GURL("http://bar.foobar.com")));
EXPECT_FALSE(matcher.Includes(GURL("http://bar.foobar.com:33")));
}
TEST(SchemeHostPortMatcherTest, WithBadInputs) {
SchemeHostPortMatcher matcher = SchemeHostPortMatcher::FromRawString(
":// , , .google.com , , http://baz");
EXPECT_EQ(2u, matcher.rules().size());
EXPECT_EQ("*.google.com", matcher.rules()[0]->ToString());
EXPECT_EQ("http://baz", matcher.rules()[1]->ToString());
EXPECT_TRUE(matcher.Includes(GURL("http://baz.google.com:40")));
EXPECT_TRUE(matcher.Includes(GURL("http://baz")));
EXPECT_FALSE(matcher.Includes(GURL("http://google.com")));
}
// Tests that URLMatcher does not include logic specific to ProxyBypassRules.
// * Should not implicitly bypass localhost or link-local addresses
// * Should not match proxy bypass specific rules like <-loopback> and <local>
//
// Historically, SchemeHostPortMatcher was refactored out of ProxyBypassRules.
// This test confirms that the layering separation is as expected.
TEST(SchemeHostPortMatcherTest, DoesNotMimicProxyBypassRules) {
// Should not parse <-loopback> as its own rule (will treat it as a hostname
// rule).
SchemeHostPortMatcher matcher =
SchemeHostPortMatcher::FromRawString("<-loopback>");
EXPECT_EQ(1u, matcher.rules().size());
EXPECT_EQ("<-loopback>", matcher.rules().front()->ToString());
// Should not parse <local> as its own rule (will treat it as a hostname
// rule).
matcher = SchemeHostPortMatcher::FromRawString("<local>");
EXPECT_EQ(1u, matcher.rules().size());
EXPECT_EQ("<local>", matcher.rules().front()->ToString());
// Should not implicitly match localhost or link-local addresses.
matcher = SchemeHostPortMatcher::FromRawString("www.example.com");
EXPECT_EQ(SchemeHostPortMatcherResult::kNoMatch,
matcher.Evaluate(GURL("http://localhost")));
EXPECT_EQ(SchemeHostPortMatcherResult::kNoMatch,
matcher.Evaluate(GURL("http://169.254.1.1")));
}
} // namespace
} // namespace net
...@@ -4,17 +4,10 @@ ...@@ -4,17 +4,10 @@
#include "net/proxy_resolution/proxy_bypass_rules.h" #include "net/proxy_resolution/proxy_bypass_rules.h"
#include "base/strings/pattern.h"
#include "base/strings/string_piece.h"
#include "base/strings/string_tokenizer.h" #include "base/strings/string_tokenizer.h"
#include "base/strings/string_util.h" #include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "build/build_config.h" #include "build/build_config.h"
#include "net/base/host_port_pair.h"
#include "net/base/ip_address.h"
#include "net/base/parse_number.h"
#include "net/base/url_util.h" #include "net/base/url_util.h"
#include "url/url_util.h"
namespace net { namespace net {
...@@ -118,70 +111,7 @@ std::unique_ptr<SchemeHostPortMatcherRule> ParseRule( ...@@ -118,70 +111,7 @@ std::unique_ptr<SchemeHostPortMatcherRule> ParseRule(
if (base::LowerCaseEqualsASCII(raw, kSubtractImplicitBypasses)) if (base::LowerCaseEqualsASCII(raw, kSubtractImplicitBypasses))
return std::make_unique<SubtractImplicitBypassesRule>(); return std::make_unique<SubtractImplicitBypassesRule>();
// Extract any scheme-restriction. return SchemeHostPortMatcherRule::FromUntrimmedRawString(raw_untrimmed);
std::string::size_type scheme_pos = raw.find("://");
std::string scheme;
if (scheme_pos != std::string::npos) {
scheme = raw.substr(0, scheme_pos);
raw = raw.substr(scheme_pos + 3);
if (scheme.empty())
return nullptr;
}
if (raw.empty())
return nullptr;
// If there is a forward slash in the input, it is probably a CIDR style
// mask.
if (raw.find('/') != std::string::npos) {
IPAddress ip_prefix;
size_t prefix_length_in_bits;
if (!ParseCIDRBlock(raw, &ip_prefix, &prefix_length_in_bits))
return nullptr;
return std::make_unique<SchemeHostPortMatcherIPBlockRule>(
raw, scheme, ip_prefix, prefix_length_in_bits);
}
// Check if we have an <ip-address>[:port] input. We need to treat this
// separately since the IP literal may not be in a canonical form.
std::string host;
int port;
if (ParseHostAndPort(raw, &host, &port)) {
// TODO(eroman): HostForURL() below DCHECKs() when |host| contains an
// embedded NULL.
if (host.find('\0') != std::string::npos)
return nullptr;
IPAddress ip_address;
if (ip_address.AssignFromIPLiteral(host)) {
// Instead of -1, 0 is invalid for IPEndPoint.
int adjusted_port = port == -1 ? 0 : port;
return std::make_unique<SchemeHostPortMatcherIPHostRule>(
scheme, IPEndPoint(ip_address, adjusted_port));
}
}
// Otherwise assume we have <hostname-pattern>[:port].
std::string::size_type pos_colon = raw.rfind(':');
port = -1;
if (pos_colon != std::string::npos) {
if (!ParseInt32(base::StringPiece(raw.begin() + pos_colon + 1, raw.end()),
ParseIntFormat::NON_NEGATIVE, &port) ||
port > 0xFFFF) {
return nullptr; // Port was invalid.
}
raw = raw.substr(0, pos_colon);
}
// Special-case hostnames that begin with a period.
// For example, we remap ".google.com" --> "*.google.com".
if (base::StartsWith(raw, ".", base::CompareCase::SENSITIVE))
raw = "*" + raw;
return std::make_unique<SchemeHostPortMatcherHostnamePatternRule>(scheme, raw,
port);
} }
} // namespace } // namespace
...@@ -206,48 +136,24 @@ ProxyBypassRules& ProxyBypassRules::operator=(const ProxyBypassRules& rhs) { ...@@ -206,48 +136,24 @@ ProxyBypassRules& ProxyBypassRules::operator=(const ProxyBypassRules& rhs) {
} }
ProxyBypassRules& ProxyBypassRules::operator=(ProxyBypassRules&& rhs) { ProxyBypassRules& ProxyBypassRules::operator=(ProxyBypassRules&& rhs) {
rules_ = std::move(rhs.rules_); matcher_ = std::move(rhs.matcher_);
return *this; return *this;
} }
void ProxyBypassRules::ReplaceRule( void ProxyBypassRules::ReplaceRule(
size_t index, size_t index,
std::unique_ptr<SchemeHostPortMatcherRule> rule) { std::unique_ptr<SchemeHostPortMatcherRule> rule) {
DCHECK_LT(index, rules_.size()); matcher_.ReplaceRule(index, std::move(rule));
rules_[index] = std::move(rule);
} }
bool ProxyBypassRules::Matches(const GURL& url, bool reverse) const { bool ProxyBypassRules::Matches(const GURL& url, bool reverse) const {
// Later rules override earlier rules, so evaluating the rule list can be switch (matcher_.Evaluate(url)) {
// done by iterating over it in reverse and short-circuiting when a match is case SchemeHostPortMatcherResult::kInclude:
// found. If no matches are found then the implicit rules are consulted. return !reverse;
// case SchemeHostPortMatcherResult::kExclude:
// The order of evaluation generally doesn't matter, since the common return reverse;
// case is to have a set of (positive) bypass rules., case SchemeHostPortMatcherResult::kNoMatch:
// break;
// However when mixing positive and negative bypass rules evaluation
// order makes a difference. The chosen evaluation order here matches
// WinInet (which supports <-loopback> as a negative rule).
//
// Consider these two rule lists:
// (a) "localhost; <-loopback>"
// (b) "<-loopback>; localhost"
//
// The expectation is that Matches("http://localhost/") returns false
// for (a) since the final rule <-loopback> unbypasses it. Whereas it is
// expected to return true for (b), since the final rule "localhost"
// bypasses it again.
for (auto it = rules_.rbegin(); it != rules_.rend(); ++it) {
const std::unique_ptr<SchemeHostPortMatcherRule>& rule = *it;
switch (rule->Evaluate(url)) {
case SchemeHostPortMatcherResult::kInclude:
return !reverse;
case SchemeHostPortMatcherResult::kExclude:
return reverse;
case SchemeHostPortMatcherResult::kNoMatch:
continue;
}
} }
// If none of the explicit rules matched, fall back to the implicit rules. // If none of the explicit rules matched, fall back to the implicit rules.
...@@ -259,11 +165,11 @@ bool ProxyBypassRules::Matches(const GURL& url, bool reverse) const { ...@@ -259,11 +165,11 @@ bool ProxyBypassRules::Matches(const GURL& url, bool reverse) const {
} }
bool ProxyBypassRules::operator==(const ProxyBypassRules& other) const { bool ProxyBypassRules::operator==(const ProxyBypassRules& other) const {
if (rules_.size() != other.rules_.size()) if (rules().size() != other.rules().size())
return false; return false;
for (size_t i = 0; i < rules_.size(); ++i) { for (size_t i = 0; i < rules().size(); ++i) {
if (rules_[i]->ToString() != other.rules_[i]->ToString()) if (rules()[i]->ToString() != other.rules()[i]->ToString())
return false; return false;
} }
return true; return true;
...@@ -272,7 +178,8 @@ bool ProxyBypassRules::operator==(const ProxyBypassRules& other) const { ...@@ -272,7 +178,8 @@ bool ProxyBypassRules::operator==(const ProxyBypassRules& other) const {
void ProxyBypassRules::ParseFromString(const std::string& raw) { void ProxyBypassRules::ParseFromString(const std::string& raw) {
Clear(); Clear();
base::StringTokenizer entries(raw, ",;"); base::StringTokenizer entries(
raw, SchemeHostPortMatcher::kParseRuleListDelimiterList);
while (entries.GetNext()) { while (entries.GetNext()) {
AddRuleFromString(entries.token()); AddRuleFromString(entries.token());
} }
...@@ -284,20 +191,21 @@ bool ProxyBypassRules::AddRuleForHostname(const std::string& optional_scheme, ...@@ -284,20 +191,21 @@ bool ProxyBypassRules::AddRuleForHostname(const std::string& optional_scheme,
if (hostname_pattern.empty()) if (hostname_pattern.empty())
return false; return false;
rules_.push_back(std::make_unique<SchemeHostPortMatcherHostnamePatternRule>( matcher_.AddAsLastRule(
optional_scheme, hostname_pattern, optional_port)); std::make_unique<SchemeHostPortMatcherHostnamePatternRule>(
optional_scheme, hostname_pattern, optional_port));
return true; return true;
} }
void ProxyBypassRules::PrependRuleToBypassSimpleHostnames() { void ProxyBypassRules::PrependRuleToBypassSimpleHostnames() {
rules_.insert(rules_.begin(), std::make_unique<BypassSimpleHostnamesRule>()); matcher_.AddAsFirstRule(std::make_unique<BypassSimpleHostnamesRule>());
} }
bool ProxyBypassRules::AddRuleFromString(const std::string& raw_untrimmed) { bool ProxyBypassRules::AddRuleFromString(const std::string& raw_untrimmed) {
auto rule = ParseRule(raw_untrimmed); auto rule = ParseRule(raw_untrimmed);
if (rule) { if (rule) {
rules_.push_back(std::move(rule)); matcher_.AddAsLastRule(std::move(rule));
return true; return true;
} }
...@@ -305,7 +213,7 @@ bool ProxyBypassRules::AddRuleFromString(const std::string& raw_untrimmed) { ...@@ -305,7 +213,7 @@ bool ProxyBypassRules::AddRuleFromString(const std::string& raw_untrimmed) {
} }
void ProxyBypassRules::AddRulesToSubtractImplicit() { void ProxyBypassRules::AddRulesToSubtractImplicit() {
rules_.push_back(std::make_unique<SubtractImplicitBypassesRule>()); matcher_.AddAsLastRule(std::make_unique<SubtractImplicitBypassesRule>());
} }
std::string ProxyBypassRules::GetRulesToSubtractImplicit() { std::string ProxyBypassRules::GetRulesToSubtractImplicit() {
...@@ -315,16 +223,11 @@ std::string ProxyBypassRules::GetRulesToSubtractImplicit() { ...@@ -315,16 +223,11 @@ std::string ProxyBypassRules::GetRulesToSubtractImplicit() {
} }
std::string ProxyBypassRules::ToString() const { std::string ProxyBypassRules::ToString() const {
std::string result; return matcher_.ToString();
for (auto rule(rules_.begin()); rule != rules_.end(); ++rule) {
result += (*rule)->ToString();
result += kBypassListDelimeter;
}
return result;
} }
void ProxyBypassRules::Clear() { void ProxyBypassRules::Clear() {
rules_.clear(); matcher_.Clear();
} }
bool ProxyBypassRules::MatchesImplicitRules(const GURL& url) { bool ProxyBypassRules::MatchesImplicitRules(const GURL& url) {
......
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#include "base/macros.h" #include "base/macros.h"
#include "net/base/net_export.h" #include "net/base/net_export.h"
#include "net/base/scheme_host_port_matcher.h"
#include "net/base/scheme_host_port_matcher_rule.h" #include "net/base/scheme_host_port_matcher_rule.h"
#include "url/gurl.h" #include "url/gurl.h"
...@@ -32,8 +33,6 @@ namespace net { ...@@ -32,8 +33,6 @@ namespace net {
// MatchesImplicitRules() for details. // MatchesImplicitRules() for details.
class NET_EXPORT ProxyBypassRules { class NET_EXPORT ProxyBypassRules {
public: public:
typedef std::vector<std::unique_ptr<SchemeHostPortMatcherRule>> RuleList;
// Note: This class supports copy constructor and assignment. // Note: This class supports copy constructor and assignment.
ProxyBypassRules(); ProxyBypassRules();
ProxyBypassRules(const ProxyBypassRules& rhs); ProxyBypassRules(const ProxyBypassRules& rhs);
...@@ -45,7 +44,9 @@ class NET_EXPORT ProxyBypassRules { ...@@ -45,7 +44,9 @@ class NET_EXPORT ProxyBypassRules {
// Returns the current list of rules. The rules list contains pointers // Returns the current list of rules. The rules list contains pointers
// which are owned by this class, callers should NOT keep references // which are owned by this class, callers should NOT keep references
// or delete them. // or delete them.
const RuleList& rules() const { return rules_; } const SchemeHostPortMatcher::RuleList& rules() const {
return matcher_.rules();
}
// Replace rule on |index| in the internal RuleList. // Replace rule on |index| in the internal RuleList.
void ReplaceRule(size_t index, void ReplaceRule(size_t index,
...@@ -125,7 +126,7 @@ class NET_EXPORT ProxyBypassRules { ...@@ -125,7 +126,7 @@ class NET_EXPORT ProxyBypassRules {
constexpr static char kBypassListDelimeter[] = ";"; constexpr static char kBypassListDelimeter[] = ";";
private: private:
RuleList rules_; SchemeHostPortMatcher matcher_;
}; };
} // namespace net } // namespace net
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment