OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/callback.h" | 7 #include "base/callback.h" |
8 #include "base/logging.h" | 8 #include "base/logging.h" |
9 #include "base/rand_util.h" | 9 #include "base/rand_util.h" |
10 #include "base/strings/string_tokenizer.h" | 10 #include "base/strings/string_tokenizer.h" |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
64 if (bad_proxy->second.try_while_bad) | 64 if (bad_proxy->second.try_while_bad) |
65 bad_proxies_to_try.push_back(*iter); | 65 bad_proxies_to_try.push_back(*iter); |
66 continue; | 66 continue; |
67 } | 67 } |
68 } | 68 } |
69 good_proxies.push_back(*iter); | 69 good_proxies.push_back(*iter); |
70 } | 70 } |
71 | 71 |
72 // "proxies_ = good_proxies + bad_proxies" | 72 // "proxies_ = good_proxies + bad_proxies" |
73 proxies_.swap(good_proxies); | 73 proxies_.swap(good_proxies); |
74 proxies_.insert(proxies_.end(), bad_proxies_to_try.begin(), | 74 proxies_.insert( |
75 bad_proxies_to_try.end()); | 75 proxies_.end(), bad_proxies_to_try.begin(), bad_proxies_to_try.end()); |
76 } | 76 } |
77 | 77 |
78 void ProxyList::RemoveProxiesWithoutScheme(int scheme_bit_field) { | 78 void ProxyList::RemoveProxiesWithoutScheme(int scheme_bit_field) { |
79 for (std::vector<ProxyServer>::iterator it = proxies_.begin(); | 79 for (std::vector<ProxyServer>::iterator it = proxies_.begin(); |
80 it != proxies_.end(); ) { | 80 it != proxies_.end();) { |
81 if (!(scheme_bit_field & it->scheme())) { | 81 if (!(scheme_bit_field & it->scheme())) { |
82 it = proxies_.erase(it); | 82 it = proxies_.erase(it); |
83 continue; | 83 continue; |
84 } | 84 } |
85 ++it; | 85 ++it; |
86 } | 86 } |
87 } | 87 } |
88 | 88 |
89 void ProxyList::Clear() { | 89 void ProxyList::Clear() { |
90 proxies_.clear(); | 90 proxies_.clear(); |
(...skipping 16 matching lines...) Expand all Loading... |
107 | 107 |
108 const ProxyServer& ProxyList::Get() const { | 108 const ProxyServer& ProxyList::Get() const { |
109 DCHECK(!proxies_.empty()); | 109 DCHECK(!proxies_.empty()); |
110 return proxies_[0]; | 110 return proxies_[0]; |
111 } | 111 } |
112 | 112 |
113 void ProxyList::SetFromPacString(const std::string& pac_string) { | 113 void ProxyList::SetFromPacString(const std::string& pac_string) { |
114 base::StringTokenizer entry_tok(pac_string, ";"); | 114 base::StringTokenizer entry_tok(pac_string, ";"); |
115 proxies_.clear(); | 115 proxies_.clear(); |
116 while (entry_tok.GetNext()) { | 116 while (entry_tok.GetNext()) { |
117 ProxyServer uri = ProxyServer::FromPacString( | 117 ProxyServer uri = ProxyServer::FromPacString(entry_tok.token_begin(), |
118 entry_tok.token_begin(), entry_tok.token_end()); | 118 entry_tok.token_end()); |
119 // Silently discard malformed inputs. | 119 // Silently discard malformed inputs. |
120 if (uri.is_valid()) | 120 if (uri.is_valid()) |
121 proxies_.push_back(uri); | 121 proxies_.push_back(uri); |
122 } | 122 } |
123 | 123 |
124 // If we failed to parse anything from the PAC results list, fallback to | 124 // If we failed to parse anything from the PAC results list, fallback to |
125 // DIRECT (this basically means an error in the PAC script). | 125 // DIRECT (this basically means an error in the PAC script). |
126 if (proxies_.empty()) { | 126 if (proxies_.empty()) { |
127 proxies_.push_back(ProxyServer::Direct()); | 127 proxies_.push_back(ProxyServer::Direct()); |
128 } | 128 } |
(...skipping 12 matching lines...) Expand all Loading... |
141 | 141 |
142 base::ListValue* ProxyList::ToValue() const { | 142 base::ListValue* ProxyList::ToValue() const { |
143 base::ListValue* list = new base::ListValue(); | 143 base::ListValue* list = new base::ListValue(); |
144 for (size_t i = 0; i < proxies_.size(); ++i) | 144 for (size_t i = 0; i < proxies_.size(); ++i) |
145 list->AppendString(proxies_[i].ToURI()); | 145 list->AppendString(proxies_[i].ToURI()); |
146 return list; | 146 return list; |
147 } | 147 } |
148 | 148 |
149 bool ProxyList::Fallback(ProxyRetryInfoMap* proxy_retry_info, | 149 bool ProxyList::Fallback(ProxyRetryInfoMap* proxy_retry_info, |
150 const BoundNetLog& net_log) { | 150 const BoundNetLog& net_log) { |
151 | |
152 // TODO(eroman): It would be good if instead of removing failed proxies | 151 // TODO(eroman): It would be good if instead of removing failed proxies |
153 // from the list, we simply annotated them with the error code they failed | 152 // from the list, we simply annotated them with the error code they failed |
154 // with. Of course, ProxyService::ReconsiderProxyAfterError() would need to | 153 // with. Of course, ProxyService::ReconsiderProxyAfterError() would need to |
155 // be given this information by the network transaction. | 154 // be given this information by the network transaction. |
156 // | 155 // |
157 // The advantage of this approach is when the network transaction | 156 // The advantage of this approach is when the network transaction |
158 // fails, we could output the full list of proxies that were attempted, and | 157 // fails, we could output the full list of proxies that were attempted, and |
159 // why each one of those failed (as opposed to just the last failure). | 158 // why each one of those failed (as opposed to just the last failure). |
160 // | 159 // |
161 // And also, before failing the transaction wholesale, we could go back and | 160 // And also, before failing the transaction wholesale, we could go back and |
162 // retry the "bad proxies" which we never tried to begin with. | 161 // retry the "bad proxies" which we never tried to begin with. |
163 // (RemoveBadProxies would annotate them as 'expected bad' rather then delete | 162 // (RemoveBadProxies would annotate them as 'expected bad' rather then delete |
164 // them from the list, so we would know what they were). | 163 // them from the list, so we would know what they were). |
165 | 164 |
166 if (proxies_.empty()) { | 165 if (proxies_.empty()) { |
167 NOTREACHED(); | 166 NOTREACHED(); |
168 return false; | 167 return false; |
169 } | 168 } |
170 UpdateRetryInfoOnFallback(proxy_retry_info, base::TimeDelta(), true, | 169 UpdateRetryInfoOnFallback( |
171 ProxyServer(), net_log); | 170 proxy_retry_info, base::TimeDelta(), true, ProxyServer(), net_log); |
172 | 171 |
173 // Remove this proxy from our list. | 172 // Remove this proxy from our list. |
174 proxies_.erase(proxies_.begin()); | 173 proxies_.erase(proxies_.begin()); |
175 return !proxies_.empty(); | 174 return !proxies_.empty(); |
176 } | 175 } |
177 | 176 |
178 void ProxyList::AddProxyToRetryList(ProxyRetryInfoMap* proxy_retry_info, | 177 void ProxyList::AddProxyToRetryList(ProxyRetryInfoMap* proxy_retry_info, |
179 base::TimeDelta retry_delay, | 178 base::TimeDelta retry_delay, |
180 bool try_while_bad, | 179 bool try_while_bad, |
181 const ProxyServer& proxy_to_retry, | 180 const ProxyServer& proxy_to_retry, |
(...skipping 19 matching lines...) Expand all Loading... |
201 void ProxyList::UpdateRetryInfoOnFallback( | 200 void ProxyList::UpdateRetryInfoOnFallback( |
202 ProxyRetryInfoMap* proxy_retry_info, | 201 ProxyRetryInfoMap* proxy_retry_info, |
203 base::TimeDelta retry_delay, | 202 base::TimeDelta retry_delay, |
204 bool reconsider, | 203 bool reconsider, |
205 const ProxyServer& another_proxy_to_bypass, | 204 const ProxyServer& another_proxy_to_bypass, |
206 const BoundNetLog& net_log) const { | 205 const BoundNetLog& net_log) const { |
207 // Time to wait before retrying a bad proxy server. | 206 // Time to wait before retrying a bad proxy server. |
208 if (retry_delay == base::TimeDelta()) { | 207 if (retry_delay == base::TimeDelta()) { |
209 #if defined(SPDY_PROXY_AUTH_ORIGIN) | 208 #if defined(SPDY_PROXY_AUTH_ORIGIN) |
210 // Randomize the timeout over a range from one to five minutes. | 209 // Randomize the timeout over a range from one to five minutes. |
211 retry_delay = | 210 retry_delay = TimeDelta::FromMilliseconds( |
212 TimeDelta::FromMilliseconds( | 211 base::RandInt(1 * 60 * 1000, 5 * 60 * 1000)); |
213 base::RandInt(1 * 60 * 1000, 5 * 60 * 1000)); | |
214 #else | 212 #else |
215 retry_delay = TimeDelta::FromMinutes(5); | 213 retry_delay = TimeDelta::FromMinutes(5); |
216 #endif | 214 #endif |
217 } | 215 } |
218 | 216 |
219 if (proxies_.empty()) { | 217 if (proxies_.empty()) { |
220 NOTREACHED(); | 218 NOTREACHED(); |
221 return; | 219 return; |
222 } | 220 } |
223 | 221 |
224 if (!proxies_[0].is_direct()) { | 222 if (!proxies_[0].is_direct()) { |
225 AddProxyToRetryList(proxy_retry_info, retry_delay, reconsider, proxies_[0], | 223 AddProxyToRetryList( |
226 net_log); | 224 proxy_retry_info, retry_delay, reconsider, proxies_[0], net_log); |
227 | 225 |
228 // If an additional proxy to bypass is specified, add it to the retry map | 226 // If an additional proxy to bypass is specified, add it to the retry map |
229 // as well. | 227 // as well. |
230 if (another_proxy_to_bypass.is_valid()) { | 228 if (another_proxy_to_bypass.is_valid()) { |
231 AddProxyToRetryList(proxy_retry_info, retry_delay, reconsider, | 229 AddProxyToRetryList(proxy_retry_info, |
232 another_proxy_to_bypass, net_log); | 230 retry_delay, |
| 231 reconsider, |
| 232 another_proxy_to_bypass, |
| 233 net_log); |
233 } | 234 } |
234 } | 235 } |
235 } | 236 } |
236 | 237 |
237 } // namespace net | 238 } // namespace net |
OLD | NEW |