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_UNSAFE(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 } // namespace 357 } // namespace net 358