| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 "net/proxy/proxy_bypass_rules.h" | 5 #include "net/proxy/proxy_bypass_rules.h" |
| 6 | 6 |
| 7 #include "base/stl_util.h" | 7 #include "base/stl_util.h" |
| 8 #include "base/strings/string_number_conversions.h" | 8 #include "base/strings/string_number_conversions.h" |
| 9 #include "base/strings/string_util.h" | 9 #include "base/strings/string_util.h" |
| 10 #include "base/strings/stringprintf.h" | 10 #include "base/strings/stringprintf.h" |
| 11 #include "base/strings/string_piece.h" | 11 #include "base/strings/string_piece.h" |
| 12 #include "base/strings/string_tokenizer.h" | 12 #include "base/strings/string_tokenizer.h" |
| 13 #include "net/base/net_util.h" | 13 #include "net/base/net_util.h" |
| 14 | 14 |
| 15 namespace net { | 15 namespace net { |
| 16 | 16 |
| 17 namespace { | 17 namespace { |
| 18 | 18 |
| 19 class HostnamePatternRule : public ProxyBypassRules::Rule { | 19 class HostnamePatternRule : public ProxyBypassRules::Rule { |
| 20 public: | 20 public: |
| 21 HostnamePatternRule(const std::string& optional_scheme, | 21 HostnamePatternRule(const std::string& optional_scheme, |
| 22 const std::string& hostname_pattern, | 22 const std::string& hostname_pattern, |
| 23 int optional_port) | 23 int optional_port) |
| 24 : optional_scheme_(StringToLowerASCII(optional_scheme)), | 24 : optional_scheme_(StringToLowerASCII(optional_scheme)), |
| 25 hostname_pattern_(StringToLowerASCII(hostname_pattern)), | 25 hostname_pattern_(StringToLowerASCII(hostname_pattern)), |
| 26 optional_port_(optional_port) { | 26 optional_port_(optional_port) {} |
| 27 } | |
| 28 | 27 |
| 29 virtual bool Matches(const GURL& url) const OVERRIDE { | 28 virtual bool Matches(const GURL& url) const OVERRIDE { |
| 30 if (optional_port_ != -1 && url.EffectiveIntPort() != optional_port_) | 29 if (optional_port_ != -1 && url.EffectiveIntPort() != optional_port_) |
| 31 return false; // Didn't match port expectation. | 30 return false; // Didn't match port expectation. |
| 32 | 31 |
| 33 if (!optional_scheme_.empty() && url.scheme() != optional_scheme_) | 32 if (!optional_scheme_.empty() && url.scheme() != optional_scheme_) |
| 34 return false; // Didn't match scheme expectation. | 33 return false; // Didn't match scheme expectation. |
| 35 | 34 |
| 36 // Note it is necessary to lower-case the host, since GURL uses capital | 35 // Note it is necessary to lower-case the host, since GURL uses capital |
| 37 // letters for percent-escaped characters. | 36 // letters for percent-escaped characters. |
| 38 return MatchPattern(StringToLowerASCII(url.host()), hostname_pattern_); | 37 return MatchPattern(StringToLowerASCII(url.host()), hostname_pattern_); |
| 39 } | 38 } |
| 40 | 39 |
| 41 virtual std::string ToString() const OVERRIDE { | 40 virtual std::string ToString() const OVERRIDE { |
| 42 std::string str; | 41 std::string str; |
| 43 if (!optional_scheme_.empty()) | 42 if (!optional_scheme_.empty()) |
| 44 base::StringAppendF(&str, "%s://", optional_scheme_.c_str()); | 43 base::StringAppendF(&str, "%s://", optional_scheme_.c_str()); |
| 45 str += hostname_pattern_; | 44 str += hostname_pattern_; |
| 46 if (optional_port_ != -1) | 45 if (optional_port_ != -1) |
| 47 base::StringAppendF(&str, ":%d", optional_port_); | 46 base::StringAppendF(&str, ":%d", optional_port_); |
| 48 return str; | 47 return str; |
| 49 } | 48 } |
| 50 | 49 |
| 51 virtual Rule* Clone() const OVERRIDE { | 50 virtual Rule* Clone() const OVERRIDE { |
| 52 return new HostnamePatternRule(optional_scheme_, | 51 return new HostnamePatternRule( |
| 53 hostname_pattern_, | 52 optional_scheme_, hostname_pattern_, optional_port_); |
| 54 optional_port_); | |
| 55 } | 53 } |
| 56 | 54 |
| 57 private: | 55 private: |
| 58 const std::string optional_scheme_; | 56 const std::string optional_scheme_; |
| 59 const std::string hostname_pattern_; | 57 const std::string hostname_pattern_; |
| 60 const int optional_port_; | 58 const int optional_port_; |
| 61 }; | 59 }; |
| 62 | 60 |
| 63 class BypassLocalRule : public ProxyBypassRules::Rule { | 61 class BypassLocalRule : public ProxyBypassRules::Rule { |
| 64 public: | 62 public: |
| 65 virtual bool Matches(const GURL& url) const OVERRIDE { | 63 virtual bool Matches(const GURL& url) const OVERRIDE { |
| 66 const std::string& host = url.host(); | 64 const std::string& host = url.host(); |
| 67 if (host == "127.0.0.1" || host == "[::1]") | 65 if (host == "127.0.0.1" || host == "[::1]") |
| 68 return true; | 66 return true; |
| 69 return host.find('.') == std::string::npos; | 67 return host.find('.') == std::string::npos; |
| 70 } | 68 } |
| 71 | 69 |
| 72 virtual std::string ToString() const OVERRIDE { | 70 virtual std::string ToString() const OVERRIDE { return "<local>"; } |
| 73 return "<local>"; | |
| 74 } | |
| 75 | 71 |
| 76 virtual Rule* Clone() const OVERRIDE { | 72 virtual Rule* Clone() const OVERRIDE { return new BypassLocalRule(); } |
| 77 return new BypassLocalRule(); | |
| 78 } | |
| 79 }; | 73 }; |
| 80 | 74 |
| 81 // Rule for matching a URL that is an IP address, if that IP address falls | 75 // Rule for matching a URL that is an IP address, if that IP address falls |
| 82 // within a certain numeric range. For example, you could use this rule to | 76 // within a certain numeric range. For example, you could use this rule to |
| 83 // match all the IPs in the CIDR block 10.10.3.4/24. | 77 // match all the IPs in the CIDR block 10.10.3.4/24. |
| 84 class BypassIPBlockRule : public ProxyBypassRules::Rule { | 78 class BypassIPBlockRule : public ProxyBypassRules::Rule { |
| 85 public: | 79 public: |
| 86 // |ip_prefix| + |prefix_length| define the IP block to match. | 80 // |ip_prefix| + |prefix_length| define the IP block to match. |
| 87 BypassIPBlockRule(const std::string& description, | 81 BypassIPBlockRule(const std::string& description, |
| 88 const std::string& optional_scheme, | 82 const std::string& optional_scheme, |
| 89 const IPAddressNumber& ip_prefix, | 83 const IPAddressNumber& ip_prefix, |
| 90 size_t prefix_length_in_bits) | 84 size_t prefix_length_in_bits) |
| 91 : description_(description), | 85 : description_(description), |
| 92 optional_scheme_(optional_scheme), | 86 optional_scheme_(optional_scheme), |
| 93 ip_prefix_(ip_prefix), | 87 ip_prefix_(ip_prefix), |
| 94 prefix_length_in_bits_(prefix_length_in_bits) { | 88 prefix_length_in_bits_(prefix_length_in_bits) {} |
| 95 } | |
| 96 | 89 |
| 97 virtual bool Matches(const GURL& url) const OVERRIDE { | 90 virtual bool Matches(const GURL& url) const OVERRIDE { |
| 98 if (!url.HostIsIPAddress()) | 91 if (!url.HostIsIPAddress()) |
| 99 return false; | 92 return false; |
| 100 | 93 |
| 101 if (!optional_scheme_.empty() && url.scheme() != optional_scheme_) | 94 if (!optional_scheme_.empty() && url.scheme() != optional_scheme_) |
| 102 return false; // Didn't match scheme expectation. | 95 return false; // Didn't match scheme expectation. |
| 103 | 96 |
| 104 // Parse the input IP literal to a number. | 97 // Parse the input IP literal to a number. |
| 105 IPAddressNumber ip_number; | 98 IPAddressNumber ip_number; |
| 106 if (!ParseIPLiteralToNumber(url.HostNoBrackets(), &ip_number)) | 99 if (!ParseIPLiteralToNumber(url.HostNoBrackets(), &ip_number)) |
| 107 return false; | 100 return false; |
| 108 | 101 |
| 109 // Test if it has the expected prefix. | 102 // Test if it has the expected prefix. |
| 110 return IPNumberMatchesPrefix(ip_number, ip_prefix_, | 103 return IPNumberMatchesPrefix(ip_number, ip_prefix_, prefix_length_in_bits_); |
| 111 prefix_length_in_bits_); | |
| 112 } | 104 } |
| 113 | 105 |
| 114 virtual std::string ToString() const OVERRIDE { | 106 virtual std::string ToString() const OVERRIDE { return description_; } |
| 115 return description_; | |
| 116 } | |
| 117 | 107 |
| 118 virtual Rule* Clone() const OVERRIDE { | 108 virtual Rule* Clone() const OVERRIDE { |
| 119 return new BypassIPBlockRule(description_, | 109 return new BypassIPBlockRule( |
| 120 optional_scheme_, | 110 description_, optional_scheme_, ip_prefix_, prefix_length_in_bits_); |
| 121 ip_prefix_, | |
| 122 prefix_length_in_bits_); | |
| 123 } | 111 } |
| 124 | 112 |
| 125 private: | 113 private: |
| 126 const std::string description_; | 114 const std::string description_; |
| 127 const std::string optional_scheme_; | 115 const std::string optional_scheme_; |
| 128 const IPAddressNumber ip_prefix_; | 116 const IPAddressNumber ip_prefix_; |
| 129 const size_t prefix_length_in_bits_; | 117 const size_t prefix_length_in_bits_; |
| 130 }; | 118 }; |
| 131 | 119 |
| 132 // Returns true if the given string represents an IP address. | 120 // Returns true if the given string represents an IP address. |
| 133 bool IsIPAddress(const std::string& domain) { | 121 bool IsIPAddress(const std::string& domain) { |
| 134 // From GURL::HostIsIPAddress() | 122 // From GURL::HostIsIPAddress() |
| 135 url::RawCanonOutputT<char, 128> ignored_output; | 123 url::RawCanonOutputT<char, 128> ignored_output; |
| 136 url::CanonHostInfo host_info; | 124 url::CanonHostInfo host_info; |
| 137 url::Component domain_comp(0, domain.size()); | 125 url::Component domain_comp(0, domain.size()); |
| 138 url::CanonicalizeIPAddress(domain.c_str(), domain_comp, &ignored_output, | 126 url::CanonicalizeIPAddress( |
| 139 &host_info); | 127 domain.c_str(), domain_comp, &ignored_output, &host_info); |
| 140 return host_info.IsIPAddress(); | 128 return host_info.IsIPAddress(); |
| 141 } | 129 } |
| 142 | 130 |
| 143 } // namespace | 131 } // namespace |
| 144 | 132 |
| 145 ProxyBypassRules::Rule::Rule() { | 133 ProxyBypassRules::Rule::Rule() { |
| 146 } | 134 } |
| 147 | 135 |
| 148 ProxyBypassRules::Rule::~Rule() { | 136 ProxyBypassRules::Rule::~Rule() { |
| 149 } | 137 } |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 195 const std::string& raw) { | 183 const std::string& raw) { |
| 196 ParseFromStringInternal(raw, true); | 184 ParseFromStringInternal(raw, true); |
| 197 } | 185 } |
| 198 | 186 |
| 199 bool ProxyBypassRules::AddRuleForHostname(const std::string& optional_scheme, | 187 bool ProxyBypassRules::AddRuleForHostname(const std::string& optional_scheme, |
| 200 const std::string& hostname_pattern, | 188 const std::string& hostname_pattern, |
| 201 int optional_port) { | 189 int optional_port) { |
| 202 if (hostname_pattern.empty()) | 190 if (hostname_pattern.empty()) |
| 203 return false; | 191 return false; |
| 204 | 192 |
| 205 rules_.push_back(new HostnamePatternRule(optional_scheme, | 193 rules_.push_back(new HostnamePatternRule( |
| 206 hostname_pattern, | 194 optional_scheme, hostname_pattern, optional_port)); |
| 207 optional_port)); | |
| 208 return true; | 195 return true; |
| 209 } | 196 } |
| 210 | 197 |
| 211 void ProxyBypassRules::AddRuleToBypassLocal() { | 198 void ProxyBypassRules::AddRuleToBypassLocal() { |
| 212 rules_.push_back(new BypassLocalRule); | 199 rules_.push_back(new BypassLocalRule); |
| 213 } | 200 } |
| 214 | 201 |
| 215 bool ProxyBypassRules::AddRuleFromString(const std::string& raw) { | 202 bool ProxyBypassRules::AddRuleFromString(const std::string& raw) { |
| 216 return AddRuleFromStringInternalWithLogging(raw, false); | 203 return AddRuleFromStringInternalWithLogging(raw, false); |
| 217 } | 204 } |
| 218 | 205 |
| 219 bool ProxyBypassRules::AddRuleFromStringUsingSuffixMatching( | 206 bool ProxyBypassRules::AddRuleFromStringUsingSuffixMatching( |
| 220 const std::string& raw) { | 207 const std::string& raw) { |
| 221 return AddRuleFromStringInternalWithLogging(raw, true); | 208 return AddRuleFromStringInternalWithLogging(raw, true); |
| 222 } | 209 } |
| 223 | 210 |
| 224 std::string ProxyBypassRules::ToString() const { | 211 std::string ProxyBypassRules::ToString() const { |
| 225 std::string result; | 212 std::string result; |
| 226 for (RuleList::const_iterator rule(rules_.begin()); | 213 for (RuleList::const_iterator rule(rules_.begin()); rule != rules_.end(); |
| 227 rule != rules_.end(); | |
| 228 ++rule) { | 214 ++rule) { |
| 229 result += (*rule)->ToString(); | 215 result += (*rule)->ToString(); |
| 230 result += ";"; | 216 result += ";"; |
| 231 } | 217 } |
| 232 return result; | 218 return result; |
| 233 } | 219 } |
| 234 | 220 |
| 235 void ProxyBypassRules::Clear() { | 221 void ProxyBypassRules::Clear() { |
| 236 STLDeleteElements(&rules_); | 222 STLDeleteElements(&rules_); |
| 237 } | 223 } |
| 238 | 224 |
| 239 void ProxyBypassRules::AssignFrom(const ProxyBypassRules& other) { | 225 void ProxyBypassRules::AssignFrom(const ProxyBypassRules& other) { |
| 240 Clear(); | 226 Clear(); |
| 241 | 227 |
| 242 // Make a copy of the rules list. | 228 // Make a copy of the rules list. |
| 243 for (RuleList::const_iterator it = other.rules_.begin(); | 229 for (RuleList::const_iterator it = other.rules_.begin(); |
| 244 it != other.rules_.end(); ++it) { | 230 it != other.rules_.end(); |
| 231 ++it) { |
| 245 rules_.push_back((*it)->Clone()); | 232 rules_.push_back((*it)->Clone()); |
| 246 } | 233 } |
| 247 } | 234 } |
| 248 | 235 |
| 249 void ProxyBypassRules::ParseFromStringInternal( | 236 void ProxyBypassRules::ParseFromStringInternal( |
| 250 const std::string& raw, | 237 const std::string& raw, |
| 251 bool use_hostname_suffix_matching) { | 238 bool use_hostname_suffix_matching) { |
| 252 Clear(); | 239 Clear(); |
| 253 | 240 |
| 254 base::StringTokenizer entries(raw, ",;"); | 241 base::StringTokenizer entries(raw, ",;"); |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 309 GURL tmp_url("http://" + host); | 296 GURL tmp_url("http://" + host); |
| 310 return AddRuleForHostname(scheme, tmp_url.host(), port); | 297 return AddRuleForHostname(scheme, tmp_url.host(), port); |
| 311 } | 298 } |
| 312 } | 299 } |
| 313 | 300 |
| 314 // Otherwise assume we have <hostname-pattern>[:port]. | 301 // Otherwise assume we have <hostname-pattern>[:port]. |
| 315 std::string::size_type pos_colon = raw.rfind(':'); | 302 std::string::size_type pos_colon = raw.rfind(':'); |
| 316 host = raw; | 303 host = raw; |
| 317 port = -1; | 304 port = -1; |
| 318 if (pos_colon != std::string::npos) { | 305 if (pos_colon != std::string::npos) { |
| 319 if (!base::StringToInt(base::StringPiece(raw.begin() + pos_colon + 1, | 306 if (!base::StringToInt( |
| 320 raw.end()), | 307 base::StringPiece(raw.begin() + pos_colon + 1, raw.end()), &port) || |
| 321 &port) || | |
| 322 (port < 0 || port > 0xFFFF)) { | 308 (port < 0 || port > 0xFFFF)) { |
| 323 return false; // Port was invalid. | 309 return false; // Port was invalid. |
| 324 } | 310 } |
| 325 raw = raw.substr(0, pos_colon); | 311 raw = raw.substr(0, pos_colon); |
| 326 } | 312 } |
| 327 | 313 |
| 328 // Special-case hostnames that begin with a period. | 314 // Special-case hostnames that begin with a period. |
| 329 // For example, we remap ".google.com" --> "*.google.com". | 315 // For example, we remap ".google.com" --> "*.google.com". |
| 330 if (StartsWithASCII(raw, ".", false)) | 316 if (StartsWithASCII(raw, ".", false)) |
| 331 raw = "*" + raw; | 317 raw = "*" + raw; |
| 332 | 318 |
| 333 // If suffix matching was asked for, make sure the pattern starts with a | 319 // If suffix matching was asked for, make sure the pattern starts with a |
| 334 // wildcard. | 320 // wildcard. |
| 335 if (use_hostname_suffix_matching && !StartsWithASCII(raw, "*", false)) | 321 if (use_hostname_suffix_matching && !StartsWithASCII(raw, "*", false)) |
| 336 raw = "*" + raw; | 322 raw = "*" + raw; |
| 337 | 323 |
| 338 return AddRuleForHostname(scheme, raw, port); | 324 return AddRuleForHostname(scheme, raw, port); |
| 339 } | 325 } |
| 340 | 326 |
| 341 bool ProxyBypassRules::AddRuleFromStringInternalWithLogging( | 327 bool ProxyBypassRules::AddRuleFromStringInternalWithLogging( |
| 342 const std::string& raw, | 328 const std::string& raw, |
| 343 bool use_hostname_suffix_matching) { | 329 bool use_hostname_suffix_matching) { |
| 344 return AddRuleFromStringInternal(raw, use_hostname_suffix_matching); | 330 return AddRuleFromStringInternal(raw, use_hostname_suffix_matching); |
| 345 } | 331 } |
| 346 | 332 |
| 347 } // namespace net | 333 } // namespace net |
| OLD | NEW |