| OLD | NEW |
| 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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/http/http_proxy_client_socket_pool.h" | 5 #include "net/http/http_proxy_client_socket_pool.h" |
| 6 | 6 |
| 7 #include <algorithm> |
| 8 |
| 7 #include "base/time.h" | 9 #include "base/time.h" |
| 8 #include "googleurl/src/gurl.h" | 10 #include "googleurl/src/gurl.h" |
| 9 #include "net/base/net_errors.h" | 11 #include "net/base/net_errors.h" |
| 10 #include "net/http/http_network_session.h" | 12 #include "net/http/http_network_session.h" |
| 11 #include "net/http/http_proxy_client_socket.h" | 13 #include "net/http/http_proxy_client_socket.h" |
| 12 #include "net/socket/client_socket_factory.h" | 14 #include "net/socket/client_socket_factory.h" |
| 13 #include "net/socket/client_socket_handle.h" | 15 #include "net/socket/client_socket_handle.h" |
| 14 #include "net/socket/client_socket_pool_base.h" | 16 #include "net/socket/client_socket_pool_base.h" |
| 15 #include "net/socket/tcp_client_socket_pool.h" | 17 #include "net/socket/tcp_client_socket_pool.h" |
| 16 | 18 |
| 17 namespace net { | 19 namespace net { |
| 18 | 20 |
| 19 HttpProxySocketParams::HttpProxySocketParams( | 21 HttpProxySocketParams::HttpProxySocketParams( |
| 20 const scoped_refptr<TCPSocketParams>& proxy_server, | 22 const scoped_refptr<TCPSocketParams>& tcp_params, |
| 23 const scoped_refptr<SSLSocketParams>& ssl_params, |
| 21 const GURL& request_url, | 24 const GURL& request_url, |
| 22 const std::string& user_agent, | 25 const std::string& user_agent, |
| 23 HostPortPair endpoint, | 26 HostPortPair endpoint, |
| 24 scoped_refptr<HttpNetworkSession> session, | 27 scoped_refptr<HttpNetworkSession> session, |
| 25 bool tunnel) | 28 bool tunnel) |
| 26 : tcp_params_(proxy_server), | 29 : tcp_params_(tcp_params), |
| 30 ssl_params_(ssl_params), |
| 27 request_url_(request_url), | 31 request_url_(request_url), |
| 28 user_agent_(user_agent), | 32 user_agent_(user_agent), |
| 29 endpoint_(endpoint), | 33 endpoint_(endpoint), |
| 30 session_(tunnel ? session : NULL), | 34 session_(tunnel ? session : NULL), |
| 31 tunnel_(tunnel) { | 35 tunnel_(tunnel) { |
| 36 DCHECK((tcp_params == NULL && ssl_params != NULL) || |
| 37 (tcp_params != NULL && ssl_params == NULL)); |
| 38 } |
| 39 |
| 40 const HostResolver::RequestInfo& HttpProxySocketParams::destination() const { |
| 41 if (tcp_params_ == NULL) |
| 42 return ssl_params_->tcp_params()->destination(); |
| 43 else |
| 44 return tcp_params_->destination(); |
| 32 } | 45 } |
| 33 | 46 |
| 34 HttpProxySocketParams::~HttpProxySocketParams() {} | 47 HttpProxySocketParams::~HttpProxySocketParams() {} |
| 35 | 48 |
| 36 // HttpProxyConnectJobs will time out after this many seconds. Note this is on | 49 // HttpProxyConnectJobs will time out after this many seconds. Note this is on |
| 37 // top of the timeout for the transport socket. | 50 // top of the timeout for the transport socket. |
| 38 static const int kHttpProxyConnectJobTimeoutInSeconds = 30; | 51 static const int kHttpProxyConnectJobTimeoutInSeconds = 30; |
| 39 | 52 |
| 40 HttpProxyConnectJob::HttpProxyConnectJob( | 53 HttpProxyConnectJob::HttpProxyConnectJob( |
| 41 const std::string& group_name, | 54 const std::string& group_name, |
| 42 const scoped_refptr<HttpProxySocketParams>& params, | 55 const scoped_refptr<HttpProxySocketParams>& params, |
| 43 const base::TimeDelta& timeout_duration, | 56 const base::TimeDelta& timeout_duration, |
| 44 const scoped_refptr<TCPClientSocketPool>& tcp_pool, | 57 const scoped_refptr<TCPClientSocketPool>& tcp_pool, |
| 58 const scoped_refptr<SSLClientSocketPool>& ssl_pool, |
| 45 const scoped_refptr<HostResolver>& host_resolver, | 59 const scoped_refptr<HostResolver>& host_resolver, |
| 46 Delegate* delegate, | 60 Delegate* delegate, |
| 47 NetLog* net_log) | 61 NetLog* net_log) |
| 48 : ConnectJob(group_name, timeout_duration, delegate, | 62 : ConnectJob(group_name, timeout_duration, delegate, |
| 49 BoundNetLog::Make(net_log, NetLog::SOURCE_CONNECT_JOB)), | 63 BoundNetLog::Make(net_log, NetLog::SOURCE_CONNECT_JOB)), |
| 50 params_(params), | 64 params_(params), |
| 51 tcp_pool_(tcp_pool), | 65 tcp_pool_(tcp_pool), |
| 66 ssl_pool_(ssl_pool), |
| 52 resolver_(host_resolver), | 67 resolver_(host_resolver), |
| 53 ALLOW_THIS_IN_INITIALIZER_LIST( | 68 ALLOW_THIS_IN_INITIALIZER_LIST( |
| 54 callback_(this, &HttpProxyConnectJob::OnIOComplete)) { | 69 callback_(this, &HttpProxyConnectJob::OnIOComplete)) { |
| 55 } | 70 } |
| 56 | 71 |
| 57 HttpProxyConnectJob::~HttpProxyConnectJob() {} | 72 HttpProxyConnectJob::~HttpProxyConnectJob() {} |
| 58 | 73 |
| 59 LoadState HttpProxyConnectJob::GetLoadState() const { | 74 LoadState HttpProxyConnectJob::GetLoadState() const { |
| 60 switch (next_state_) { | 75 switch (next_state_) { |
| 61 case kStateTCPConnect: | 76 case kStateTCPConnect: |
| 62 case kStateTCPConnectComplete: | 77 case kStateTCPConnectComplete: |
| 63 return tcp_socket_handle_->GetLoadState(); | 78 case kStateSSLConnect: |
| 79 case kStateSSLConnectComplete: |
| 80 return transport_socket_handle_->GetLoadState(); |
| 64 case kStateHttpProxyConnect: | 81 case kStateHttpProxyConnect: |
| 65 case kStateHttpProxyConnectComplete: | 82 case kStateHttpProxyConnectComplete: |
| 66 return LOAD_STATE_ESTABLISHING_PROXY_TUNNEL; | 83 return LOAD_STATE_ESTABLISHING_PROXY_TUNNEL; |
| 67 default: | 84 default: |
| 68 NOTREACHED(); | 85 NOTREACHED(); |
| 69 return LOAD_STATE_IDLE; | 86 return LOAD_STATE_IDLE; |
| 70 } | 87 } |
| 71 } | 88 } |
| 72 | 89 |
| 73 int HttpProxyConnectJob::ConnectInternal() { | 90 int HttpProxyConnectJob::ConnectInternal() { |
| 74 next_state_ = kStateTCPConnect; | 91 if (params_->tcp_params()) |
| 92 next_state_ = kStateTCPConnect; |
| 93 else |
| 94 next_state_ = kStateSSLConnect; |
| 75 return DoLoop(OK); | 95 return DoLoop(OK); |
| 76 } | 96 } |
| 77 | 97 |
| 78 void HttpProxyConnectJob::OnIOComplete(int result) { | 98 void HttpProxyConnectJob::OnIOComplete(int result) { |
| 79 int rv = DoLoop(result); | 99 int rv = DoLoop(result); |
| 80 if (rv != ERR_IO_PENDING) | 100 if (rv != ERR_IO_PENDING) |
| 81 NotifyDelegateOfCompletion(rv); // Deletes |this| | 101 NotifyDelegateOfCompletion(rv); // Deletes |this| |
| 82 } | 102 } |
| 83 | 103 |
| 84 int HttpProxyConnectJob::DoLoop(int result) { | 104 int HttpProxyConnectJob::DoLoop(int result) { |
| 85 DCHECK_NE(next_state_, kStateNone); | 105 DCHECK_NE(next_state_, kStateNone); |
| 86 | 106 |
| 87 int rv = result; | 107 int rv = result; |
| 88 do { | 108 do { |
| 89 State state = next_state_; | 109 State state = next_state_; |
| 90 next_state_ = kStateNone; | 110 next_state_ = kStateNone; |
| 91 switch (state) { | 111 switch (state) { |
| 92 case kStateTCPConnect: | 112 case kStateTCPConnect: |
| 93 DCHECK_EQ(OK, rv); | 113 DCHECK_EQ(OK, rv); |
| 94 rv = DoTCPConnect(); | 114 rv = DoTCPConnect(); |
| 95 break; | 115 break; |
| 96 case kStateTCPConnectComplete: | 116 case kStateTCPConnectComplete: |
| 97 rv = DoTCPConnectComplete(rv); | 117 rv = DoTCPConnectComplete(rv); |
| 98 break; | 118 break; |
| 119 case kStateSSLConnect: |
| 120 DCHECK_EQ(OK, rv); |
| 121 rv = DoSSLConnect(); |
| 122 break; |
| 123 case kStateSSLConnectComplete: |
| 124 rv = DoSSLConnectComplete(rv); |
| 125 break; |
| 99 case kStateHttpProxyConnect: | 126 case kStateHttpProxyConnect: |
| 100 DCHECK_EQ(OK, rv); | 127 DCHECK_EQ(OK, rv); |
| 101 rv = DoHttpProxyConnect(); | 128 rv = DoHttpProxyConnect(); |
| 102 break; | 129 break; |
| 103 case kStateHttpProxyConnectComplete: | 130 case kStateHttpProxyConnectComplete: |
| 104 rv = DoHttpProxyConnectComplete(rv); | 131 rv = DoHttpProxyConnectComplete(rv); |
| 105 break; | 132 break; |
| 106 default: | 133 default: |
| 107 NOTREACHED() << "bad state"; | 134 NOTREACHED() << "bad state"; |
| 108 rv = ERR_FAILED; | 135 rv = ERR_FAILED; |
| 109 break; | 136 break; |
| 110 } | 137 } |
| 111 } while (rv != ERR_IO_PENDING && next_state_ != kStateNone); | 138 } while (rv != ERR_IO_PENDING && next_state_ != kStateNone); |
| 112 | 139 |
| 113 return rv; | 140 return rv; |
| 114 } | 141 } |
| 115 | 142 |
| 116 int HttpProxyConnectJob::DoTCPConnect() { | 143 int HttpProxyConnectJob::DoTCPConnect() { |
| 117 next_state_ = kStateTCPConnectComplete; | 144 next_state_ = kStateTCPConnectComplete; |
| 118 tcp_socket_handle_.reset(new ClientSocketHandle()); | 145 transport_socket_handle_.reset(new ClientSocketHandle()); |
| 119 return tcp_socket_handle_->Init( | 146 return transport_socket_handle_->Init( |
| 120 group_name(), params_->tcp_params(), | 147 group_name(), params_->tcp_params(), |
| 121 params_->tcp_params()->destination().priority(), &callback_, tcp_pool_, | 148 params_->tcp_params()->destination().priority(), &callback_, tcp_pool_, |
| 122 net_log()); | 149 net_log()); |
| 123 } | 150 } |
| 124 | 151 |
| 125 int HttpProxyConnectJob::DoTCPConnectComplete(int result) { | 152 int HttpProxyConnectJob::DoTCPConnectComplete(int result) { |
| 126 if (result != OK) | 153 if (result != OK) |
| 127 return result; | 154 return result; |
| 128 | 155 |
| 129 // Reset the timer to just the length of time allowed for HttpProxy handshake | 156 // Reset the timer to just the length of time allowed for HttpProxy handshake |
| 130 // so that a fast TCP connection plus a slow HttpProxy failure doesn't take | 157 // so that a fast TCP connection plus a slow HttpProxy failure doesn't take |
| 131 // longer to timeout than it should. | 158 // longer to timeout than it should. |
| 132 ResetTimer(base::TimeDelta::FromSeconds( | 159 ResetTimer(base::TimeDelta::FromSeconds( |
| 133 kHttpProxyConnectJobTimeoutInSeconds)); | 160 kHttpProxyConnectJobTimeoutInSeconds)); |
| 134 next_state_ = kStateHttpProxyConnect; | 161 next_state_ = kStateHttpProxyConnect; |
| 135 return result; | 162 return result; |
| 136 } | 163 } |
| 137 | 164 |
| 165 int HttpProxyConnectJob::DoSSLConnect() { |
| 166 next_state_ = kStateSSLConnectComplete; |
| 167 transport_socket_handle_.reset(new ClientSocketHandle()); |
| 168 return transport_socket_handle_->Init( |
| 169 group_name(), params_->ssl_params(), |
| 170 params_->ssl_params()->tcp_params()->destination().priority(), |
| 171 &callback_, ssl_pool_, net_log()); |
| 172 } |
| 173 |
| 174 int HttpProxyConnectJob::DoSSLConnectComplete(int result) { |
| 175 if (result < 0) { |
| 176 if (transport_socket_handle_->socket()) |
| 177 transport_socket_handle_->socket()->Disconnect(); |
| 178 return result; |
| 179 } |
| 180 |
| 181 // Reset the timer to just the length of time allowed for HttpProxy handshake |
| 182 // so that a fast SSL connection plus a slow HttpProxy failure doesn't take |
| 183 // longer to timeout than it should. |
| 184 ResetTimer(base::TimeDelta::FromSeconds( |
| 185 kHttpProxyConnectJobTimeoutInSeconds)); |
| 186 next_state_ = kStateHttpProxyConnect; |
| 187 return result; |
| 188 } |
| 189 |
| 138 int HttpProxyConnectJob::DoHttpProxyConnect() { | 190 int HttpProxyConnectJob::DoHttpProxyConnect() { |
| 139 next_state_ = kStateHttpProxyConnectComplete; | 191 next_state_ = kStateHttpProxyConnectComplete; |
| 140 const HostResolver::RequestInfo& tcp_destination = | 192 const HostResolver::RequestInfo& tcp_destination = params_->destination(); |
| 141 params_->tcp_params()->destination(); | |
| 142 HostPortPair proxy_server(tcp_destination.hostname(), | 193 HostPortPair proxy_server(tcp_destination.hostname(), |
| 143 tcp_destination.port()); | 194 tcp_destination.port()); |
| 144 | 195 |
| 145 // Add a HttpProxy connection on top of the tcp socket. | 196 // Add a HttpProxy connection on top of the tcp socket. |
| 146 socket_.reset(new HttpProxyClientSocket(tcp_socket_handle_.release(), | 197 transport_socket_.reset( |
| 147 params_->request_url(), | 198 new HttpProxyClientSocket(transport_socket_handle_.release(), |
| 148 params_->user_agent(), | 199 params_->request_url(), |
| 149 params_->endpoint(), | 200 params_->user_agent(), |
| 150 proxy_server, | 201 params_->endpoint(), |
| 151 params_->session(), | 202 proxy_server, params_->session(), |
| 152 params_->tunnel())); | 203 params_->tunnel())); |
| 153 int result = socket_->Connect(&callback_); | 204 int result = transport_socket_->Connect(&callback_); |
| 154 | 205 |
| 155 // Clear the circular reference to HttpNetworkSession (|params_| reference | 206 // Clear the circular reference to HttpNetworkSession (|params_| reference |
| 156 // HttpNetworkSession, which reference HttpProxyClientSocketPool, which | 207 // HttpNetworkSession, which reference HttpProxyClientSocketPool, which |
| 157 // references |this|) here because it is safe to do so now but not at other | 208 // references |this|) here because it is safe to do so now but not at other |
| 158 // points. This may cancel this ConnectJob. | 209 // points. This may cancel this ConnectJob. |
| 159 params_ = NULL; | 210 params_ = NULL; |
| 160 return result; | 211 return result; |
| 161 } | 212 } |
| 162 | 213 |
| 163 int HttpProxyConnectJob::DoHttpProxyConnectComplete(int result) { | 214 int HttpProxyConnectJob::DoHttpProxyConnectComplete(int result) { |
| 164 if (result == OK || result == ERR_PROXY_AUTH_REQUESTED) | 215 if (result == OK || result == ERR_PROXY_AUTH_REQUESTED) |
| 165 set_socket(socket_.release()); | 216 set_socket(transport_socket_.release()); |
| 166 | 217 |
| 167 return result; | 218 return result; |
| 168 } | 219 } |
| 169 | 220 |
| 221 HttpProxyClientSocketPool:: |
| 222 HttpProxyConnectJobFactory::HttpProxyConnectJobFactory( |
| 223 const scoped_refptr<TCPClientSocketPool>& tcp_pool, |
| 224 const scoped_refptr<SSLClientSocketPool>& ssl_pool, |
| 225 HostResolver* host_resolver, |
| 226 NetLog* net_log) |
| 227 : tcp_pool_(tcp_pool), |
| 228 ssl_pool_(ssl_pool), |
| 229 host_resolver_(host_resolver), |
| 230 net_log_(net_log) { |
| 231 base::TimeDelta max_pool_timeout = base::TimeDelta(); |
| 232 if (tcp_pool_) |
| 233 max_pool_timeout = tcp_pool_->ConnectionTimeout(); |
| 234 if (ssl_pool_) |
| 235 max_pool_timeout = std::max(max_pool_timeout, |
| 236 ssl_pool_->ConnectionTimeout()); |
| 237 timeout_ = max_pool_timeout + |
| 238 base::TimeDelta::FromSeconds(kHttpProxyConnectJobTimeoutInSeconds); |
| 239 } |
| 240 |
| 241 |
| 170 ConnectJob* | 242 ConnectJob* |
| 171 HttpProxyClientSocketPool::HttpProxyConnectJobFactory::NewConnectJob( | 243 HttpProxyClientSocketPool::HttpProxyConnectJobFactory::NewConnectJob( |
| 172 const std::string& group_name, | 244 const std::string& group_name, |
| 173 const PoolBase::Request& request, | 245 const PoolBase::Request& request, |
| 174 ConnectJob::Delegate* delegate) const { | 246 ConnectJob::Delegate* delegate) const { |
| 175 return new HttpProxyConnectJob(group_name, request.params(), | 247 return new HttpProxyConnectJob(group_name, request.params(), |
| 176 ConnectionTimeout(), tcp_pool_, host_resolver_, | 248 ConnectionTimeout(), tcp_pool_, ssl_pool_, |
| 177 delegate, net_log_); | 249 host_resolver_, delegate, net_log_); |
| 178 } | |
| 179 | |
| 180 base::TimeDelta | |
| 181 HttpProxyClientSocketPool::HttpProxyConnectJobFactory::ConnectionTimeout() | |
| 182 const { | |
| 183 return tcp_pool_->ConnectionTimeout() + | |
| 184 base::TimeDelta::FromSeconds(kHttpProxyConnectJobTimeoutInSeconds); | |
| 185 } | 250 } |
| 186 | 251 |
| 187 HttpProxyClientSocketPool::HttpProxyClientSocketPool( | 252 HttpProxyClientSocketPool::HttpProxyClientSocketPool( |
| 188 int max_sockets, | 253 int max_sockets, |
| 189 int max_sockets_per_group, | 254 int max_sockets_per_group, |
| 190 const scoped_refptr<ClientSocketPoolHistograms>& histograms, | 255 const scoped_refptr<ClientSocketPoolHistograms>& histograms, |
| 191 const scoped_refptr<HostResolver>& host_resolver, | 256 const scoped_refptr<HostResolver>& host_resolver, |
| 192 const scoped_refptr<TCPClientSocketPool>& tcp_pool, | 257 const scoped_refptr<TCPClientSocketPool>& tcp_pool, |
| 258 const scoped_refptr<SSLClientSocketPool>& ssl_pool, |
| 193 NetLog* net_log) | 259 NetLog* net_log) |
| 194 : base_(max_sockets, max_sockets_per_group, histograms, | 260 : base_(max_sockets, max_sockets_per_group, histograms, |
| 195 base::TimeDelta::FromSeconds( | 261 base::TimeDelta::FromSeconds( |
| 196 ClientSocketPool::unused_idle_socket_timeout()), | 262 ClientSocketPool::unused_idle_socket_timeout()), |
| 197 base::TimeDelta::FromSeconds(kUsedIdleSocketTimeout), | 263 base::TimeDelta::FromSeconds(kUsedIdleSocketTimeout), |
| 198 new HttpProxyConnectJobFactory(tcp_pool, host_resolver, net_log)) {} | 264 new HttpProxyConnectJobFactory(tcp_pool, ssl_pool, host_resolver, |
| 265 net_log)) {} |
| 199 | 266 |
| 200 HttpProxyClientSocketPool::~HttpProxyClientSocketPool() {} | 267 HttpProxyClientSocketPool::~HttpProxyClientSocketPool() {} |
| 201 | 268 |
| 202 int HttpProxyClientSocketPool::RequestSocket(const std::string& group_name, | 269 int HttpProxyClientSocketPool::RequestSocket(const std::string& group_name, |
| 203 const void* socket_params, | 270 const void* socket_params, |
| 204 RequestPriority priority, | 271 RequestPriority priority, |
| 205 ClientSocketHandle* handle, | 272 ClientSocketHandle* handle, |
| 206 CompletionCallback* callback, | 273 CompletionCallback* callback, |
| 207 const BoundNetLog& net_log) { | 274 const BoundNetLog& net_log) { |
| 208 const scoped_refptr<HttpProxySocketParams>* casted_socket_params = | 275 const scoped_refptr<HttpProxySocketParams>* casted_socket_params = |
| (...skipping 26 matching lines...) Expand all Loading... |
| 235 const std::string& group_name) const { | 302 const std::string& group_name) const { |
| 236 return base_.IdleSocketCountInGroup(group_name); | 303 return base_.IdleSocketCountInGroup(group_name); |
| 237 } | 304 } |
| 238 | 305 |
| 239 LoadState HttpProxyClientSocketPool::GetLoadState( | 306 LoadState HttpProxyClientSocketPool::GetLoadState( |
| 240 const std::string& group_name, const ClientSocketHandle* handle) const { | 307 const std::string& group_name, const ClientSocketHandle* handle) const { |
| 241 return base_.GetLoadState(group_name, handle); | 308 return base_.GetLoadState(group_name, handle); |
| 242 } | 309 } |
| 243 | 310 |
| 244 } // namespace net | 311 } // namespace net |
| OLD | NEW |