OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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_service.h" | 5 #include "net/proxy/proxy_service.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
| 9 #include "base/bind.h" |
| 10 #include "base/bind_helpers.h" |
9 #include "base/compiler_specific.h" | 11 #include "base/compiler_specific.h" |
10 #include "base/logging.h" | 12 #include "base/logging.h" |
11 #include "base/message_loop.h" | 13 #include "base/message_loop.h" |
12 #include "base/message_loop_proxy.h" | 14 #include "base/message_loop_proxy.h" |
13 #include "base/string_util.h" | 15 #include "base/string_util.h" |
14 #include "base/values.h" | 16 #include "base/values.h" |
15 #include "googleurl/src/gurl.h" | 17 #include "googleurl/src/gurl.h" |
16 #include "net/base/completion_callback.h" | 18 #include "net/base/completion_callback.h" |
17 #include "net/base/net_errors.h" | 19 #include "net/base/net_errors.h" |
18 #include "net/base/net_log.h" | 20 #include "net/base/net_log.h" |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
60 // The reason we play this game is that our signal for detecting network | 62 // The reason we play this game is that our signal for detecting network |
61 // changes (NetworkChangeNotifier) may fire *before* the system's networking | 63 // changes (NetworkChangeNotifier) may fire *before* the system's networking |
62 // dependencies are fully configured. This is a problem since it means if | 64 // dependencies are fully configured. This is a problem since it means if |
63 // we were to run proxy auto-config right away, it could fail due to spurious | 65 // we were to run proxy auto-config right away, it could fail due to spurious |
64 // DNS failures. (see http://crbug.com/50779 for more details.) | 66 // DNS failures. (see http://crbug.com/50779 for more details.) |
65 // | 67 // |
66 // By adding the wait window, we give things a chance to get properly set up. | 68 // By adding the wait window, we give things a chance to get properly set up. |
67 // Now by the time we run the proxy-autoconfig there is a lower chance of | 69 // Now by the time we run the proxy-autoconfig there is a lower chance of |
68 // getting transient DNS / connect failures. | 70 // getting transient DNS / connect failures. |
69 // | 71 // |
70 // Admitedly this is a hack. Ideally we would have NetworkChangeNotifier | 72 // Admittedly this is a hack. Ideally we would have NetworkChangeNotifier |
71 // deliver a reliable signal indicating that the network has changed AND is | 73 // deliver a reliable signal indicating that the network has changed AND is |
72 // ready for action... But until then, we can reduce the likelihood of users | 74 // ready for action... But until then, we can reduce the likelihood of users |
73 // getting wedged because of proxy detection failures on network switch. | 75 // getting wedged because of proxy detection failures on network switch. |
74 // | 76 // |
75 // The obvious downside to this strategy is it introduces an additional | 77 // The obvious downside to this strategy is it introduces an additional |
76 // latency when switching networks. This delay shouldn't be too disruptive | 78 // latency when switching networks. This delay shouldn't be too disruptive |
77 // assuming network switches are infrequent and user initiated. However if | 79 // assuming network switches are infrequent and user initiated. However if |
78 // NetworkChangeNotifier delivers network changes more frequently this could | 80 // NetworkChangeNotifier delivers network changes more frequently this could |
79 // cause jankiness. (NetworkChangeNotifier broadcasts a change event when ANY | 81 // cause jankiness. (NetworkChangeNotifier broadcasts a change event when ANY |
80 // interface goes up/down. So in theory if the non-primary interface were | 82 // interface goes up/down. So in theory if the non-primary interface were |
81 // hopping on and off wireless networks our constant delayed reconfiguration | 83 // hopping on and off wireless networks our constant delayed reconfiguration |
82 // could add noticeable jank.) | 84 // could add noticeable jank.) |
83 // | 85 // |
84 // The specific hard-coded wait time below is arbitrary. | 86 // The specific hard-coded wait time below is arbitrary. |
85 // Basically I ran some experiments switching between wireless networks on | 87 // Basically I ran some experiments switching between wireless networks on |
86 // a Linux Ubuntu (Lucid) laptop, and experimentally found this timeout fixes | 88 // a Linux Ubuntu (Lucid) laptop, and experimentally found this timeout fixes |
87 // things. It is entirely possible that the value is insuficient for other | 89 // things. It is entirely possible that the value is insufficient for other |
88 // setups. | 90 // setups. |
89 const int64 kNumMillisToStallAfterNetworkChanges = 2000; | 91 const int64 kNumMillisToStallAfterNetworkChanges = 2000; |
90 | 92 |
91 // Config getter that always returns direct settings. | 93 // Config getter that always returns direct settings. |
92 class ProxyConfigServiceDirect : public ProxyConfigService { | 94 class ProxyConfigServiceDirect : public ProxyConfigService { |
93 public: | 95 public: |
94 // ProxyConfigService implementation: | 96 // ProxyConfigService implementation: |
95 virtual void AddObserver(Observer* observer) OVERRIDE {} | 97 virtual void AddObserver(Observer* observer) OVERRIDE {} |
96 virtual void RemoveObserver(Observer* observer) OVERRIDE {} | 98 virtual void RemoveObserver(Observer* observer) OVERRIDE {} |
97 virtual ConfigAvailability GetLatestProxyConfig(ProxyConfig* config) | 99 virtual ConfigAvailability GetLatestProxyConfig(ProxyConfig* config) |
(...skipping 672 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
770 return req->QueryDidComplete(rv); | 772 return req->QueryDidComplete(rv); |
771 } else { | 773 } else { |
772 req->net_log()->BeginEvent(NetLog::TYPE_PROXY_SERVICE_WAITING_FOR_INIT_PAC, | 774 req->net_log()->BeginEvent(NetLog::TYPE_PROXY_SERVICE_WAITING_FOR_INIT_PAC, |
773 NULL); | 775 NULL); |
774 } | 776 } |
775 | 777 |
776 DCHECK_EQ(ERR_IO_PENDING, rv); | 778 DCHECK_EQ(ERR_IO_PENDING, rv); |
777 DCHECK(!ContainsPendingRequest(req)); | 779 DCHECK(!ContainsPendingRequest(req)); |
778 pending_requests_.push_back(req); | 780 pending_requests_.push_back(req); |
779 | 781 |
780 // Completion will be notifed through |callback|, unless the caller cancels | 782 // Completion will be notified through |callback|, unless the caller cancels |
781 // the request using |pac_request|. | 783 // the request using |pac_request|. |
782 if (pac_request) | 784 if (pac_request) |
783 *pac_request = req.get(); | 785 *pac_request = req.get(); |
784 return rv; // ERR_IO_PENDING | 786 return rv; // ERR_IO_PENDING |
785 } | 787 } |
786 | 788 |
787 int ProxyService::ResolveProxy(const GURL& raw_url, | 789 int ProxyService::ResolveProxy(const GURL& raw_url, |
788 ProxyInfo* result, | 790 ProxyInfo* result, |
789 const net::CompletionCallback& callback, | 791 const net::CompletionCallback& callback, |
790 PacRequest** pac_request, | 792 PacRequest** pac_request, |
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
953 | 955 |
954 config_.set_id(fetched_config_.id()); | 956 config_.set_id(fetched_config_.id()); |
955 | 957 |
956 // Resume any requests which we had to defer until the PAC script was | 958 // Resume any requests which we had to defer until the PAC script was |
957 // downloaded. | 959 // downloaded. |
958 SetReady(); | 960 SetReady(); |
959 } | 961 } |
960 | 962 |
961 int ProxyService::ReconsiderProxyAfterError(const GURL& url, | 963 int ProxyService::ReconsiderProxyAfterError(const GURL& url, |
962 ProxyInfo* result, | 964 ProxyInfo* result, |
963 OldCompletionCallback* callback, | 965 const CompletionCallback& callback, |
964 PacRequest** pac_request, | 966 PacRequest** pac_request, |
965 const BoundNetLog& net_log) { | 967 const BoundNetLog& net_log) { |
966 DCHECK(CalledOnValidThread()); | 968 DCHECK(CalledOnValidThread()); |
967 | 969 |
968 // Check to see if we have a new config since ResolveProxy was called. We | 970 // Check to see if we have a new config since ResolveProxy was called. We |
969 // want to re-run ResolveProxy in two cases: 1) we have a new config, or 2) a | 971 // want to re-run ResolveProxy in two cases: 1) we have a new config, or 2) a |
970 // direct connection failed and we never tried the current config. | 972 // direct connection failed and we never tried the current config. |
971 | 973 |
972 bool re_resolve = result->config_id_ != config_.id(); | 974 bool re_resolve = result->config_id_ != config_.id(); |
973 | 975 |
(...skipping 281 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1255 if (previous_state != STATE_NONE) | 1257 if (previous_state != STATE_NONE) |
1256 ApplyProxyConfigIfAvailable(); | 1258 ApplyProxyConfigIfAvailable(); |
1257 } | 1259 } |
1258 | 1260 |
1259 SyncProxyServiceHelper::SyncProxyServiceHelper(MessageLoop* io_message_loop, | 1261 SyncProxyServiceHelper::SyncProxyServiceHelper(MessageLoop* io_message_loop, |
1260 ProxyService* proxy_service) | 1262 ProxyService* proxy_service) |
1261 : io_message_loop_(io_message_loop), | 1263 : io_message_loop_(io_message_loop), |
1262 proxy_service_(proxy_service), | 1264 proxy_service_(proxy_service), |
1263 event_(false, false), | 1265 event_(false, false), |
1264 ALLOW_THIS_IN_INITIALIZER_LIST(callback_( | 1266 ALLOW_THIS_IN_INITIALIZER_LIST(callback_( |
1265 this, &SyncProxyServiceHelper::OnCompletion)) { | 1267 base::Bind(&SyncProxyServiceHelper::OnCompletion, |
| 1268 base::Unretained(this)))) { |
1266 DCHECK(io_message_loop_ != MessageLoop::current()); | 1269 DCHECK(io_message_loop_ != MessageLoop::current()); |
1267 } | 1270 } |
1268 | 1271 |
1269 int SyncProxyServiceHelper::ResolveProxy(const GURL& url, | 1272 int SyncProxyServiceHelper::ResolveProxy(const GURL& url, |
1270 ProxyInfo* proxy_info, | 1273 ProxyInfo* proxy_info, |
1271 const BoundNetLog& net_log) { | 1274 const BoundNetLog& net_log) { |
1272 DCHECK(io_message_loop_ != MessageLoop::current()); | 1275 DCHECK(io_message_loop_ != MessageLoop::current()); |
1273 | 1276 |
1274 io_message_loop_->PostTask(FROM_HERE, NewRunnableMethod( | 1277 io_message_loop_->PostTask(FROM_HERE, NewRunnableMethod( |
1275 this, &SyncProxyServiceHelper::StartAsyncResolve, url, net_log)); | 1278 this, &SyncProxyServiceHelper::StartAsyncResolve, url, net_log)); |
(...skipping 19 matching lines...) Expand all Loading... |
1295 *proxy_info = proxy_info_; | 1298 *proxy_info = proxy_info_; |
1296 } | 1299 } |
1297 return result_; | 1300 return result_; |
1298 } | 1301 } |
1299 | 1302 |
1300 SyncProxyServiceHelper::~SyncProxyServiceHelper() {} | 1303 SyncProxyServiceHelper::~SyncProxyServiceHelper() {} |
1301 | 1304 |
1302 void SyncProxyServiceHelper::StartAsyncResolve(const GURL& url, | 1305 void SyncProxyServiceHelper::StartAsyncResolve(const GURL& url, |
1303 const BoundNetLog& net_log) { | 1306 const BoundNetLog& net_log) { |
1304 result_ = proxy_service_->ResolveProxy( | 1307 result_ = proxy_service_->ResolveProxy( |
1305 url, &proxy_info_, &callback_, NULL, net_log); | 1308 url, &proxy_info_, callback_, NULL, net_log); |
1306 if (result_ != net::ERR_IO_PENDING) { | 1309 if (result_ != net::ERR_IO_PENDING) { |
1307 OnCompletion(result_); | 1310 OnCompletion(result_); |
1308 } | 1311 } |
1309 } | 1312 } |
1310 | 1313 |
1311 void SyncProxyServiceHelper::StartAsyncReconsider(const GURL& url, | 1314 void SyncProxyServiceHelper::StartAsyncReconsider(const GURL& url, |
1312 const BoundNetLog& net_log) { | 1315 const BoundNetLog& net_log) { |
1313 result_ = proxy_service_->ReconsiderProxyAfterError( | 1316 result_ = proxy_service_->ReconsiderProxyAfterError( |
1314 url, &proxy_info_, &callback_, NULL, net_log); | 1317 url, &proxy_info_, callback_, NULL, net_log); |
1315 if (result_ != net::ERR_IO_PENDING) { | 1318 if (result_ != net::ERR_IO_PENDING) { |
1316 OnCompletion(result_); | 1319 OnCompletion(result_); |
1317 } | 1320 } |
1318 } | 1321 } |
1319 | 1322 |
1320 void SyncProxyServiceHelper::OnCompletion(int rv) { | 1323 void SyncProxyServiceHelper::OnCompletion(int rv) { |
1321 result_ = rv; | 1324 result_ = rv; |
1322 event_.Signal(); | 1325 event_.Signal(); |
1323 } | 1326 } |
1324 | 1327 |
1325 } // namespace net | 1328 } // namespace net |
OLD | NEW |