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