OLD | NEW |
| (Empty) |
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/base/net_errors.h" | |
8 #include "net/base/net_log.h" | |
9 #include "net/proxy/proxy_retry_info.h" | |
10 #include "net/proxy/proxy_server.h" | |
11 #include "testing/gtest/include/gtest/gtest.h" | |
12 | |
13 namespace net { | |
14 | |
15 namespace { | |
16 | |
17 // Test parsing from a PAC string. | |
18 TEST(ProxyListTest, SetFromPacString) { | |
19 const struct { | |
20 const char* pac_input; | |
21 const char* pac_output; | |
22 } tests[] = { | |
23 // Valid inputs: | |
24 { "PROXY foopy:10", | |
25 "PROXY foopy:10", | |
26 }, | |
27 { " DIRECT", // leading space. | |
28 "DIRECT", | |
29 }, | |
30 { "PROXY foopy1 ; proxy foopy2;\t DIRECT", | |
31 "PROXY foopy1:80;PROXY foopy2:80;DIRECT", | |
32 }, | |
33 { "proxy foopy1 ; SOCKS foopy2", | |
34 "PROXY foopy1:80;SOCKS foopy2:1080", | |
35 }, | |
36 // Try putting DIRECT first. | |
37 { "DIRECT ; proxy foopy1 ; DIRECT ; SOCKS5 foopy2;DIRECT ", | |
38 "DIRECT;PROXY foopy1:80;DIRECT;SOCKS5 foopy2:1080;DIRECT", | |
39 }, | |
40 // Try putting DIRECT consecutively. | |
41 { "DIRECT ; proxy foopy1:80; DIRECT ; DIRECT", | |
42 "DIRECT;PROXY foopy1:80;DIRECT;DIRECT", | |
43 }, | |
44 | |
45 // Invalid inputs (parts which aren't understood get | |
46 // silently discarded): | |
47 // | |
48 // If the proxy list string parsed to empty, automatically fall-back to | |
49 // DIRECT. | |
50 { "PROXY-foopy:10", | |
51 "DIRECT", | |
52 }, | |
53 { "PROXY", | |
54 "DIRECT", | |
55 }, | |
56 { "PROXY foopy1 ; JUNK ; JUNK ; SOCKS5 foopy2 ; ;", | |
57 "PROXY foopy1:80;SOCKS5 foopy2:1080", | |
58 }, | |
59 }; | |
60 | |
61 for (size_t i = 0; i < arraysize(tests); ++i) { | |
62 ProxyList list; | |
63 list.SetFromPacString(tests[i].pac_input); | |
64 EXPECT_EQ(tests[i].pac_output, list.ToPacString()); | |
65 EXPECT_FALSE(list.IsEmpty()); | |
66 } | |
67 } | |
68 | |
69 TEST(ProxyListTest, RemoveProxiesWithoutScheme) { | |
70 const struct { | |
71 const char* pac_input; | |
72 int filter; | |
73 const char* filtered_pac_output; | |
74 } tests[] = { | |
75 { "PROXY foopy:10 ; SOCKS5 foopy2 ; SOCKS foopy11 ; PROXY foopy3 ; DIRECT", | |
76 // Remove anything that isn't HTTP or DIRECT. | |
77 ProxyServer::SCHEME_DIRECT | ProxyServer::SCHEME_HTTP, | |
78 "PROXY foopy:10;PROXY foopy3:80;DIRECT", | |
79 }, | |
80 { "PROXY foopy:10 ; SOCKS5 foopy2", | |
81 // Remove anything that isn't HTTP or SOCKS5. | |
82 ProxyServer::SCHEME_DIRECT | ProxyServer::SCHEME_SOCKS4, | |
83 "", | |
84 }, | |
85 }; | |
86 | |
87 for (size_t i = 0; i < arraysize(tests); ++i) { | |
88 ProxyList list; | |
89 list.SetFromPacString(tests[i].pac_input); | |
90 list.RemoveProxiesWithoutScheme(tests[i].filter); | |
91 EXPECT_EQ(tests[i].filtered_pac_output, list.ToPacString()); | |
92 } | |
93 } | |
94 | |
95 TEST(ProxyListTest, DeprioritizeBadProxies) { | |
96 // Retry info that marks a proxy as being bad for a *very* long time (to avoid | |
97 // the test depending on the current time.) | |
98 ProxyRetryInfo proxy_retry_info; | |
99 proxy_retry_info.bad_until = | |
100 base::TimeTicks::Now() + base::TimeDelta::FromDays(1); | |
101 | |
102 // Call DeprioritizeBadProxies with an empty map -- should have no effect. | |
103 { | |
104 ProxyList list; | |
105 list.SetFromPacString("PROXY foopy1:80;PROXY foopy2:80;PROXY foopy3:80"); | |
106 | |
107 ProxyRetryInfoMap retry_info_map; | |
108 list.DeprioritizeBadProxies(retry_info_map); | |
109 EXPECT_EQ("PROXY foopy1:80;PROXY foopy2:80;PROXY foopy3:80", | |
110 list.ToPacString()); | |
111 } | |
112 | |
113 // Call DeprioritizeBadProxies with 2 of the three proxies marked as bad. | |
114 // These proxies should be retried last. | |
115 { | |
116 ProxyList list; | |
117 list.SetFromPacString("PROXY foopy1:80;PROXY foopy2:80;PROXY foopy3:80"); | |
118 | |
119 ProxyRetryInfoMap retry_info_map; | |
120 retry_info_map["foopy1:80"] = proxy_retry_info; | |
121 retry_info_map["foopy3:80"] = proxy_retry_info; | |
122 retry_info_map["socks5://localhost:1080"] = proxy_retry_info; | |
123 | |
124 list.DeprioritizeBadProxies(retry_info_map); | |
125 | |
126 EXPECT_EQ("PROXY foopy2:80;PROXY foopy1:80;PROXY foopy3:80", | |
127 list.ToPacString()); | |
128 } | |
129 | |
130 // Call DeprioritizeBadProxies where ALL of the proxies are marked as bad. | |
131 // This should have no effect on the order. | |
132 { | |
133 ProxyList list; | |
134 list.SetFromPacString("PROXY foopy1:80;PROXY foopy2:80;PROXY foopy3:80"); | |
135 | |
136 ProxyRetryInfoMap retry_info_map; | |
137 retry_info_map["foopy1:80"] = proxy_retry_info; | |
138 retry_info_map["foopy2:80"] = proxy_retry_info; | |
139 retry_info_map["foopy3:80"] = proxy_retry_info; | |
140 | |
141 list.DeprioritizeBadProxies(retry_info_map); | |
142 | |
143 EXPECT_EQ("PROXY foopy1:80;PROXY foopy2:80;PROXY foopy3:80", | |
144 list.ToPacString()); | |
145 } | |
146 | |
147 // Call DeprioritizeBadProxies with 2 of the three proxies marked as bad. Of | |
148 // the 2 bad proxies, one is to be reconsidered and should be retried last. | |
149 // The other is not to be reconsidered and should be removed from the list. | |
150 { | |
151 ProxyList list; | |
152 list.SetFromPacString("PROXY foopy1:80;PROXY foopy2:80;PROXY foopy3:80"); | |
153 | |
154 ProxyRetryInfoMap retry_info_map; | |
155 // |proxy_retry_info.reconsider defaults to true. | |
156 retry_info_map["foopy1:80"] = proxy_retry_info; | |
157 proxy_retry_info.try_while_bad = false; | |
158 retry_info_map["foopy3:80"] = proxy_retry_info; | |
159 proxy_retry_info.try_while_bad = true; | |
160 retry_info_map["socks5://localhost:1080"] = proxy_retry_info; | |
161 | |
162 list.DeprioritizeBadProxies(retry_info_map); | |
163 | |
164 EXPECT_EQ("PROXY foopy2:80;PROXY foopy1:80", | |
165 list.ToPacString()); | |
166 } | |
167 } | |
168 | |
169 TEST(ProxyListTest, UpdateRetryInfoOnFallback) { | |
170 ProxyRetryInfo proxy_retry_info; | |
171 // Retrying should put the first proxy on the retry list. | |
172 { | |
173 ProxyList list; | |
174 ProxyRetryInfoMap retry_info_map; | |
175 BoundNetLog net_log; | |
176 ProxyServer proxy_server( | |
177 ProxyServer::FromURI("foopy1:80", ProxyServer::SCHEME_HTTP)); | |
178 list.SetFromPacString("PROXY foopy1:80;PROXY foopy2:80;PROXY foopy3:80"); | |
179 list.UpdateRetryInfoOnFallback(&retry_info_map, | |
180 base::TimeDelta::FromSeconds(60), | |
181 true, | |
182 proxy_server, | |
183 ERR_PROXY_CONNECTION_FAILED, | |
184 net_log); | |
185 EXPECT_TRUE(retry_info_map.end() != retry_info_map.find("foopy1:80")); | |
186 EXPECT_EQ(ERR_PROXY_CONNECTION_FAILED, | |
187 retry_info_map[proxy_server.ToURI()].net_error); | |
188 EXPECT_TRUE(retry_info_map.end() == retry_info_map.find("foopy2:80")); | |
189 EXPECT_TRUE(retry_info_map.end() == retry_info_map.find("foopy3:80")); | |
190 } | |
191 // Retrying should put the first proxy on the retry list, even if there | |
192 // was no network error. | |
193 { | |
194 ProxyList list; | |
195 ProxyRetryInfoMap retry_info_map; | |
196 BoundNetLog net_log; | |
197 ProxyServer proxy_server( | |
198 ProxyServer::FromURI("foopy1:80", ProxyServer::SCHEME_HTTP)); | |
199 list.SetFromPacString("PROXY foopy1:80;PROXY foopy2:80;PROXY foopy3:80"); | |
200 list.UpdateRetryInfoOnFallback(&retry_info_map, | |
201 base::TimeDelta::FromSeconds(60), | |
202 true, | |
203 proxy_server, | |
204 OK, | |
205 net_log); | |
206 EXPECT_TRUE(retry_info_map.end() != retry_info_map.find("foopy1:80")); | |
207 EXPECT_EQ(OK, retry_info_map[proxy_server.ToURI()].net_error); | |
208 EXPECT_TRUE(retry_info_map.end() == retry_info_map.find("foopy2:80")); | |
209 EXPECT_TRUE(retry_info_map.end() == retry_info_map.find("foopy3:80")); | |
210 } | |
211 // Including another bad proxy should put both the first and the specified | |
212 // proxy on the retry list. | |
213 { | |
214 ProxyList list; | |
215 ProxyRetryInfoMap retry_info_map; | |
216 BoundNetLog net_log; | |
217 ProxyServer proxy_server = ProxyServer::FromURI("foopy3:80", | |
218 ProxyServer::SCHEME_HTTP); | |
219 list.SetFromPacString("PROXY foopy1:80;PROXY foopy2:80;PROXY foopy3:80"); | |
220 list.UpdateRetryInfoOnFallback(&retry_info_map, | |
221 base::TimeDelta::FromSeconds(60), | |
222 true, | |
223 proxy_server, | |
224 ERR_NAME_RESOLUTION_FAILED, | |
225 net_log); | |
226 EXPECT_TRUE(retry_info_map.end() != retry_info_map.find("foopy1:80")); | |
227 EXPECT_EQ(ERR_NAME_RESOLUTION_FAILED, | |
228 retry_info_map[proxy_server.ToURI()].net_error); | |
229 EXPECT_TRUE(retry_info_map.end() == retry_info_map.find("foopy2:80")); | |
230 EXPECT_TRUE(retry_info_map.end() != retry_info_map.find("foopy3:80")); | |
231 } | |
232 // If the first proxy is DIRECT, nothing is added to the retry list, even | |
233 // if another bad proxy is specified. | |
234 { | |
235 ProxyList list; | |
236 ProxyRetryInfoMap retry_info_map; | |
237 BoundNetLog net_log; | |
238 ProxyServer proxy_server = ProxyServer::FromURI("foopy2:80", | |
239 ProxyServer::SCHEME_HTTP); | |
240 list.SetFromPacString("DIRECT;PROXY foopy2:80;PROXY foopy3:80"); | |
241 list.UpdateRetryInfoOnFallback(&retry_info_map, | |
242 base::TimeDelta::FromSeconds(60), | |
243 true, | |
244 proxy_server, | |
245 OK, | |
246 net_log); | |
247 EXPECT_TRUE(retry_info_map.end() == retry_info_map.find("foopy2:80")); | |
248 EXPECT_TRUE(retry_info_map.end() == retry_info_map.find("foopy3:80")); | |
249 } | |
250 } | |
251 | |
252 } // namesapce | |
253 | |
254 } // namespace net | |
OLD | NEW |