Home | History | Annotate | Download | only in proxy
      1 // Copyright (c) 2010 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_bypass_rules.h"
      6 
      7 #include "base/string_util.h"
      8 #include "base/stringprintf.h"
      9 #include "net/proxy/proxy_config_service_common_unittest.h"
     10 #include "testing/gtest/include/gtest/gtest.h"
     11 
     12 namespace net {
     13 
     14 namespace {
     15 
     16 TEST(ProxyBypassRulesTest, ParseAndMatchBasicHost) {
     17   ProxyBypassRules rules;
     18   rules.ParseFromString("wWw.gOogle.com");
     19   ASSERT_EQ(1u, rules.rules().size());
     20   EXPECT_EQ("www.google.com", rules.rules()[0]->ToString());
     21 
     22   // All of these match; port, scheme, and non-hostname components don't
     23   // matter.
     24   EXPECT_TRUE(rules.Matches(GURL("http://www.google.com")));
     25   EXPECT_TRUE(rules.Matches(GURL("ftp://www.google.com:99")));
     26   EXPECT_TRUE(rules.Matches(GURL("https://www.google.com:81")));
     27 
     28   // Must be a strict host match to work.
     29   EXPECT_FALSE(rules.Matches(GURL("http://foo.www.google.com")));
     30   EXPECT_FALSE(rules.Matches(GURL("http://xxx.google.com")));
     31   EXPECT_FALSE(rules.Matches(GURL("http://google.com")));
     32   EXPECT_FALSE(rules.Matches(GURL("http://www.google.com.baz.org")));
     33 }
     34 
     35 TEST(ProxyBypassRulesTest, ParseAndMatchBasicDomain) {
     36   ProxyBypassRules rules;
     37   rules.ParseFromString(".gOOgle.com");
     38   ASSERT_EQ(1u, rules.rules().size());
     39   // Note that we inferred this was an "ends with" test.
     40   EXPECT_EQ("*.google.com", rules.rules()[0]->ToString());
     41 
     42   // All of these match; port, scheme, and non-hostname components don't
     43   // matter.
     44   EXPECT_TRUE(rules.Matches(GURL("http://www.google.com")));
     45   EXPECT_TRUE(rules.Matches(GURL("ftp://www.google.com:99")));
     46   EXPECT_TRUE(rules.Matches(GURL("https://a.google.com:81")));
     47   EXPECT_TRUE(rules.Matches(GURL("http://foo.google.com/x/y?q")));
     48   EXPECT_TRUE(rules.Matches(GURL("http://foo:bar@baz.google.com#x")));
     49 
     50   // Must be a strict "ends with" to work.
     51   EXPECT_FALSE(rules.Matches(GURL("http://google.com")));
     52   EXPECT_FALSE(rules.Matches(GURL("http://foo.google.com.baz.org")));
     53 }
     54 
     55 TEST(ProxyBypassRulesTest, ParseAndMatchBasicDomainWithPort) {
     56   ProxyBypassRules rules;
     57   rules.ParseFromString("*.GOOGLE.com:80");
     58   ASSERT_EQ(1u, rules.rules().size());
     59   EXPECT_EQ("*.google.com:80", rules.rules()[0]->ToString());
     60 
     61   // All of these match; scheme, and non-hostname components don't matter.
     62   EXPECT_TRUE(rules.Matches(GURL("http://www.google.com")));
     63   EXPECT_TRUE(rules.Matches(GURL("ftp://www.google.com:80")));
     64   EXPECT_TRUE(rules.Matches(GURL("https://a.google.com:80?x")));
     65 
     66   // Must be a strict "ends with" to work.
     67   EXPECT_FALSE(rules.Matches(GURL("http://google.com")));
     68   EXPECT_FALSE(rules.Matches(GURL("http://foo.google.com.baz.org")));
     69 
     70   // The ports must match.
     71   EXPECT_FALSE(rules.Matches(GURL("http://www.google.com:90")));
     72   EXPECT_FALSE(rules.Matches(GURL("https://www.google.com")));
     73 }
     74 
     75 TEST(ProxyBypassRulesTest, MatchAll) {
     76   ProxyBypassRules rules;
     77   rules.ParseFromString("*");
     78   ASSERT_EQ(1u, rules.rules().size());
     79   EXPECT_EQ("*", rules.rules()[0]->ToString());
     80 
     81   EXPECT_TRUE(rules.Matches(GURL("http://www.google.com")));
     82   EXPECT_TRUE(rules.Matches(GURL("ftp://www.foobar.com:99")));
     83   EXPECT_TRUE(rules.Matches(GURL("https://a.google.com:80?x")));
     84 }
     85 
     86 TEST(ProxyBypassRulesTest, WildcardAtStart) {
     87   ProxyBypassRules rules;
     88   rules.ParseFromString("*.org:443");
     89   ASSERT_EQ(1u, rules.rules().size());
     90   EXPECT_EQ("*.org:443", rules.rules()[0]->ToString());
     91 
     92   EXPECT_TRUE(rules.Matches(GURL("http://www.google.org:443")));
     93   EXPECT_TRUE(rules.Matches(GURL("https://www.google.org")));
     94 
     95   EXPECT_FALSE(rules.Matches(GURL("http://www.google.org")));
     96   EXPECT_FALSE(rules.Matches(GURL("https://www.google.com")));
     97   EXPECT_FALSE(rules.Matches(GURL("https://www.google.org.com")));
     98 }
     99 
    100 TEST(ProxyBypassRulesTest, IPV4Address) {
    101   ProxyBypassRules rules;
    102   rules.ParseFromString("192.168.1.1");
    103   ASSERT_EQ(1u, rules.rules().size());
    104   EXPECT_EQ("192.168.1.1", rules.rules()[0]->ToString());
    105 
    106   EXPECT_TRUE(rules.Matches(GURL("http://192.168.1.1")));
    107   EXPECT_TRUE(rules.Matches(GURL("https://192.168.1.1:90")));
    108 
    109   EXPECT_FALSE(rules.Matches(GURL("http://www.google.com")));
    110   EXPECT_FALSE(rules.Matches(GURL("http://sup.192.168.1.1")));
    111 }
    112 
    113 TEST(ProxyBypassRulesTest, IPV4AddressWithPort) {
    114   ProxyBypassRules rules;
    115   rules.ParseFromString("192.168.1.1:33");
    116   ASSERT_EQ(1u, rules.rules().size());
    117   EXPECT_EQ("192.168.1.1:33", rules.rules()[0]->ToString());
    118 
    119   EXPECT_TRUE(rules.Matches(GURL("http://192.168.1.1:33")));
    120 
    121   EXPECT_FALSE(rules.Matches(GURL("http://www.google.com")));
    122   EXPECT_FALSE(rules.Matches(GURL("http://192.168.1.1")));
    123   EXPECT_FALSE(rules.Matches(GURL("http://sup.192.168.1.1:33")));
    124 }
    125 
    126 TEST(ProxyBypassRulesTest, IPV6Address) {
    127   ProxyBypassRules rules;
    128   rules.ParseFromString("[3ffe:2a00:100:7031:0:0::1]");
    129   ASSERT_EQ(1u, rules.rules().size());
    130   // Note that we canonicalized the IP address.
    131   EXPECT_EQ("[3ffe:2a00:100:7031::1]", rules.rules()[0]->ToString());
    132 
    133   EXPECT_TRUE(rules.Matches(GURL("http://[3ffe:2a00:100:7031::1]")));
    134   EXPECT_TRUE(rules.Matches(GURL("http://[3ffe:2a00:100:7031::1]:33")));
    135 
    136   EXPECT_FALSE(rules.Matches(GURL("http://www.google.com")));
    137   EXPECT_FALSE(rules.Matches(GURL("http://sup.192.168.1.1:33")));
    138 }
    139 
    140 TEST(ProxyBypassRulesTest, IPV6AddressWithPort) {
    141   ProxyBypassRules rules;
    142   rules.ParseFromString("[3ffe:2a00:100:7031::1]:33");
    143   ASSERT_EQ(1u, rules.rules().size());
    144   EXPECT_EQ("[3ffe:2a00:100:7031::1]:33", rules.rules()[0]->ToString());
    145 
    146   EXPECT_TRUE(rules.Matches(GURL("http://[3ffe:2a00:100:7031::1]:33")));
    147 
    148   EXPECT_FALSE(rules.Matches(GURL("http://[3ffe:2a00:100:7031::1]")));
    149   EXPECT_FALSE(rules.Matches(GURL("http://www.google.com")));
    150 }
    151 
    152 TEST(ProxyBypassRulesTest, HTTPOnly) {
    153   ProxyBypassRules rules;
    154   rules.ParseFromString("http://www.google.com");
    155   ASSERT_EQ(1u, rules.rules().size());
    156   EXPECT_EQ("http://www.google.com", rules.rules()[0]->ToString());
    157 
    158   EXPECT_TRUE(rules.Matches(GURL("http://www.google.com/foo")));
    159   EXPECT_TRUE(rules.Matches(GURL("http://www.google.com:99")));
    160 
    161   EXPECT_FALSE(rules.Matches(GURL("https://www.google.com")));
    162   EXPECT_FALSE(rules.Matches(GURL("ftp://www.google.com")));
    163   EXPECT_FALSE(rules.Matches(GURL("http://foo.www.google.com")));
    164   EXPECT_FALSE(rules.Matches(GURL("http://www.google.com.org")));
    165   EXPECT_FALSE(rules.Matches(GURL("https://www.google.com")));
    166 }
    167 
    168 TEST(ProxyBypassRulesTest, HTTPOnlyWithWildcard) {
    169   ProxyBypassRules rules;
    170   rules.ParseFromString("http://*www.google.com");
    171   ASSERT_EQ(1u, rules.rules().size());
    172   EXPECT_EQ("http://*www.google.com", rules.rules()[0]->ToString());
    173 
    174   EXPECT_TRUE(rules.Matches(GURL("http://www.google.com/foo")));
    175   EXPECT_TRUE(rules.Matches(GURL("http://www.google.com:99")));
    176   EXPECT_TRUE(rules.Matches(GURL("http://foo.www.google.com")));
    177 
    178   EXPECT_FALSE(rules.Matches(GURL("https://www.google.com")));
    179   EXPECT_FALSE(rules.Matches(GURL("ftp://www.google.com")));
    180   EXPECT_FALSE(rules.Matches(GURL("http://www.google.com.org")));
    181   EXPECT_FALSE(rules.Matches(GURL("https://www.google.com")));
    182 }
    183 
    184 TEST(ProxyBypassRulesTest, UseSuffixMatching) {
    185   ProxyBypassRules rules;
    186   rules.ParseFromStringUsingSuffixMatching(
    187       "foo1.com, .foo2.com, 192.168.1.1, "
    188       "*foobar.com:80, *.foo, http://baz, <local>");
    189   ASSERT_EQ(7u, rules.rules().size());
    190   EXPECT_EQ("*foo1.com", rules.rules()[0]->ToString());
    191   EXPECT_EQ("*.foo2.com", rules.rules()[1]->ToString());
    192   EXPECT_EQ("192.168.1.1", rules.rules()[2]->ToString());
    193   EXPECT_EQ("*foobar.com:80", rules.rules()[3]->ToString());
    194   EXPECT_EQ("*.foo", rules.rules()[4]->ToString());
    195   EXPECT_EQ("http://*baz", rules.rules()[5]->ToString());
    196   EXPECT_EQ("<local>", rules.rules()[6]->ToString());
    197 
    198   EXPECT_TRUE(rules.Matches(GURL("http://foo1.com")));
    199   EXPECT_TRUE(rules.Matches(GURL("http://aaafoo1.com")));
    200   EXPECT_FALSE(rules.Matches(GURL("http://aaafoo1.com.net")));
    201 }
    202 
    203 TEST(ProxyBypassRulesTest, MultipleRules) {
    204   ProxyBypassRules rules;
    205   rules.ParseFromString(".google.com , .foobar.com:30");
    206   ASSERT_EQ(2u, rules.rules().size());
    207 
    208   EXPECT_TRUE(rules.Matches(GURL("http://baz.google.com:40")));
    209   EXPECT_FALSE(rules.Matches(GURL("http://google.com:40")));
    210   EXPECT_TRUE(rules.Matches(GURL("http://bar.foobar.com:30")));
    211   EXPECT_FALSE(rules.Matches(GURL("http://bar.foobar.com")));
    212   EXPECT_FALSE(rules.Matches(GURL("http://bar.foobar.com:33")));
    213 }
    214 
    215 TEST(ProxyBypassRulesTest, BadInputs) {
    216   ProxyBypassRules rules;
    217   EXPECT_FALSE(rules.AddRuleFromString("://"));
    218   EXPECT_FALSE(rules.AddRuleFromString("  "));
    219   EXPECT_FALSE(rules.AddRuleFromString("http://"));
    220   EXPECT_FALSE(rules.AddRuleFromString("*.foo.com:-34"));
    221   EXPECT_EQ(0u, rules.rules().size());
    222 }
    223 
    224 TEST(ProxyBypassRulesTest, Equals) {
    225   ProxyBypassRules rules1;
    226   ProxyBypassRules rules2;
    227 
    228   rules1.ParseFromString("foo1.com, .foo2.com");
    229   rules2.ParseFromString("foo1.com,.FOo2.com");
    230 
    231   EXPECT_TRUE(rules1.Equals(rules2));
    232   EXPECT_TRUE(rules2.Equals(rules1));
    233 
    234   rules1.ParseFromString(".foo2.com");
    235   rules2.ParseFromString("foo1.com,.FOo2.com");
    236 
    237   EXPECT_FALSE(rules1.Equals(rules2));
    238   EXPECT_FALSE(rules2.Equals(rules1));
    239 }
    240 
    241 TEST(ProxyBypassRulesTest, BypassLocalNames) {
    242   const struct {
    243     const char* url;
    244     bool expected_is_local;
    245   } tests[] = {
    246     // Single-component hostnames are considered local.
    247     {"http://localhost/x", true},
    248     {"http://www", true},
    249 
    250     // IPv4 loopback interface.
    251     {"http://127.0.0.1/x", true},
    252     {"http://127.0.0.1:80/x", true},
    253 
    254     // IPv6 loopback interface.
    255     {"http://[::1]:80/x", true},
    256     {"http://[0:0::1]:6233/x", true},
    257     {"http://[0:0:0:0:0:0:0:1]/x", true},
    258 
    259     // Non-local URLs.
    260     {"http://foo.com/", false},
    261     {"http://localhost.i/", false},
    262     {"http://www.google.com/", false},
    263     {"http://192.168.0.1/", false},
    264 
    265     // Try with different protocols.
    266     {"ftp://127.0.0.1/x", true},
    267     {"ftp://foobar.com/x", false},
    268 
    269     // This is a bit of a gray-area, but GURL does not strip trailing dots
    270     // in host-names, so the following are considered non-local.
    271     {"http://www./x", false},
    272     {"http://localhost./x", false},
    273   };
    274 
    275   ProxyBypassRules rules;
    276   rules.ParseFromString("<local>");
    277 
    278   for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
    279     SCOPED_TRACE(base::StringPrintf(
    280         "Test[%d]: %s", static_cast<int>(i), tests[i].url));
    281     EXPECT_EQ(tests[i].expected_is_local, rules.Matches(GURL(tests[i].url)));
    282   }
    283 }
    284 
    285 TEST(ProxyBypassRulesTest, ParseAndMatchCIDR_IPv4) {
    286   ProxyBypassRules rules;
    287   rules.ParseFromString("192.168.1.1/16");
    288   ASSERT_EQ(1u, rules.rules().size());
    289   EXPECT_EQ("192.168.1.1/16", rules.rules()[0]->ToString());
    290 
    291   EXPECT_TRUE(rules.Matches(GURL("http://192.168.1.1")));
    292   EXPECT_TRUE(rules.Matches(GURL("ftp://192.168.4.4")));
    293   EXPECT_TRUE(rules.Matches(GURL("https://192.168.0.0:81")));
    294   EXPECT_TRUE(rules.Matches(GURL("http://[::ffff:192.168.11.11]")));
    295 
    296   EXPECT_FALSE(rules.Matches(GURL("http://foobar.com")));
    297   EXPECT_FALSE(rules.Matches(GURL("http://192.169.1.1")));
    298   EXPECT_FALSE(rules.Matches(GURL("http://xxx.192.168.1.1")));
    299   EXPECT_FALSE(rules.Matches(GURL("http://192.168.1.1.xx")));
    300 }
    301 
    302 TEST(ProxyBypassRulesTest, ParseAndMatchCIDR_IPv6) {
    303   ProxyBypassRules rules;
    304   rules.ParseFromString("a:b:c:d::/48");
    305   ASSERT_EQ(1u, rules.rules().size());
    306   EXPECT_EQ("a:b:c:d::/48", rules.rules()[0]->ToString());
    307 
    308   EXPECT_TRUE(rules.Matches(GURL("http://[A:b:C:9::]")));
    309   EXPECT_FALSE(rules.Matches(GURL("http://foobar.com")));
    310   EXPECT_FALSE(rules.Matches(GURL("http://192.169.1.1")));
    311 }
    312 
    313 }  // namespace
    314 
    315 }  // namespace net
    316