Chromium Code Reviews| 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/string_tokenizer.h" | 9 #include "base/string_tokenizer.h" |
| 10 #include "base/time.h" | 10 #include "base/time.h" |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 60 } | 60 } |
| 61 } | 61 } |
| 62 good_proxies.push_back(*iter); | 62 good_proxies.push_back(*iter); |
| 63 } | 63 } |
| 64 | 64 |
| 65 // "proxies_ = good_proxies + bad_proxies" | 65 // "proxies_ = good_proxies + bad_proxies" |
| 66 proxies_.swap(good_proxies); | 66 proxies_.swap(good_proxies); |
| 67 proxies_.insert(proxies_.end(), bad_proxies.begin(), bad_proxies.end()); | 67 proxies_.insert(proxies_.end(), bad_proxies.begin(), bad_proxies.end()); |
| 68 } | 68 } |
| 69 | 69 |
| 70 bool ProxyList::HasUntriedProxies( | |
| 71 const ProxyRetryInfoMap& proxy_retry_info) const { | |
| 72 std::vector<ProxyServer>::const_iterator iter = proxies_.begin(); | |
| 73 for (; iter != proxies_.end(); ++iter) { | |
| 74 ProxyRetryInfoMap::const_iterator bad_proxy = | |
| 75 proxy_retry_info.find(iter->ToURI()); | |
| 76 if (bad_proxy != proxy_retry_info.end()) { | |
| 77 // This proxy is bad. Check if it's time to retry. | |
| 78 if (bad_proxy->second.bad_until >= TimeTicks::Now()) { | |
| 79 continue; | |
| 80 } | |
| 81 } | |
| 82 // Either we've found the entry in the retry map and it's expired or we | |
| 83 // didn't find a corresponding entry in the retry map. In either case, we | |
| 84 // have a proxy to try. | |
| 85 return true; | |
|
eroman
2012/10/12 18:30:58
Note |proxies_| can also contain entries for "DIRE
Michael Piatek
2012/10/15 17:10:16
Done.
| |
| 86 } | |
| 87 return false; | |
| 88 } | |
| 89 | |
| 70 void ProxyList::RemoveProxiesWithoutScheme(int scheme_bit_field) { | 90 void ProxyList::RemoveProxiesWithoutScheme(int scheme_bit_field) { |
| 71 for (std::vector<ProxyServer>::iterator it = proxies_.begin(); | 91 for (std::vector<ProxyServer>::iterator it = proxies_.begin(); |
| 72 it != proxies_.end(); ) { | 92 it != proxies_.end(); ) { |
| 73 if (!(scheme_bit_field & it->scheme())) { | 93 if (!(scheme_bit_field & it->scheme())) { |
| 74 it = proxies_.erase(it); | 94 it = proxies_.erase(it); |
| 75 continue; | 95 continue; |
| 76 } | 96 } |
| 77 ++it; | 97 ++it; |
| 78 } | 98 } |
| 79 } | 99 } |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 119 for (; iter != proxies_.end(); ++iter) { | 139 for (; iter != proxies_.end(); ++iter) { |
| 120 if (!proxy_list.empty()) | 140 if (!proxy_list.empty()) |
| 121 proxy_list += ";"; | 141 proxy_list += ";"; |
| 122 proxy_list += iter->ToPacString(); | 142 proxy_list += iter->ToPacString(); |
| 123 } | 143 } |
| 124 return proxy_list.empty() ? std::string() : proxy_list; | 144 return proxy_list.empty() ? std::string() : proxy_list; |
| 125 } | 145 } |
| 126 | 146 |
| 127 bool ProxyList::Fallback(ProxyRetryInfoMap* proxy_retry_info, | 147 bool ProxyList::Fallback(ProxyRetryInfoMap* proxy_retry_info, |
| 128 const BoundNetLog& net_log) { | 148 const BoundNetLog& net_log) { |
| 129 // Number of minutes to wait before retrying a bad proxy server. | |
| 130 const TimeDelta kProxyRetryDelay = TimeDelta::FromMinutes(5); | |
| 131 | 149 |
| 132 // TODO(eroman): It would be good if instead of removing failed proxies | 150 // TODO(eroman): It would be good if instead of removing failed proxies |
| 133 // from the list, we simply annotated them with the error code they failed | 151 // from the list, we simply annotated them with the error code they failed |
| 134 // with. Of course, ProxyService::ReconsiderProxyAfterError() would need to | 152 // with. Of course, ProxyService::ReconsiderProxyAfterError() would need to |
| 135 // be given this information by the network transaction. | 153 // be given this information by the network transaction. |
| 136 // | 154 // |
| 137 // The advantage of this approach is when the network transaction | 155 // The advantage of this approach is when the network transaction |
| 138 // fails, we could output the full list of proxies that were attempted, and | 156 // fails, we could output the full list of proxies that were attempted, and |
| 139 // why each one of those failed (as opposed to just the last failure). | 157 // why each one of those failed (as opposed to just the last failure). |
| 140 // | 158 // |
| 141 // And also, before failing the transaction wholesale, we could go back and | 159 // And also, before failing the transaction wholesale, we could go back and |
| 142 // retry the "bad proxies" which we never tried to begin with. | 160 // retry the "bad proxies" which we never tried to begin with. |
| 143 // (RemoveBadProxies would annotate them as 'expected bad' rather then delete | 161 // (RemoveBadProxies would annotate them as 'expected bad' rather then delete |
| 144 // them from the list, so we would know what they were). | 162 // them from the list, so we would know what they were). |
| 145 | 163 |
| 146 if (proxies_.empty()) { | 164 if (proxies_.empty()) { |
| 147 NOTREACHED(); | 165 NOTREACHED(); |
| 148 return false; | 166 return false; |
| 149 } | 167 } |
| 168 UpdateRetryInfoOnFallback(proxy_retry_info, net_log); | |
| 169 | |
| 170 // Remove this proxy from our list. | |
| 171 proxies_.erase(proxies_.begin()); | |
| 172 return !proxies_.empty(); | |
| 173 } | |
| 174 | |
| 175 void ProxyList::UpdateRetryInfoOnFallback( | |
| 176 ProxyRetryInfoMap* proxy_retry_info, const BoundNetLog& net_log) const { | |
| 177 // Number of minutes to wait before retrying a bad proxy server. | |
| 178 const TimeDelta kProxyRetryDelay = TimeDelta::FromMinutes(5); | |
| 179 | |
| 180 if (proxies_.empty()) { | |
| 181 NOTREACHED(); | |
| 182 return; | |
| 183 } | |
| 150 | 184 |
| 151 if (!proxies_[0].is_direct()) { | 185 if (!proxies_[0].is_direct()) { |
| 152 std::string key = proxies_[0].ToURI(); | 186 std::string key = proxies_[0].ToURI(); |
| 153 // Mark this proxy as bad. | 187 // Mark this proxy as bad. |
| 154 ProxyRetryInfoMap::iterator iter = proxy_retry_info->find(key); | 188 ProxyRetryInfoMap::iterator iter = proxy_retry_info->find(key); |
| 155 if (iter != proxy_retry_info->end()) { | 189 if (iter != proxy_retry_info->end()) { |
| 156 // TODO(nsylvain): This is not the first time we get this. We should | 190 // TODO(nsylvain): This is not the first time we get this. We should |
| 157 // double the retry time. Bug 997660. | 191 // double the retry time. Bug 997660. |
| 158 iter->second.bad_until = TimeTicks::Now() + iter->second.current_delay; | 192 iter->second.bad_until = TimeTicks::Now() + iter->second.current_delay; |
| 159 } else { | 193 } else { |
| 160 ProxyRetryInfo retry_info; | 194 ProxyRetryInfo retry_info; |
| 161 retry_info.current_delay = kProxyRetryDelay; | 195 retry_info.current_delay = kProxyRetryDelay; |
| 162 retry_info.bad_until = TimeTicks().Now() + retry_info.current_delay; | 196 retry_info.bad_until = TimeTicks().Now() + retry_info.current_delay; |
| 163 (*proxy_retry_info)[key] = retry_info; | 197 (*proxy_retry_info)[key] = retry_info; |
| 164 } | 198 } |
| 165 net_log.AddEvent(NetLog::TYPE_PROXY_LIST_FALLBACK, | 199 net_log.AddEvent(NetLog::TYPE_PROXY_LIST_FALLBACK, |
| 166 NetLog::StringCallback("bad_proxy", &key)); | 200 NetLog::StringCallback("bad_proxy", &key)); |
| 167 } | 201 } |
| 168 | |
| 169 // Remove this proxy from our list. | |
| 170 proxies_.erase(proxies_.begin()); | |
| 171 | |
| 172 return !proxies_.empty(); | |
| 173 } | 202 } |
| 174 | 203 |
| 175 } // namespace net | 204 } // namespace net |
| OLD | NEW |