OLD | NEW |
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "net/proxy/proxy_list.h" | 5 #include "net/proxy/proxy_list.h" |
6 | 6 |
7 #include "base/logging.h" | 7 #include "base/logging.h" |
8 #include "base/string_tokenizer.h" | 8 #include "base/string_tokenizer.h" |
9 #include "base/time.h" | 9 #include "base/time.h" |
10 | 10 |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
54 for (std::vector<ProxyServer>::iterator it = proxies_.begin(); | 54 for (std::vector<ProxyServer>::iterator it = proxies_.begin(); |
55 it != proxies_.end(); ) { | 55 it != proxies_.end(); ) { |
56 if (!(scheme_bit_field & it->scheme())) { | 56 if (!(scheme_bit_field & it->scheme())) { |
57 it = proxies_.erase(it); | 57 it = proxies_.erase(it); |
58 continue; | 58 continue; |
59 } | 59 } |
60 ++it; | 60 ++it; |
61 } | 61 } |
62 } | 62 } |
63 | 63 |
64 ProxyServer ProxyList::Get() const { | 64 bool ProxyList::IsEmpty() const { |
65 if (!proxies_.empty()) | 65 return proxies_.empty(); |
66 return proxies_[0]; | 66 } |
67 return ProxyServer(ProxyServer::SCHEME_DIRECT, std::string(), -1); | 67 |
| 68 const ProxyServer& ProxyList::Get() const { |
| 69 DCHECK(!proxies_.empty()); |
| 70 return proxies_[0]; |
68 } | 71 } |
69 | 72 |
70 std::string ProxyList::ToPacString() const { | 73 std::string ProxyList::ToPacString() const { |
71 std::string proxy_list; | 74 std::string proxy_list; |
72 std::vector<ProxyServer>::const_iterator iter = proxies_.begin(); | 75 std::vector<ProxyServer>::const_iterator iter = proxies_.begin(); |
73 for (; iter != proxies_.end(); ++iter) { | 76 for (; iter != proxies_.end(); ++iter) { |
74 if (!proxy_list.empty()) | 77 if (!proxy_list.empty()) |
75 proxy_list += ";"; | 78 proxy_list += ";"; |
76 proxy_list += iter->ToPacString(); | 79 proxy_list += iter->ToPacString(); |
77 } | 80 } |
78 return proxy_list.empty() ? "DIRECT" : proxy_list; | 81 return proxy_list.empty() ? std::string() : proxy_list; |
79 } | 82 } |
80 | 83 |
81 void ProxyList::SetFromPacString(const std::string& pac_string) { | 84 void ProxyList::SetFromPacString(const std::string& pac_string) { |
82 StringTokenizer entry_tok(pac_string, ";"); | 85 StringTokenizer entry_tok(pac_string, ";"); |
83 proxies_.clear(); | 86 proxies_.clear(); |
84 while (entry_tok.GetNext()) { | 87 while (entry_tok.GetNext()) { |
85 ProxyServer uri = ProxyServer::FromPacString( | 88 ProxyServer uri = ProxyServer::FromPacString( |
86 entry_tok.token_begin(), entry_tok.token_end()); | 89 entry_tok.token_begin(), entry_tok.token_end()); |
87 // Silently discard malformed inputs. | 90 // Silently discard malformed inputs. |
88 if (uri.is_valid()) | 91 if (uri.is_valid()) |
89 proxies_.push_back(uri); | 92 proxies_.push_back(uri); |
90 } | 93 } |
| 94 |
| 95 // If we failed to parse anything from the PAC results list, fallback to |
| 96 // DIRECT (this basically means an error in the PAC script). |
| 97 if (proxies_.empty()) { |
| 98 proxies_.push_back(ProxyServer::Direct()); |
| 99 } |
91 } | 100 } |
92 | 101 |
93 bool ProxyList::Fallback(ProxyRetryInfoMap* proxy_retry_info) { | 102 bool ProxyList::Fallback(ProxyRetryInfoMap* proxy_retry_info) { |
94 // Number of minutes to wait before retrying a bad proxy server. | 103 // Number of minutes to wait before retrying a bad proxy server. |
95 const TimeDelta kProxyRetryDelay = TimeDelta::FromMinutes(5); | 104 const TimeDelta kProxyRetryDelay = TimeDelta::FromMinutes(5); |
96 | 105 |
| 106 // TODO(eroman): It would be good if instead of removing failed proxies |
| 107 // from the list, we simply annotated them with the error code they failed |
| 108 // with. Of course, ProxyService::ReconsiderProxyAfterError() would need to |
| 109 // be given this information by the network transaction. |
| 110 // |
| 111 // The advantage of this approach is when the network transaction |
| 112 // fails, we could output the full list of proxies that were attempted, and |
| 113 // why each one of those failed (as opposed to just the last failure). |
| 114 // |
| 115 // And also, before failing the transaction wholesale, we could go back and |
| 116 // retry the "bad proxies" which we never tried to begin with. |
| 117 // (RemoveBadProxies would annotate them as 'expected bad' rather then delete |
| 118 // them from the list, so we would know what they were). |
| 119 |
97 if (proxies_.empty()) { | 120 if (proxies_.empty()) { |
98 NOTREACHED(); | 121 NOTREACHED(); |
99 return false; | 122 return false; |
100 } | 123 } |
101 | 124 |
102 std::string key = proxies_[0].ToURI(); | 125 if (!proxies_[0].is_direct()) { |
103 | 126 std::string key = proxies_[0].ToURI(); |
104 // Mark this proxy as bad. | 127 // Mark this proxy as bad. |
105 ProxyRetryInfoMap::iterator iter = proxy_retry_info->find(key); | 128 ProxyRetryInfoMap::iterator iter = proxy_retry_info->find(key); |
106 if (iter != proxy_retry_info->end()) { | 129 if (iter != proxy_retry_info->end()) { |
107 // TODO(nsylvain): This is not the first time we get this. We should | 130 // TODO(nsylvain): This is not the first time we get this. We should |
108 // double the retry time. Bug 997660. | 131 // double the retry time. Bug 997660. |
109 iter->second.bad_until = TimeTicks::Now() + iter->second.current_delay; | 132 iter->second.bad_until = TimeTicks::Now() + iter->second.current_delay; |
110 } else { | 133 } else { |
111 ProxyRetryInfo retry_info; | 134 ProxyRetryInfo retry_info; |
112 retry_info.current_delay = kProxyRetryDelay; | 135 retry_info.current_delay = kProxyRetryDelay; |
113 retry_info.bad_until = TimeTicks().Now() + retry_info.current_delay; | 136 retry_info.bad_until = TimeTicks().Now() + retry_info.current_delay; |
114 (*proxy_retry_info)[key] = retry_info; | 137 (*proxy_retry_info)[key] = retry_info; |
| 138 } |
115 } | 139 } |
116 | 140 |
117 // Remove this proxy from our list. | 141 // Remove this proxy from our list. |
118 proxies_.erase(proxies_.begin()); | 142 proxies_.erase(proxies_.begin()); |
119 | 143 |
120 return !proxies_.empty(); | 144 return !proxies_.empty(); |
121 } | 145 } |
122 | 146 |
123 } // namespace net | 147 } // namespace net |
OLD | NEW |