Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(95)

Side by Side Diff: net/http/http_proxy_client_socket_pool.cc

Issue 3112034: Attempting to re-land CL 3110006 which turned out to have ... (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: '' Created 10 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
OLDNEW
« no previous file with comments | « net/http/http_proxy_client_socket_pool.h ('k') | net/http/http_proxy_client_socket_pool_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698