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 |