Home | History | Annotate | Download | only in proxy
      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