15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/proxy/proxy_list.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "net/base/net_errors.h"
85d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "net/base/net_log.h"
95d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "net/proxy/proxy_retry_info.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/proxy/proxy_server.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace net {
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test parsing from a PAC string.
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(ProxyListTest, SetFromPacString) {
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const struct {
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char* pac_input;
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char* pac_output;
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } tests[] = {
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Valid inputs:
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {  "PROXY foopy:10",
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       "PROXY foopy:10",
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {  " DIRECT",  // leading space.
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       "DIRECT",
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {  "PROXY foopy1 ; proxy foopy2;\t DIRECT",
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       "PROXY foopy1:80;PROXY foopy2:80;DIRECT",
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {  "proxy foopy1 ; SOCKS foopy2",
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       "PROXY foopy1:80;SOCKS foopy2:1080",
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Try putting DIRECT first.
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {  "DIRECT ; proxy foopy1 ; DIRECT ; SOCKS5 foopy2;DIRECT ",
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       "DIRECT;PROXY foopy1:80;DIRECT;SOCKS5 foopy2:1080;DIRECT",
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Try putting DIRECT consecutively.
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {  "DIRECT ; proxy foopy1:80; DIRECT ; DIRECT",
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       "DIRECT;PROXY foopy1:80;DIRECT;DIRECT",
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Invalid inputs (parts which aren't understood get
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // silently discarded):
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // If the proxy list string parsed to empty, automatically fall-back to
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // DIRECT.
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {  "PROXY-foopy:10",
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       "DIRECT",
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {  "PROXY",
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       "DIRECT",
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {  "PROXY foopy1 ; JUNK ; JUNK ; SOCKS5 foopy2 ; ;",
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       "PROXY foopy1:80;SOCKS5 foopy2:1080",
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ProxyList list;
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    list.SetFromPacString(tests[i].pac_input);
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(tests[i].pac_output, list.ToPacString());
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(list.IsEmpty());
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(ProxyListTest, RemoveProxiesWithoutScheme) {
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const struct {
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char* pac_input;
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int filter;
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char* filtered_pac_output;
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } tests[] = {
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {  "PROXY foopy:10 ; SOCKS5 foopy2 ; SOCKS foopy11 ; PROXY foopy3 ; DIRECT",
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       // Remove anything that isn't HTTP or DIRECT.
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       ProxyServer::SCHEME_DIRECT | ProxyServer::SCHEME_HTTP,
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       "PROXY foopy:10;PROXY foopy3:80;DIRECT",
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {  "PROXY foopy:10 ; SOCKS5 foopy2",
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       // Remove anything that isn't HTTP or SOCKS5.
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       ProxyServer::SCHEME_DIRECT | ProxyServer::SCHEME_SOCKS4,
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       "",
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ProxyList list;
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    list.SetFromPacString(tests[i].pac_input);
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    list.RemoveProxiesWithoutScheme(tests[i].filter);
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(tests[i].filtered_pac_output, list.ToPacString());
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(ProxyListTest, DeprioritizeBadProxies) {
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Retry info that marks a proxy as being bad for a *very* long time (to avoid
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the test depending on the current time.)
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProxyRetryInfo proxy_retry_info;
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  proxy_retry_info.bad_until =
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::TimeTicks::Now() + base::TimeDelta::FromDays(1);
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Call DeprioritizeBadProxies with an empty map -- should have no effect.
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ProxyList list;
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    list.SetFromPacString("PROXY foopy1:80;PROXY foopy2:80;PROXY foopy3:80");
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ProxyRetryInfoMap retry_info_map;
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    list.DeprioritizeBadProxies(retry_info_map);
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ("PROXY foopy1:80;PROXY foopy2:80;PROXY foopy3:80",
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              list.ToPacString());
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Call DeprioritizeBadProxies with 2 of the three proxies marked as bad.
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // These proxies should be retried last.
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ProxyList list;
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    list.SetFromPacString("PROXY foopy1:80;PROXY foopy2:80;PROXY foopy3:80");
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ProxyRetryInfoMap retry_info_map;
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    retry_info_map["foopy1:80"] = proxy_retry_info;
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    retry_info_map["foopy3:80"] = proxy_retry_info;
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    retry_info_map["socks5://localhost:1080"] = proxy_retry_info;
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    list.DeprioritizeBadProxies(retry_info_map);
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ("PROXY foopy2:80;PROXY foopy1:80;PROXY foopy3:80",
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              list.ToPacString());
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Call DeprioritizeBadProxies where ALL of the proxies are marked as bad.
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This should have no effect on the order.
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ProxyList list;
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    list.SetFromPacString("PROXY foopy1:80;PROXY foopy2:80;PROXY foopy3:80");
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ProxyRetryInfoMap retry_info_map;
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    retry_info_map["foopy1:80"] = proxy_retry_info;
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    retry_info_map["foopy2:80"] = proxy_retry_info;
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    retry_info_map["foopy3:80"] = proxy_retry_info;
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    list.DeprioritizeBadProxies(retry_info_map);
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ("PROXY foopy1:80;PROXY foopy2:80;PROXY foopy3:80",
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              list.ToPacString());
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
146a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
147a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Call DeprioritizeBadProxies with 2 of the three proxies marked as bad. Of
148a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // the 2 bad proxies, one is to be reconsidered and should be retried last.
149a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // The other is not to be reconsidered and should be removed from the list.
150a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  {
151a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    ProxyList list;
152a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    list.SetFromPacString("PROXY foopy1:80;PROXY foopy2:80;PROXY foopy3:80");
153a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
154a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    ProxyRetryInfoMap retry_info_map;
155a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // |proxy_retry_info.reconsider defaults to true.
156a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    retry_info_map["foopy1:80"] = proxy_retry_info;
157a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    proxy_retry_info.try_while_bad = false;
158a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    retry_info_map["foopy3:80"] = proxy_retry_info;
159a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    proxy_retry_info.try_while_bad = true;
160a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    retry_info_map["socks5://localhost:1080"] = proxy_retry_info;
161a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
162a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    list.DeprioritizeBadProxies(retry_info_map);
163a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
164a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    EXPECT_EQ("PROXY foopy2:80;PROXY foopy1:80",
165a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)              list.ToPacString());
166a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST(ProxyListTest, UpdateRetryInfoOnFallback) {
1705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ProxyRetryInfo proxy_retry_info;
1715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Retrying should put the first proxy on the retry list.
1725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  {
1735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ProxyList list;
1745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ProxyRetryInfoMap retry_info_map;
1755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    BoundNetLog net_log;
17603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    ProxyServer proxy_server(
17703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        ProxyServer::FromURI("foopy1:80", ProxyServer::SCHEME_HTTP));
1785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    list.SetFromPacString("PROXY foopy1:80;PROXY foopy2:80;PROXY foopy3:80");
1795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    list.UpdateRetryInfoOnFallback(&retry_info_map,
1805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                   base::TimeDelta::FromSeconds(60),
181a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                   true,
18203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                                   proxy_server,
18303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                                   ERR_PROXY_CONNECTION_FAILED,
18403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                                   net_log);
18503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    EXPECT_TRUE(retry_info_map.end() != retry_info_map.find("foopy1:80"));
18603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    EXPECT_EQ(ERR_PROXY_CONNECTION_FAILED,
18703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)              retry_info_map[proxy_server.ToURI()].net_error);
18803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    EXPECT_TRUE(retry_info_map.end() == retry_info_map.find("foopy2:80"));
18903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    EXPECT_TRUE(retry_info_map.end() == retry_info_map.find("foopy3:80"));
19003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  }
19103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // Retrying should put the first proxy on the retry list, even if there
19203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // was no network error.
19303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  {
19403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    ProxyList list;
19503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    ProxyRetryInfoMap retry_info_map;
19603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    BoundNetLog net_log;
19703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    ProxyServer proxy_server(
19803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        ProxyServer::FromURI("foopy1:80", ProxyServer::SCHEME_HTTP));
19903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    list.SetFromPacString("PROXY foopy1:80;PROXY foopy2:80;PROXY foopy3:80");
20003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    list.UpdateRetryInfoOnFallback(&retry_info_map,
20103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                                   base::TimeDelta::FromSeconds(60),
20203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                                   true,
20303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                                   proxy_server,
20403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                                   OK,
2055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                   net_log);
2065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_TRUE(retry_info_map.end() != retry_info_map.find("foopy1:80"));
20703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    EXPECT_EQ(OK, retry_info_map[proxy_server.ToURI()].net_error);
2085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_TRUE(retry_info_map.end() == retry_info_map.find("foopy2:80"));
2095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_TRUE(retry_info_map.end() == retry_info_map.find("foopy3:80"));
2105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
2115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Including another bad proxy should put both the first and the specified
2125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // proxy on the retry list.
2135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  {
2145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ProxyList list;
2155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ProxyRetryInfoMap retry_info_map;
2165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    BoundNetLog net_log;
2175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ProxyServer proxy_server = ProxyServer::FromURI("foopy3:80",
2185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                                    ProxyServer::SCHEME_HTTP);
2195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    list.SetFromPacString("PROXY foopy1:80;PROXY foopy2:80;PROXY foopy3:80");
2205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    list.UpdateRetryInfoOnFallback(&retry_info_map,
2215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                   base::TimeDelta::FromSeconds(60),
222a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                   true,
2235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                   proxy_server,
22403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                                   ERR_NAME_RESOLUTION_FAILED,
2255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                   net_log);
2265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_TRUE(retry_info_map.end() != retry_info_map.find("foopy1:80"));
22703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    EXPECT_EQ(ERR_NAME_RESOLUTION_FAILED,
22803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)              retry_info_map[proxy_server.ToURI()].net_error);
2295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_TRUE(retry_info_map.end() == retry_info_map.find("foopy2:80"));
2305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_TRUE(retry_info_map.end() != retry_info_map.find("foopy3:80"));
2315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
2325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // If the first proxy is DIRECT, nothing is added to the retry list, even
2335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // if another bad proxy is specified.
2345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  {
2355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ProxyList list;
2365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ProxyRetryInfoMap retry_info_map;
2375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    BoundNetLog net_log;
2385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ProxyServer proxy_server = ProxyServer::FromURI("foopy2:80",
2395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                                    ProxyServer::SCHEME_HTTP);
2405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    list.SetFromPacString("DIRECT;PROXY foopy2:80;PROXY foopy3:80");
2415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    list.UpdateRetryInfoOnFallback(&retry_info_map,
2425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                   base::TimeDelta::FromSeconds(60),
243a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                   true,
2445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                   proxy_server,
24503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                                   OK,
2465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                   net_log);
2475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_TRUE(retry_info_map.end() == retry_info_map.find("foopy2:80"));
2485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_TRUE(retry_info_map.end() == retry_info_map.find("foopy3:80"));
2495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
2505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
2515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namesapce
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace net
255