15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 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) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/callback.h" 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h" 92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/strings/string_tokenizer.h" 10eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/time/time.h" 11c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/values.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/proxy/proxy_server.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::TimeDelta; 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::TimeTicks; 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace net { 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ProxyList::ProxyList() { 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ProxyList::~ProxyList() { 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ProxyList::Set(const std::string& proxy_uri_list) { 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) proxies_.clear(); 272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::StringTokenizer str_tok(proxy_uri_list, ";"); 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (str_tok.GetNext()) { 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ProxyServer uri = ProxyServer::FromURI( 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) str_tok.token_begin(), str_tok.token_end(), ProxyServer::SCHEME_HTTP); 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Silently discard malformed inputs. 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (uri.is_valid()) 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) proxies_.push_back(uri); 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ProxyList::SetSingleProxyServer(const ProxyServer& proxy_server) { 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) proxies_.clear(); 392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) AddProxyServer(proxy_server); 402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ProxyList::AddProxyServer(const ProxyServer& proxy_server) { 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (proxy_server.is_valid()) 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) proxies_.push_back(proxy_server); 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ProxyList::DeprioritizeBadProxies( 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ProxyRetryInfoMap& proxy_retry_info) { 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Partition the proxy list in two: 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // (1) the known bad proxies 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // (2) everything else 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<ProxyServer> good_proxies; 53a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) std::vector<ProxyServer> bad_proxies_to_try; 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<ProxyServer>::const_iterator iter = proxies_.begin(); 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (; iter != proxies_.end(); ++iter) { 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ProxyRetryInfoMap::const_iterator bad_proxy = 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) proxy_retry_info.find(iter->ToURI()); 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (bad_proxy != proxy_retry_info.end()) { 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This proxy is bad. Check if it's time to retry. 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (bad_proxy->second.bad_until >= TimeTicks::Now()) { 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // still invalid. 63a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (bad_proxy->second.try_while_bad) 64a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) bad_proxies_to_try.push_back(*iter); 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) good_proxies.push_back(*iter); 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // "proxies_ = good_proxies + bad_proxies" 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) proxies_.swap(good_proxies); 73a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) proxies_.insert(proxies_.end(), bad_proxies_to_try.begin(), 74a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) bad_proxies_to_try.end()); 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ProxyList::RemoveProxiesWithoutScheme(int scheme_bit_field) { 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (std::vector<ProxyServer>::iterator it = proxies_.begin(); 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) it != proxies_.end(); ) { 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!(scheme_bit_field & it->scheme())) { 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) it = proxies_.erase(it); 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++it; 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ProxyList::Clear() { 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) proxies_.clear(); 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ProxyList::IsEmpty() const { 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return proxies_.empty(); 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)size_t ProxyList::size() const { 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return proxies_.size(); 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Returns true if |*this| lists the same proxies as |other|. 1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool ProxyList::Equals(const ProxyList& other) const { 1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (size() != other.size()) 1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return proxies_ == other.proxies_; 1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const ProxyServer& ProxyList::Get() const { 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!proxies_.empty()); 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return proxies_[0]; 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ProxyList::SetFromPacString(const std::string& pac_string) { 1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::StringTokenizer entry_tok(pac_string, ";"); 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) proxies_.clear(); 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (entry_tok.GetNext()) { 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ProxyServer uri = ProxyServer::FromPacString( 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entry_tok.token_begin(), entry_tok.token_end()); 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Silently discard malformed inputs. 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (uri.is_valid()) 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) proxies_.push_back(uri); 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If we failed to parse anything from the PAC results list, fallback to 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // DIRECT (this basically means an error in the PAC script). 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (proxies_.empty()) { 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) proxies_.push_back(ProxyServer::Direct()); 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string ProxyList::ToPacString() const { 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string proxy_list; 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<ProxyServer>::const_iterator iter = proxies_.begin(); 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (; iter != proxies_.end(); ++iter) { 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!proxy_list.empty()) 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) proxy_list += ";"; 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) proxy_list += iter->ToPacString(); 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return proxy_list.empty() ? std::string() : proxy_list; 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 141c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)base::ListValue* ProxyList::ToValue() const { 142c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::ListValue* list = new base::ListValue(); 143c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) for (size_t i = 0; i < proxies_.size(); ++i) 144c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) list->AppendString(proxies_[i].ToURI()); 145c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return list; 146c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 147c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ProxyList::Fallback(ProxyRetryInfoMap* proxy_retry_info, 14903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) int net_error, 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const BoundNetLog& net_log) { 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(eroman): It would be good if instead of removing failed proxies 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // from the list, we simply annotated them with the error code they failed 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // with. Of course, ProxyService::ReconsiderProxyAfterError() would need to 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // be given this information by the network transaction. 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The advantage of this approach is when the network transaction 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // fails, we could output the full list of proxies that were attempted, and 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // why each one of those failed (as opposed to just the last failure). 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // And also, before failing the transaction wholesale, we could go back and 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // retry the "bad proxies" which we never tried to begin with. 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // (RemoveBadProxies would annotate them as 'expected bad' rather then delete 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // them from the list, so we would know what they were). 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (proxies_.empty()) { 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // By default, proxies are not retried for 5 minutes. 1715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) UpdateRetryInfoOnFallback(proxy_retry_info, 1725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) TimeDelta::FromMinutes(5), 1735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) true, 1745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ProxyServer(), 17503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) net_error, 1765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) net_log); 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Remove this proxy from our list. 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) proxies_.erase(proxies_.begin()); 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return !proxies_.empty(); 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void ProxyList::AddProxyToRetryList(ProxyRetryInfoMap* proxy_retry_info, 1845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::TimeDelta retry_delay, 185a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) bool try_while_bad, 1865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const ProxyServer& proxy_to_retry, 18703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) int net_error, 1885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const BoundNetLog& net_log) const { 1895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Mark this proxy as bad. 1905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::string proxy_key = proxy_to_retry.ToURI(); 1915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ProxyRetryInfoMap::iterator iter = proxy_retry_info->find(proxy_key); 1925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (iter != proxy_retry_info->end()) { 1935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // TODO(nsylvain): This is not the first time we get this. We should 1945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // double the retry time. Bug 997660. 1955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) iter->second.bad_until = TimeTicks::Now() + iter->second.current_delay; 1965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } else { 1975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ProxyRetryInfo retry_info; 1985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) retry_info.current_delay = retry_delay; 1995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) retry_info.bad_until = TimeTicks().Now() + retry_info.current_delay; 200a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) retry_info.try_while_bad = try_while_bad; 20103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) retry_info.net_error = net_error; 2025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) (*proxy_retry_info)[proxy_key] = retry_info; 2035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 2045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) net_log.AddEvent(NetLog::TYPE_PROXY_LIST_FALLBACK, 2055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) NetLog::StringCallback("bad_proxy", &proxy_key)); 2065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 2075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void ProxyList::UpdateRetryInfoOnFallback( 2095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ProxyRetryInfoMap* proxy_retry_info, 2105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::TimeDelta retry_delay, 211a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) bool reconsider, 2125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const ProxyServer& another_proxy_to_bypass, 21303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) int net_error, 2145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const BoundNetLog& net_log) const { 2155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) DCHECK(retry_delay != base::TimeDelta()); 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (proxies_.empty()) { 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!proxies_[0].is_direct()) { 22303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) AddProxyToRetryList(proxy_retry_info, 22403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) retry_delay, 22503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) reconsider, 22603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) proxies_[0], 22703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) net_error, 228a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) net_log); 2295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // If an additional proxy to bypass is specified, add it to the retry map 2315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // as well. 2325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (another_proxy_to_bypass.is_valid()) { 23303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) AddProxyToRetryList(proxy_retry_info, 23403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) retry_delay, 23503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) reconsider, 23603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) another_proxy_to_bypass, 23703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) net_error, 23803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) net_log); 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace net 244