Home | History | Annotate | Download | only in proxy
      1 // Copyright (c) 2006-2008 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_list.h"
      6 
      7 #include "net/proxy/proxy_server.h"
      8 #include "testing/gtest/include/gtest/gtest.h"
      9 
     10 namespace net {
     11 
     12 namespace {
     13 
     14 // Test parsing from a PAC string.
     15 TEST(ProxyListTest, SetFromPacString) {
     16   const struct {
     17     const char* pac_input;
     18     const char* pac_output;
     19   } tests[] = {
     20     // Valid inputs:
     21     {  "PROXY foopy:10",
     22        "PROXY foopy:10",
     23     },
     24     {  " DIRECT",  // leading space.
     25        "DIRECT",
     26     },
     27     {  "PROXY foopy1 ; proxy foopy2;\t DIRECT",
     28        "PROXY foopy1:80;PROXY foopy2:80;DIRECT",
     29     },
     30     {  "proxy foopy1 ; SOCKS foopy2",
     31        "PROXY foopy1:80;SOCKS foopy2:1080",
     32     },
     33     // Try putting DIRECT first.
     34     {  "DIRECT ; proxy foopy1 ; DIRECT ; SOCKS5 foopy2;DIRECT ",
     35        "DIRECT;PROXY foopy1:80;DIRECT;SOCKS5 foopy2:1080;DIRECT",
     36     },
     37     // Try putting DIRECT consecutively.
     38     {  "DIRECT ; proxy foopy1:80; DIRECT ; DIRECT",
     39        "DIRECT;PROXY foopy1:80;DIRECT;DIRECT",
     40     },
     41 
     42     // Invalid inputs (parts which aren't understood get
     43     // silently discarded):
     44     //
     45     // If the proxy list string parsed to empty, automatically fall-back to
     46     // DIRECT.
     47     {  "PROXY-foopy:10",
     48        "DIRECT",
     49     },
     50     {  "PROXY",
     51        "DIRECT",
     52     },
     53     {  "PROXY foopy1 ; JUNK ; JUNK ; SOCKS5 foopy2 ; ;",
     54        "PROXY foopy1:80;SOCKS5 foopy2:1080",
     55     },
     56   };
     57 
     58   for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
     59     ProxyList list;
     60     list.SetFromPacString(tests[i].pac_input);
     61     EXPECT_EQ(tests[i].pac_output, list.ToPacString());
     62     EXPECT_FALSE(list.IsEmpty());
     63   }
     64 }
     65 
     66 TEST(ProxyListTest, RemoveProxiesWithoutScheme) {
     67   const struct {
     68     const char* pac_input;
     69     int filter;
     70     const char* filtered_pac_output;
     71   } tests[] = {
     72     {  "PROXY foopy:10 ; SOCKS5 foopy2 ; SOCKS foopy11 ; PROXY foopy3 ; DIRECT",
     73        // Remove anything that isn't HTTP or DIRECT.
     74        ProxyServer::SCHEME_DIRECT | ProxyServer::SCHEME_HTTP,
     75        "PROXY foopy:10;PROXY foopy3:80;DIRECT",
     76     },
     77     {  "PROXY foopy:10 ; SOCKS5 foopy2",
     78        // Remove anything that isn't HTTP or SOCKS5.
     79        ProxyServer::SCHEME_DIRECT | ProxyServer::SCHEME_SOCKS4,
     80        "",
     81     },
     82   };
     83 
     84   for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
     85     ProxyList list;
     86     list.SetFromPacString(tests[i].pac_input);
     87     list.RemoveProxiesWithoutScheme(tests[i].filter);
     88     EXPECT_EQ(tests[i].filtered_pac_output, list.ToPacString());
     89   }
     90 }
     91 
     92 TEST(ProxyListTest, HasUntriedProxies) {
     93   // As in DeprioritizeBadProxies, we use a lengthy timeout to avoid depending
     94   // on the current time.
     95   ProxyRetryInfo proxy_retry_info;
     96   proxy_retry_info.bad_until =
     97       base::TimeTicks::Now() + base::TimeDelta::FromDays(1);
     98 
     99   // An empty list has nothing to try.
    100   {
    101     ProxyList list;
    102     ProxyRetryInfoMap proxy_retry_info;
    103     EXPECT_FALSE(list.HasUntriedProxies(proxy_retry_info));
    104   }
    105 
    106   // A list with one bad proxy has something to try. With two bad proxies,
    107   // there's nothing to try.
    108   {
    109     ProxyList list;
    110     list.SetFromPacString("PROXY bad1:80; PROXY bad2:80");
    111     ProxyRetryInfoMap retry_info_map;
    112     retry_info_map["bad1:80"] = proxy_retry_info;
    113     EXPECT_TRUE(list.HasUntriedProxies(retry_info_map));
    114     retry_info_map["bad2:80"] = proxy_retry_info;
    115     EXPECT_FALSE(list.HasUntriedProxies(retry_info_map));
    116   }
    117 
    118   // A list with one bad proxy and a DIRECT entry has something to try.
    119   {
    120     ProxyList list;
    121     list.SetFromPacString("PROXY bad1:80; DIRECT");
    122     ProxyRetryInfoMap retry_info_map;
    123     retry_info_map["bad1:80"] = proxy_retry_info;
    124     EXPECT_TRUE(list.HasUntriedProxies(retry_info_map));
    125   }
    126 }
    127 
    128 TEST(ProxyListTest, DeprioritizeBadProxies) {
    129   // Retry info that marks a proxy as being bad for a *very* long time (to avoid
    130   // the test depending on the current time.)
    131   ProxyRetryInfo proxy_retry_info;
    132   proxy_retry_info.bad_until =
    133       base::TimeTicks::Now() + base::TimeDelta::FromDays(1);
    134 
    135   // Call DeprioritizeBadProxies with an empty map -- should have no effect.
    136   {
    137     ProxyList list;
    138     list.SetFromPacString("PROXY foopy1:80;PROXY foopy2:80;PROXY foopy3:80");
    139 
    140     ProxyRetryInfoMap retry_info_map;
    141     list.DeprioritizeBadProxies(retry_info_map);
    142     EXPECT_EQ("PROXY foopy1:80;PROXY foopy2:80;PROXY foopy3:80",
    143               list.ToPacString());
    144   }
    145 
    146   // Call DeprioritizeBadProxies with 2 of the three proxies marked as bad.
    147   // These proxies should be retried last.
    148   {
    149     ProxyList list;
    150     list.SetFromPacString("PROXY foopy1:80;PROXY foopy2:80;PROXY foopy3:80");
    151 
    152     ProxyRetryInfoMap retry_info_map;
    153     retry_info_map["foopy1:80"] = proxy_retry_info;
    154     retry_info_map["foopy3:80"] = proxy_retry_info;
    155     retry_info_map["socks5://localhost:1080"] = proxy_retry_info;
    156 
    157     list.DeprioritizeBadProxies(retry_info_map);
    158 
    159     EXPECT_EQ("PROXY foopy2:80;PROXY foopy1:80;PROXY foopy3:80",
    160               list.ToPacString());
    161   }
    162 
    163   // Call DeprioritizeBadProxies where ALL of the proxies are marked as bad.
    164   // This should have no effect on the order.
    165   {
    166     ProxyList list;
    167     list.SetFromPacString("PROXY foopy1:80;PROXY foopy2:80;PROXY foopy3:80");
    168 
    169     ProxyRetryInfoMap retry_info_map;
    170     retry_info_map["foopy1:80"] = proxy_retry_info;
    171     retry_info_map["foopy2:80"] = proxy_retry_info;
    172     retry_info_map["foopy3:80"] = proxy_retry_info;
    173 
    174     list.DeprioritizeBadProxies(retry_info_map);
    175 
    176     EXPECT_EQ("PROXY foopy1:80;PROXY foopy2:80;PROXY foopy3:80",
    177               list.ToPacString());
    178   }
    179 }
    180 
    181 }  // namesapce
    182 
    183 }  // namespace net
    184