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