15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2011 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/proxy/proxy_bypass_rules.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/stl_util.h" 85e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)#include "base/strings/string_number_conversions.h" 95e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)#include "base/strings/string_util.h" 105e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)#include "base/strings/stringprintf.h" 11c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/strings/string_piece.h" 122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/strings/string_tokenizer.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/net_util.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace net { 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class HostnamePatternRule : public ProxyBypassRules::Rule { 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HostnamePatternRule(const std::string& optional_scheme, 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& hostname_pattern, 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int optional_port) 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : optional_scheme_(StringToLowerASCII(optional_scheme)), 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hostname_pattern_(StringToLowerASCII(hostname_pattern)), 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) optional_port_(optional_port) { 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual bool Matches(const GURL& url) const OVERRIDE { 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (optional_port_ != -1 && url.EffectiveIntPort() != optional_port_) 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; // Didn't match port expectation. 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!optional_scheme_.empty() && url.scheme() != optional_scheme_) 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; // Didn't match scheme expectation. 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Note it is necessary to lower-case the host, since GURL uses capital 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // letters for percent-escaped characters. 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return MatchPattern(StringToLowerASCII(url.host()), hostname_pattern_); 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual std::string ToString() const OVERRIDE { 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string str; 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!optional_scheme_.empty()) 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::StringAppendF(&str, "%s://", optional_scheme_.c_str()); 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) str += hostname_pattern_; 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (optional_port_ != -1) 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::StringAppendF(&str, ":%d", optional_port_); 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return str; 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual Rule* Clone() const OVERRIDE { 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return new HostnamePatternRule(optional_scheme_, 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hostname_pattern_, 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) optional_port_); 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string optional_scheme_; 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string hostname_pattern_; 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int optional_port_; 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class BypassLocalRule : public ProxyBypassRules::Rule { 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual bool Matches(const GURL& url) const OVERRIDE { 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& host = url.host(); 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (host == "127.0.0.1" || host == "[::1]") 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return host.find('.') == std::string::npos; 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual std::string ToString() const OVERRIDE { 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return "<local>"; 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual Rule* Clone() const OVERRIDE { 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return new BypassLocalRule(); 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Rule for matching a URL that is an IP address, if that IP address falls 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// within a certain numeric range. For example, you could use this rule to 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// match all the IPs in the CIDR block 10.10.3.4/24. 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class BypassIPBlockRule : public ProxyBypassRules::Rule { 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |ip_prefix| + |prefix_length| define the IP block to match. 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BypassIPBlockRule(const std::string& description, 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& optional_scheme, 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const IPAddressNumber& ip_prefix, 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t prefix_length_in_bits) 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : description_(description), 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) optional_scheme_(optional_scheme), 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ip_prefix_(ip_prefix), 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) prefix_length_in_bits_(prefix_length_in_bits) { 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual bool Matches(const GURL& url) const OVERRIDE { 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!url.HostIsIPAddress()) 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!optional_scheme_.empty() && url.scheme() != optional_scheme_) 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; // Didn't match scheme expectation. 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Parse the input IP literal to a number. 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPAddressNumber ip_number; 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!ParseIPLiteralToNumber(url.HostNoBrackets(), &ip_number)) 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Test if it has the expected prefix. 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return IPNumberMatchesPrefix(ip_number, ip_prefix_, 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) prefix_length_in_bits_); 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual std::string ToString() const OVERRIDE { 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return description_; 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual Rule* Clone() const OVERRIDE { 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return new BypassIPBlockRule(description_, 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) optional_scheme_, 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ip_prefix_, 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) prefix_length_in_bits_); 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string description_; 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string optional_scheme_; 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const IPAddressNumber ip_prefix_; 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const size_t prefix_length_in_bits_; 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Returns true if the given string represents an IP address. 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool IsIPAddress(const std::string& domain) { 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // From GURL::HostIsIPAddress() 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) url_canon::RawCanonOutputT<char, 128> ignored_output; 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) url_canon::CanonHostInfo host_info; 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) url_parse::Component domain_comp(0, domain.size()); 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) url_canon::CanonicalizeIPAddress(domain.c_str(), domain_comp, 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &ignored_output, &host_info); 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return host_info.IsIPAddress(); 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ProxyBypassRules::Rule::Rule() { 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ProxyBypassRules::Rule::~Rule() { 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ProxyBypassRules::Rule::Equals(const Rule& rule) const { 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ToString() == rule.ToString(); 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ProxyBypassRules::ProxyBypassRules() { 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ProxyBypassRules::ProxyBypassRules(const ProxyBypassRules& rhs) { 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AssignFrom(rhs); 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ProxyBypassRules::~ProxyBypassRules() { 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Clear(); 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ProxyBypassRules& ProxyBypassRules::operator=(const ProxyBypassRules& rhs) { 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AssignFrom(rhs); 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return *this; 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ProxyBypassRules::Matches(const GURL& url) const { 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (RuleList::const_iterator it = rules_.begin(); it != rules_.end(); ++it) { 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((*it)->Matches(url)) 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ProxyBypassRules::Equals(const ProxyBypassRules& other) const { 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rules_.size() != other.rules_.size()) 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < rules_.size(); ++i) { 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!rules_[i]->Equals(*other.rules_[i])) 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ProxyBypassRules::ParseFromString(const std::string& raw) { 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ParseFromStringInternal(raw, false); 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ProxyBypassRules::ParseFromStringUsingSuffixMatching( 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& raw) { 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ParseFromStringInternal(raw, true); 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ProxyBypassRules::AddRuleForHostname(const std::string& optional_scheme, 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& hostname_pattern, 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int optional_port) { 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (hostname_pattern.empty()) 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rules_.push_back(new HostnamePatternRule(optional_scheme, 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hostname_pattern, 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) optional_port)); 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ProxyBypassRules::AddRuleToBypassLocal() { 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rules_.push_back(new BypassLocalRule); 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ProxyBypassRules::AddRuleFromString(const std::string& raw) { 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return AddRuleFromStringInternalWithLogging(raw, false); 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ProxyBypassRules::AddRuleFromStringUsingSuffixMatching( 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& raw) { 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return AddRuleFromStringInternalWithLogging(raw, true); 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string ProxyBypassRules::ToString() const { 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string result; 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (RuleList::const_iterator rule(rules_.begin()); 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rule != rules_.end(); 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++rule) { 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result += (*rule)->ToString(); 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result += ";"; 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return result; 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ProxyBypassRules::Clear() { 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) STLDeleteElements(&rules_); 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ProxyBypassRules::AssignFrom(const ProxyBypassRules& other) { 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Clear(); 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Make a copy of the rules list. 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (RuleList::const_iterator it = other.rules_.begin(); 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) it != other.rules_.end(); ++it) { 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rules_.push_back((*it)->Clone()); 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ProxyBypassRules::ParseFromStringInternal( 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& raw, 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool use_hostname_suffix_matching) { 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Clear(); 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::StringTokenizer entries(raw, ",;"); 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (entries.GetNext()) { 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddRuleFromStringInternalWithLogging(entries.token(), 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) use_hostname_suffix_matching); 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ProxyBypassRules::AddRuleFromStringInternal( 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& raw_untrimmed, 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool use_hostname_suffix_matching) { 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string raw; 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TrimWhitespaceASCII(raw_untrimmed, TRIM_ALL, &raw); 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This is the special syntax used by WinInet's bypass list -- we allow it 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // on all platforms and interpret it the same way. 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (LowerCaseEqualsASCII(raw, "<local>")) { 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddRuleToBypassLocal(); 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Extract any scheme-restriction. 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string::size_type scheme_pos = raw.find("://"); 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string scheme; 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (scheme_pos != std::string::npos) { 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scheme = raw.substr(0, scheme_pos); 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) raw = raw.substr(scheme_pos + 3); 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (scheme.empty()) 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (raw.empty()) 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If there is a forward slash in the input, it is probably a CIDR style 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // mask. 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (raw.find('/') != std::string::npos) { 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPAddressNumber ip_prefix; 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t prefix_length_in_bits; 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!ParseCIDRBlock(raw, &ip_prefix, &prefix_length_in_bits)) 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rules_.push_back( 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new BypassIPBlockRule(raw, scheme, ip_prefix, prefix_length_in_bits)); 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Check if we have an <ip-address>[:port] input. We need to treat this 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // separately since the IP literal may not be in a canonical form. 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string host; 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int port; 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ParseHostAndPort(raw, &host, &port)) { 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (IsIPAddress(host)) { 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Canonicalize the IP literal before adding it as a string pattern. 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GURL tmp_url("http://" + host); 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return AddRuleForHostname(scheme, tmp_url.host(), port); 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Otherwise assume we have <hostname-pattern>[:port]. 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string::size_type pos_colon = raw.rfind(':'); 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) host = raw; 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) port = -1; 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (pos_colon != std::string::npos) { 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!base::StringToInt(base::StringPiece(raw.begin() + pos_colon + 1, 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) raw.end()), 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &port) || 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (port < 0 || port > 0xFFFF)) { 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; // Port was invalid. 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) raw = raw.substr(0, pos_colon); 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Special-case hostnames that begin with a period. 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // For example, we remap ".google.com" --> "*.google.com". 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (StartsWithASCII(raw, ".", false)) 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) raw = "*" + raw; 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If suffix matching was asked for, make sure the pattern starts with a 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // wildcard. 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (use_hostname_suffix_matching && !StartsWithASCII(raw, "*", false)) 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) raw = "*" + raw; 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return AddRuleForHostname(scheme, raw, port); 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ProxyBypassRules::AddRuleFromStringInternalWithLogging( 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& raw, 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool use_hostname_suffix_matching) { 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return AddRuleFromStringInternal(raw, use_hostname_suffix_matching); 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace net 348