blob: e390bbc80eeba9ae502308bea9bba9e26e8a3a53 [file] [log] [blame]
[email protected]7dc52f22009-03-02 22:37:181// 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 "base/logging.h"
8#include "base/string_tokenizer.h"
9#include "base/time.h"
10
11using base::TimeDelta;
12using base::TimeTicks;
13
14namespace net {
15
16void ProxyList::Set(const std::string& proxy_uri_list) {
17 proxies_.clear();
18 StringTokenizer str_tok(proxy_uri_list, ";");
19 while (str_tok.GetNext()) {
20 ProxyServer uri = ProxyServer::FromURI(
21 str_tok.token_begin(), str_tok.token_end());
22 // Silently discard malformed inputs.
23 if (uri.is_valid())
24 proxies_.push_back(uri);
25 }
26}
27
[email protected]5b45aec02009-03-31 01:03:2328void ProxyList::SetSingleProxyServer(const ProxyServer& proxy_server) {
29 proxies_.clear();
30 if (proxy_server.is_valid())
31 proxies_.push_back(proxy_server);
32}
33
[email protected]7dc52f22009-03-02 22:37:1834void ProxyList::RemoveBadProxies(const ProxyRetryInfoMap& proxy_retry_info) {
35 std::vector<ProxyServer> new_proxy_list;
36 std::vector<ProxyServer>::const_iterator iter = proxies_.begin();
37 for (; iter != proxies_.end(); ++iter) {
38 ProxyRetryInfoMap::const_iterator bad_proxy =
39 proxy_retry_info.find(iter->ToURI());
40 if (bad_proxy != proxy_retry_info.end()) {
41 // This proxy is bad. Check if it's time to retry.
42 if (bad_proxy->second.bad_until >= TimeTicks::Now()) {
43 // still invalid.
44 continue;
45 }
46 }
47 new_proxy_list.push_back(*iter);
48 }
49
50 proxies_ = new_proxy_list;
51}
52
53void ProxyList::RemoveProxiesWithoutScheme(int scheme_bit_field) {
54 for (std::vector<ProxyServer>::iterator it = proxies_.begin();
55 it != proxies_.end(); ) {
56 if (!(scheme_bit_field & it->scheme())) {
57 it = proxies_.erase(it);
58 continue;
59 }
60 ++it;
61 }
62}
63
64ProxyServer ProxyList::Get() const {
65 if (!proxies_.empty())
66 return proxies_[0];
67 return ProxyServer(ProxyServer::SCHEME_DIRECT, std::string(), -1);
68}
69
70std::string ProxyList::ToPacString() const {
71 std::string proxy_list;
72 std::vector<ProxyServer>::const_iterator iter = proxies_.begin();
73 for (; iter != proxies_.end(); ++iter) {
74 if (!proxy_list.empty())
75 proxy_list += ";";
76 proxy_list += iter->ToPacString();
77 }
78 return proxy_list.empty() ? "DIRECT" : proxy_list;
79}
80
81void ProxyList::SetFromPacString(const std::string& pac_string) {
82 StringTokenizer entry_tok(pac_string, ";");
83 proxies_.clear();
84 while (entry_tok.GetNext()) {
85 ProxyServer uri = ProxyServer::FromPacString(
86 entry_tok.token_begin(), entry_tok.token_end());
87 // Silently discard malformed inputs.
88 if (uri.is_valid())
89 proxies_.push_back(uri);
90 }
91}
92
93bool ProxyList::Fallback(ProxyRetryInfoMap* proxy_retry_info) {
94 // Number of minutes to wait before retrying a bad proxy server.
95 const TimeDelta kProxyRetryDelay = TimeDelta::FromMinutes(5);
96
97 if (proxies_.empty()) {
98 NOTREACHED();
99 return false;
100 }
101
102 std::string key = proxies_[0].ToURI();
103
104 // Mark this proxy as bad.
105 ProxyRetryInfoMap::iterator iter = proxy_retry_info->find(key);
106 if (iter != proxy_retry_info->end()) {
107 // TODO(nsylvain): This is not the first time we get this. We should
108 // double the retry time. Bug 997660.
109 iter->second.bad_until = TimeTicks::Now() + iter->second.current_delay;
110 } else {
111 ProxyRetryInfo retry_info;
112 retry_info.current_delay = kProxyRetryDelay;
113 retry_info.bad_until = TimeTicks().Now() + retry_info.current_delay;
114 (*proxy_retry_info)[key] = retry_info;
115 }
116
117 // Remove this proxy from our list.
118 proxies_.erase(proxies_.begin());
119
120 return !proxies_.empty();
121}
122
123} // namespace net