OLD | NEW |
| (Empty) |
1 // Copyright (c) 2012 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/proxy/proxy_config.h" | |
6 #include "net/proxy/proxy_config_service_common_unittest.h" | |
7 #include "net/proxy/proxy_info.h" | |
8 #include "testing/gtest/include/gtest/gtest.h" | |
9 | |
10 namespace net { | |
11 namespace { | |
12 | |
13 void ExpectProxyServerEquals(const char* expectation, | |
14 const ProxyList& proxy_servers) { | |
15 if (expectation == NULL) { | |
16 EXPECT_TRUE(proxy_servers.IsEmpty()); | |
17 } else { | |
18 EXPECT_EQ(expectation, proxy_servers.ToPacString()); | |
19 } | |
20 } | |
21 | |
22 TEST(ProxyConfigTest, Equals) { | |
23 // Test |ProxyConfig::auto_detect|. | |
24 | |
25 ProxyConfig config1; | |
26 config1.set_auto_detect(true); | |
27 | |
28 ProxyConfig config2; | |
29 config2.set_auto_detect(false); | |
30 | |
31 EXPECT_FALSE(config1.Equals(config2)); | |
32 EXPECT_FALSE(config2.Equals(config1)); | |
33 | |
34 config2.set_auto_detect(true); | |
35 | |
36 EXPECT_TRUE(config1.Equals(config2)); | |
37 EXPECT_TRUE(config2.Equals(config1)); | |
38 | |
39 // Test |ProxyConfig::pac_url|. | |
40 | |
41 config2.set_pac_url(GURL("http://wpad/wpad.dat")); | |
42 | |
43 EXPECT_FALSE(config1.Equals(config2)); | |
44 EXPECT_FALSE(config2.Equals(config1)); | |
45 | |
46 config1.set_pac_url(GURL("http://wpad/wpad.dat")); | |
47 | |
48 EXPECT_TRUE(config1.Equals(config2)); | |
49 EXPECT_TRUE(config2.Equals(config1)); | |
50 | |
51 // Test |ProxyConfig::proxy_rules|. | |
52 | |
53 config2.proxy_rules().type = ProxyConfig::ProxyRules::TYPE_SINGLE_PROXY; | |
54 config2.proxy_rules().single_proxies.SetSingleProxyServer( | |
55 ProxyServer::FromURI("myproxy:80", ProxyServer::SCHEME_HTTP)); | |
56 | |
57 EXPECT_FALSE(config1.Equals(config2)); | |
58 EXPECT_FALSE(config2.Equals(config1)); | |
59 | |
60 config1.proxy_rules().type = ProxyConfig::ProxyRules::TYPE_SINGLE_PROXY; | |
61 config1.proxy_rules().single_proxies.SetSingleProxyServer( | |
62 ProxyServer::FromURI("myproxy:100", ProxyServer::SCHEME_HTTP)); | |
63 | |
64 EXPECT_FALSE(config1.Equals(config2)); | |
65 EXPECT_FALSE(config2.Equals(config1)); | |
66 | |
67 config1.proxy_rules().single_proxies.SetSingleProxyServer( | |
68 ProxyServer::FromURI("myproxy", ProxyServer::SCHEME_HTTP)); | |
69 | |
70 EXPECT_TRUE(config1.Equals(config2)); | |
71 EXPECT_TRUE(config2.Equals(config1)); | |
72 | |
73 // Test |ProxyConfig::bypass_rules|. | |
74 | |
75 config2.proxy_rules().bypass_rules.AddRuleFromString("*.google.com"); | |
76 | |
77 EXPECT_FALSE(config1.Equals(config2)); | |
78 EXPECT_FALSE(config2.Equals(config1)); | |
79 | |
80 config1.proxy_rules().bypass_rules.AddRuleFromString("*.google.com"); | |
81 | |
82 EXPECT_TRUE(config1.Equals(config2)); | |
83 EXPECT_TRUE(config2.Equals(config1)); | |
84 | |
85 // Test |ProxyConfig::proxy_rules.reverse_bypass|. | |
86 | |
87 config2.proxy_rules().reverse_bypass = true; | |
88 | |
89 EXPECT_FALSE(config1.Equals(config2)); | |
90 EXPECT_FALSE(config2.Equals(config1)); | |
91 | |
92 config1.proxy_rules().reverse_bypass = true; | |
93 | |
94 EXPECT_TRUE(config1.Equals(config2)); | |
95 EXPECT_TRUE(config2.Equals(config1)); | |
96 } | |
97 | |
98 TEST(ProxyConfigTest, ParseProxyRules) { | |
99 const struct { | |
100 const char* proxy_rules; | |
101 | |
102 ProxyConfig::ProxyRules::Type type; | |
103 // These will be PAC-stle strings, eg 'PROXY foo.com' | |
104 const char* single_proxy; | |
105 const char* proxy_for_http; | |
106 const char* proxy_for_https; | |
107 const char* proxy_for_ftp; | |
108 const char* fallback_proxy; | |
109 } tests[] = { | |
110 // One HTTP proxy for all schemes. | |
111 { | |
112 "myproxy:80", | |
113 | |
114 ProxyConfig::ProxyRules::TYPE_SINGLE_PROXY, | |
115 "PROXY myproxy:80", | |
116 NULL, | |
117 NULL, | |
118 NULL, | |
119 NULL, | |
120 }, | |
121 | |
122 // Multiple HTTP proxies for all schemes. | |
123 { | |
124 "myproxy:80,https://myotherproxy", | |
125 | |
126 ProxyConfig::ProxyRules::TYPE_SINGLE_PROXY, | |
127 "PROXY myproxy:80;HTTPS myotherproxy:443", | |
128 NULL, | |
129 NULL, | |
130 NULL, | |
131 NULL, | |
132 }, | |
133 | |
134 // Only specify a proxy server for "http://" urls. | |
135 { | |
136 "http=myproxy:80", | |
137 | |
138 ProxyConfig::ProxyRules::TYPE_PROXY_PER_SCHEME, | |
139 NULL, | |
140 "PROXY myproxy:80", | |
141 NULL, | |
142 NULL, | |
143 NULL, | |
144 }, | |
145 | |
146 // Specify an HTTP proxy for "ftp://" and a SOCKS proxy for "https://" urls. | |
147 { | |
148 "ftp=ftp-proxy ; https=socks4://foopy", | |
149 | |
150 ProxyConfig::ProxyRules::TYPE_PROXY_PER_SCHEME, | |
151 NULL, | |
152 NULL, | |
153 "SOCKS foopy:1080", | |
154 "PROXY ftp-proxy:80", | |
155 NULL, | |
156 }, | |
157 | |
158 // Give a scheme-specific proxy as well as a non-scheme specific. | |
159 // The first entry "foopy" takes precedance marking this list as | |
160 // TYPE_SINGLE_PROXY. | |
161 { | |
162 "foopy ; ftp=ftp-proxy", | |
163 | |
164 ProxyConfig::ProxyRules::TYPE_SINGLE_PROXY, | |
165 "PROXY foopy:80", | |
166 NULL, | |
167 NULL, | |
168 NULL, | |
169 NULL, | |
170 }, | |
171 | |
172 // Give a scheme-specific proxy as well as a non-scheme specific. | |
173 // The first entry "ftp=ftp-proxy" takes precedance marking this list as | |
174 // TYPE_PROXY_PER_SCHEME. | |
175 { | |
176 "ftp=ftp-proxy ; foopy", | |
177 | |
178 ProxyConfig::ProxyRules::TYPE_PROXY_PER_SCHEME, | |
179 NULL, | |
180 NULL, | |
181 NULL, | |
182 "PROXY ftp-proxy:80", | |
183 NULL, | |
184 }, | |
185 | |
186 // Include a list of entries for a single scheme. | |
187 { | |
188 "ftp=ftp1,ftp2,ftp3", | |
189 | |
190 ProxyConfig::ProxyRules::TYPE_PROXY_PER_SCHEME, | |
191 NULL, | |
192 NULL, | |
193 NULL, | |
194 "PROXY ftp1:80;PROXY ftp2:80;PROXY ftp3:80", | |
195 NULL, | |
196 }, | |
197 | |
198 // Include multiple entries for the same scheme -- they accumulate. | |
199 { | |
200 "http=http1,http2; http=http3", | |
201 | |
202 ProxyConfig::ProxyRules::TYPE_PROXY_PER_SCHEME, | |
203 NULL, | |
204 "PROXY http1:80;PROXY http2:80;PROXY http3:80", | |
205 NULL, | |
206 NULL, | |
207 NULL, | |
208 }, | |
209 | |
210 // Include lists of entries for multiple schemes. | |
211 { | |
212 "ftp=ftp1,ftp2,ftp3 ; http=http1,http2; ", | |
213 | |
214 ProxyConfig::ProxyRules::TYPE_PROXY_PER_SCHEME, | |
215 NULL, | |
216 "PROXY http1:80;PROXY http2:80", | |
217 NULL, | |
218 "PROXY ftp1:80;PROXY ftp2:80;PROXY ftp3:80", | |
219 NULL, | |
220 }, | |
221 | |
222 // Include non-default proxy schemes. | |
223 { | |
224 "http=https://secure_proxy; ftp=socks4://socks_proxy; https=socks://foo", | |
225 | |
226 ProxyConfig::ProxyRules::TYPE_PROXY_PER_SCHEME, | |
227 NULL, | |
228 "HTTPS secure_proxy:443", | |
229 "SOCKS5 foo:1080", | |
230 "SOCKS socks_proxy:1080", | |
231 NULL, | |
232 }, | |
233 | |
234 // Only SOCKS proxy present, others being blank. | |
235 { | |
236 "socks=foopy", | |
237 | |
238 ProxyConfig::ProxyRules::TYPE_PROXY_PER_SCHEME, | |
239 NULL, | |
240 NULL, | |
241 NULL, | |
242 NULL, | |
243 "SOCKS foopy:1080", | |
244 }, | |
245 | |
246 // SOCKS proxy present along with other proxies too | |
247 { | |
248 "http=httpproxy ; https=httpsproxy ; ftp=ftpproxy ; socks=foopy ", | |
249 | |
250 ProxyConfig::ProxyRules::TYPE_PROXY_PER_SCHEME, | |
251 NULL, | |
252 "PROXY httpproxy:80", | |
253 "PROXY httpsproxy:80", | |
254 "PROXY ftpproxy:80", | |
255 "SOCKS foopy:1080", | |
256 }, | |
257 | |
258 // SOCKS proxy (with modifier) present along with some proxies | |
259 // (FTP being blank) | |
260 { | |
261 "http=httpproxy ; https=httpsproxy ; socks=socks5://foopy ", | |
262 | |
263 ProxyConfig::ProxyRules::TYPE_PROXY_PER_SCHEME, | |
264 NULL, | |
265 "PROXY httpproxy:80", | |
266 "PROXY httpsproxy:80", | |
267 NULL, | |
268 "SOCKS5 foopy:1080", | |
269 }, | |
270 | |
271 // Include unsupported schemes -- they are discarded. | |
272 { | |
273 "crazy=foopy ; foo=bar ; https=myhttpsproxy", | |
274 | |
275 ProxyConfig::ProxyRules::TYPE_PROXY_PER_SCHEME, | |
276 NULL, | |
277 NULL, | |
278 "PROXY myhttpsproxy:80", | |
279 NULL, | |
280 NULL, | |
281 }, | |
282 | |
283 // direct:// as first option for a scheme. | |
284 { | |
285 "http=direct://,myhttpproxy; https=direct://", | |
286 | |
287 ProxyConfig::ProxyRules::TYPE_PROXY_PER_SCHEME, | |
288 NULL, | |
289 "DIRECT;PROXY myhttpproxy:80", | |
290 "DIRECT", | |
291 NULL, | |
292 NULL, | |
293 }, | |
294 | |
295 // direct:// as a second option for a scheme. | |
296 { | |
297 "http=myhttpproxy,direct://", | |
298 | |
299 ProxyConfig::ProxyRules::TYPE_PROXY_PER_SCHEME, | |
300 NULL, | |
301 "PROXY myhttpproxy:80;DIRECT", | |
302 NULL, | |
303 NULL, | |
304 NULL, | |
305 }, | |
306 | |
307 }; | |
308 | |
309 ProxyConfig config; | |
310 | |
311 for (size_t i = 0; i < arraysize(tests); ++i) { | |
312 config.proxy_rules().ParseFromString(tests[i].proxy_rules); | |
313 | |
314 EXPECT_EQ(tests[i].type, config.proxy_rules().type); | |
315 ExpectProxyServerEquals(tests[i].single_proxy, | |
316 config.proxy_rules().single_proxies); | |
317 ExpectProxyServerEquals(tests[i].proxy_for_http, | |
318 config.proxy_rules().proxies_for_http); | |
319 ExpectProxyServerEquals(tests[i].proxy_for_https, | |
320 config.proxy_rules().proxies_for_https); | |
321 ExpectProxyServerEquals(tests[i].proxy_for_ftp, | |
322 config.proxy_rules().proxies_for_ftp); | |
323 ExpectProxyServerEquals(tests[i].fallback_proxy, | |
324 config.proxy_rules().fallback_proxies); | |
325 } | |
326 } | |
327 | |
328 TEST(ProxyConfigTest, ProxyRulesSetBypassFlag) { | |
329 // Test whether the did_bypass_proxy() flag is set in proxy info correctly. | |
330 ProxyConfig::ProxyRules rules; | |
331 ProxyInfo result; | |
332 | |
333 rules.ParseFromString("http=httpproxy:80"); | |
334 rules.bypass_rules.AddRuleFromString(".com"); | |
335 | |
336 rules.Apply(GURL("http://example.com"), &result); | |
337 EXPECT_TRUE(result.is_direct_only()); | |
338 EXPECT_TRUE(result.did_bypass_proxy()); | |
339 | |
340 rules.Apply(GURL("http://example.org"), &result); | |
341 EXPECT_FALSE(result.is_direct()); | |
342 EXPECT_FALSE(result.did_bypass_proxy()); | |
343 | |
344 // Try with reversed bypass rules. | |
345 rules.reverse_bypass = true; | |
346 | |
347 rules.Apply(GURL("http://example.org"), &result); | |
348 EXPECT_TRUE(result.is_direct_only()); | |
349 EXPECT_TRUE(result.did_bypass_proxy()); | |
350 | |
351 rules.Apply(GURL("http://example.com"), &result); | |
352 EXPECT_FALSE(result.is_direct()); | |
353 EXPECT_FALSE(result.did_bypass_proxy()); | |
354 } | |
355 | |
356 static const char kWsUrl[] = "ws://example.com/echo"; | |
357 static const char kWssUrl[] = "wss://example.com/echo"; | |
358 | |
359 class ProxyConfigWebSocketTest : public ::testing::Test { | |
360 protected: | |
361 void ParseFromString(const std::string& rules) { | |
362 rules_.ParseFromString(rules); | |
363 } | |
364 void Apply(const GURL& gurl) { rules_.Apply(gurl, &info_); } | |
365 std::string ToPacString() const { return info_.ToPacString(); } | |
366 | |
367 static GURL WsUrl() { return GURL(kWsUrl); } | |
368 static GURL WssUrl() { return GURL(kWssUrl); } | |
369 | |
370 ProxyConfig::ProxyRules rules_; | |
371 ProxyInfo info_; | |
372 }; | |
373 | |
374 // If a single proxy is set for all protocols, WebSocket uses it. | |
375 TEST_F(ProxyConfigWebSocketTest, UsesProxy) { | |
376 ParseFromString("proxy:3128"); | |
377 Apply(WsUrl()); | |
378 EXPECT_EQ("PROXY proxy:3128", ToPacString()); | |
379 } | |
380 | |
381 // See RFC6455 Section 4.1. item 3, "_Proxy Usage_". | |
382 TEST_F(ProxyConfigWebSocketTest, PrefersSocks) { | |
383 ParseFromString( | |
384 "http=proxy:3128 ; https=sslproxy:3128 ; socks=socksproxy:1080"); | |
385 Apply(WsUrl()); | |
386 EXPECT_EQ("SOCKS socksproxy:1080", ToPacString()); | |
387 } | |
388 | |
389 TEST_F(ProxyConfigWebSocketTest, PrefersHttpsToHttp) { | |
390 ParseFromString("http=proxy:3128 ; https=sslproxy:3128"); | |
391 Apply(WssUrl()); | |
392 EXPECT_EQ("PROXY sslproxy:3128", ToPacString()); | |
393 } | |
394 | |
395 TEST_F(ProxyConfigWebSocketTest, PrefersHttpsEvenForWs) { | |
396 ParseFromString("http=proxy:3128 ; https=sslproxy:3128"); | |
397 Apply(WsUrl()); | |
398 EXPECT_EQ("PROXY sslproxy:3128", ToPacString()); | |
399 } | |
400 | |
401 TEST_F(ProxyConfigWebSocketTest, PrefersHttpToDirect) { | |
402 ParseFromString("http=proxy:3128"); | |
403 Apply(WssUrl()); | |
404 EXPECT_EQ("PROXY proxy:3128", ToPacString()); | |
405 } | |
406 | |
407 TEST_F(ProxyConfigWebSocketTest, IgnoresFtpProxy) { | |
408 ParseFromString("ftp=ftpproxy:3128"); | |
409 Apply(WssUrl()); | |
410 EXPECT_EQ("DIRECT", ToPacString()); | |
411 } | |
412 | |
413 TEST_F(ProxyConfigWebSocketTest, ObeysBypassRules) { | |
414 ParseFromString("http=proxy:3128 ; https=sslproxy:3128"); | |
415 rules_.bypass_rules.AddRuleFromString(".chromium.org"); | |
416 Apply(GURL("wss://codereview.chromium.org/feed")); | |
417 EXPECT_EQ("DIRECT", ToPacString()); | |
418 } | |
419 | |
420 TEST_F(ProxyConfigWebSocketTest, ObeysLocalBypass) { | |
421 ParseFromString("http=proxy:3128 ; https=sslproxy:3128"); | |
422 rules_.bypass_rules.AddRuleFromString("<local>"); | |
423 Apply(GURL("ws://localhost/feed")); | |
424 EXPECT_EQ("DIRECT", ToPacString()); | |
425 } | |
426 | |
427 } // namespace | |
428 } // namespace net | |
OLD | NEW |