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.
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"
13 void ExpectProxyServerEquals(const char* expectation
,
14 const ProxyList
& proxy_servers
) {
15 if (expectation
== NULL
) {
16 EXPECT_TRUE(proxy_servers
.IsEmpty());
18 EXPECT_EQ(expectation
, proxy_servers
.ToPacString());
22 TEST(ProxyConfigTest
, Equals
) {
23 // Test |ProxyConfig::auto_detect|.
26 config1
.set_auto_detect(true);
29 config2
.set_auto_detect(false);
31 EXPECT_FALSE(config1
.Equals(config2
));
32 EXPECT_FALSE(config2
.Equals(config1
));
34 config2
.set_auto_detect(true);
36 EXPECT_TRUE(config1
.Equals(config2
));
37 EXPECT_TRUE(config2
.Equals(config1
));
39 // Test |ProxyConfig::pac_url|.
41 config2
.set_pac_url(GURL("http://wpad/wpad.dat"));
43 EXPECT_FALSE(config1
.Equals(config2
));
44 EXPECT_FALSE(config2
.Equals(config1
));
46 config1
.set_pac_url(GURL("http://wpad/wpad.dat"));
48 EXPECT_TRUE(config1
.Equals(config2
));
49 EXPECT_TRUE(config2
.Equals(config1
));
51 // Test |ProxyConfig::proxy_rules|.
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
));
57 EXPECT_FALSE(config1
.Equals(config2
));
58 EXPECT_FALSE(config2
.Equals(config1
));
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
));
64 EXPECT_FALSE(config1
.Equals(config2
));
65 EXPECT_FALSE(config2
.Equals(config1
));
67 config1
.proxy_rules().single_proxies
.SetSingleProxyServer(
68 ProxyServer::FromURI("myproxy", ProxyServer::SCHEME_HTTP
));
70 EXPECT_TRUE(config1
.Equals(config2
));
71 EXPECT_TRUE(config2
.Equals(config1
));
73 // Test |ProxyConfig::bypass_rules|.
75 config2
.proxy_rules().bypass_rules
.AddRuleFromString("*.google.com");
77 EXPECT_FALSE(config1
.Equals(config2
));
78 EXPECT_FALSE(config2
.Equals(config1
));
80 config1
.proxy_rules().bypass_rules
.AddRuleFromString("*.google.com");
82 EXPECT_TRUE(config1
.Equals(config2
));
83 EXPECT_TRUE(config2
.Equals(config1
));
85 // Test |ProxyConfig::proxy_rules.reverse_bypass|.
87 config2
.proxy_rules().reverse_bypass
= true;
89 EXPECT_FALSE(config1
.Equals(config2
));
90 EXPECT_FALSE(config2
.Equals(config1
));
92 config1
.proxy_rules().reverse_bypass
= true;
94 EXPECT_TRUE(config1
.Equals(config2
));
95 EXPECT_TRUE(config2
.Equals(config1
));
98 TEST(ProxyConfigTest
, ParseProxyRules
) {
100 const char* proxy_rules
;
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
;
110 // One HTTP proxy for all schemes.
114 ProxyConfig::ProxyRules::TYPE_SINGLE_PROXY
,
122 // Multiple HTTP proxies for all schemes.
124 "myproxy:80,https://myotherproxy",
126 ProxyConfig::ProxyRules::TYPE_SINGLE_PROXY
,
127 "PROXY myproxy:80;HTTPS myotherproxy:443",
134 // Only specify a proxy server for "http://" urls.
138 ProxyConfig::ProxyRules::TYPE_PROXY_PER_SCHEME
,
146 // Specify an HTTP proxy for "ftp://" and a SOCKS proxy for "https://" urls.
148 "ftp=ftp-proxy ; https=socks4://foopy",
150 ProxyConfig::ProxyRules::TYPE_PROXY_PER_SCHEME
,
154 "PROXY ftp-proxy:80",
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.
162 "foopy ; ftp=ftp-proxy",
164 ProxyConfig::ProxyRules::TYPE_SINGLE_PROXY
,
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.
176 "ftp=ftp-proxy ; foopy",
178 ProxyConfig::ProxyRules::TYPE_PROXY_PER_SCHEME
,
182 "PROXY ftp-proxy:80",
186 // Include a list of entries for a single scheme.
188 "ftp=ftp1,ftp2,ftp3",
190 ProxyConfig::ProxyRules::TYPE_PROXY_PER_SCHEME
,
194 "PROXY ftp1:80;PROXY ftp2:80;PROXY ftp3:80",
198 // Include multiple entries for the same scheme -- they accumulate.
200 "http=http1,http2; http=http3",
202 ProxyConfig::ProxyRules::TYPE_PROXY_PER_SCHEME
,
204 "PROXY http1:80;PROXY http2:80;PROXY http3:80",
210 // Include lists of entries for multiple schemes.
212 "ftp=ftp1,ftp2,ftp3 ; http=http1,http2; ",
214 ProxyConfig::ProxyRules::TYPE_PROXY_PER_SCHEME
,
216 "PROXY http1:80;PROXY http2:80",
218 "PROXY ftp1:80;PROXY ftp2:80;PROXY ftp3:80",
222 // Include non-default proxy schemes.
224 "http=https://secure_proxy; ftp=socks4://socks_proxy; https=socks://foo",
226 ProxyConfig::ProxyRules::TYPE_PROXY_PER_SCHEME
,
228 "HTTPS secure_proxy:443",
230 "SOCKS socks_proxy:1080",
234 // Only SOCKS proxy present, others being blank.
238 ProxyConfig::ProxyRules::TYPE_PROXY_PER_SCHEME
,
246 // SOCKS proxy present along with other proxies too
248 "http=httpproxy ; https=httpsproxy ; ftp=ftpproxy ; socks=foopy ",
250 ProxyConfig::ProxyRules::TYPE_PROXY_PER_SCHEME
,
252 "PROXY httpproxy:80",
253 "PROXY httpsproxy:80",
258 // SOCKS proxy (with modifier) present along with some proxies
261 "http=httpproxy ; https=httpsproxy ; socks=socks5://foopy ",
263 ProxyConfig::ProxyRules::TYPE_PROXY_PER_SCHEME
,
265 "PROXY httpproxy:80",
266 "PROXY httpsproxy:80",
271 // Include unsupported schemes -- they are discarded.
273 "crazy=foopy ; foo=bar ; https=myhttpsproxy",
275 ProxyConfig::ProxyRules::TYPE_PROXY_PER_SCHEME
,
278 "PROXY myhttpsproxy:80",
283 // direct:// as first option for a scheme.
285 "http=direct://,myhttpproxy; https=direct://",
287 ProxyConfig::ProxyRules::TYPE_PROXY_PER_SCHEME
,
289 "DIRECT;PROXY myhttpproxy:80",
295 // direct:// as a second option for a scheme.
297 "http=myhttpproxy,direct://",
299 ProxyConfig::ProxyRules::TYPE_PROXY_PER_SCHEME
,
301 "PROXY myhttpproxy:80;DIRECT",
311 for (size_t i
= 0; i
< arraysize(tests
); ++i
) {
312 config
.proxy_rules().ParseFromString(tests
[i
].proxy_rules
);
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
);
328 TEST(ProxyConfigTest
, ProxyRulesSetBypassFlag
) {
329 // Test whether the did_bypass_proxy() flag is set in proxy info correctly.
330 ProxyConfig::ProxyRules rules
;
333 rules
.ParseFromString("http=httpproxy:80");
334 rules
.bypass_rules
.AddRuleFromString(".com");
336 rules
.Apply(GURL("http://example.com"), &result
);
337 EXPECT_TRUE(result
.is_direct_only());
338 EXPECT_TRUE(result
.did_bypass_proxy());
340 rules
.Apply(GURL("http://example.org"), &result
);
341 EXPECT_FALSE(result
.is_direct());
342 EXPECT_FALSE(result
.did_bypass_proxy());
344 // Try with reversed bypass rules.
345 rules
.reverse_bypass
= true;
347 rules
.Apply(GURL("http://example.org"), &result
);
348 EXPECT_TRUE(result
.is_direct_only());
349 EXPECT_TRUE(result
.did_bypass_proxy());
351 rules
.Apply(GURL("http://example.com"), &result
);
352 EXPECT_FALSE(result
.is_direct());
353 EXPECT_FALSE(result
.did_bypass_proxy());
356 static const char kWsUrl
[] = "ws://example.com/echo";
357 static const char kWssUrl
[] = "wss://example.com/echo";
359 class ProxyConfigWebSocketTest
: public ::testing::Test
{
361 void ParseFromString(const std::string
& rules
) {
362 rules_
.ParseFromString(rules
);
364 void Apply(const GURL
& gurl
) { rules_
.Apply(gurl
, &info_
); }
365 std::string
ToPacString() const { return info_
.ToPacString(); }
367 static GURL
WsUrl() { return GURL(kWsUrl
); }
368 static GURL
WssUrl() { return GURL(kWssUrl
); }
370 ProxyConfig::ProxyRules rules_
;
374 // If a single proxy is set for all protocols, WebSocket uses it.
375 TEST_F(ProxyConfigWebSocketTest
, UsesProxy
) {
376 ParseFromString("proxy:3128");
378 EXPECT_EQ("PROXY proxy:3128", ToPacString());
381 // See RFC6455 Section 4.1. item 3, "_Proxy Usage_".
382 TEST_F(ProxyConfigWebSocketTest
, PrefersSocks
) {
384 "http=proxy:3128 ; https=sslproxy:3128 ; socks=socksproxy:1080");
386 EXPECT_EQ("SOCKS socksproxy:1080", ToPacString());
389 TEST_F(ProxyConfigWebSocketTest
, PrefersHttpsToHttp
) {
390 ParseFromString("http=proxy:3128 ; https=sslproxy:3128");
392 EXPECT_EQ("PROXY sslproxy:3128", ToPacString());
395 TEST_F(ProxyConfigWebSocketTest
, PrefersHttpsEvenForWs
) {
396 ParseFromString("http=proxy:3128 ; https=sslproxy:3128");
398 EXPECT_EQ("PROXY sslproxy:3128", ToPacString());
401 TEST_F(ProxyConfigWebSocketTest
, PrefersHttpToDirect
) {
402 ParseFromString("http=proxy:3128");
404 EXPECT_EQ("PROXY proxy:3128", ToPacString());
407 TEST_F(ProxyConfigWebSocketTest
, IgnoresFtpProxy
) {
408 ParseFromString("ftp=ftpproxy:3128");
410 EXPECT_EQ("DIRECT", ToPacString());
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());
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());