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

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

Issue 3058013: Fix late binding induced mismatch of Socket and AuthController (Closed)
Patch Set: Address comments 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
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.h" 5 #include "net/http/http_proxy_client_socket.h"
6 6
7 #include "base/string_util.h" 7 #include "base/string_util.h"
8 #include "googleurl/src/gurl.h" 8 #include "googleurl/src/gurl.h"
9 #include "net/base/host_port_pair.h" 9 #include "net/base/host_port_pair.h"
10 #include "net/base/io_buffer.h" 10 #include "net/base/io_buffer.h"
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
43 &user_agent)) 43 &user_agent))
44 request_headers->SetHeader(HttpRequestHeaders::kUserAgent, user_agent); 44 request_headers->SetHeader(HttpRequestHeaders::kUserAgent, user_agent);
45 45
46 request_headers->MergeFrom(authorization_headers); 46 request_headers->MergeFrom(authorization_headers);
47 } 47 }
48 48
49 } // namespace 49 } // namespace
50 50
51 HttpProxyClientSocket::HttpProxyClientSocket( 51 HttpProxyClientSocket::HttpProxyClientSocket(
52 ClientSocketHandle* transport_socket, const GURL& request_url, 52 ClientSocketHandle* transport_socket, const GURL& request_url,
53 const HostPortPair& endpoint, const scoped_refptr<HttpAuthController>& auth, 53 const HostPortPair& endpoint, const HostPortPair& proxy_server,
54 bool tunnel) 54 const scoped_refptr<HttpNetworkSession>& session, bool tunnel)
55 : ALLOW_THIS_IN_INITIALIZER_LIST( 55 : ALLOW_THIS_IN_INITIALIZER_LIST(
56 io_callback_(this, &HttpProxyClientSocket::OnIOComplete)), 56 io_callback_(this, &HttpProxyClientSocket::OnIOComplete)),
57 next_state_(STATE_NONE), 57 next_state_(STATE_NONE),
58 user_callback_(NULL), 58 user_callback_(NULL),
59 transport_(transport_socket), 59 transport_(transport_socket),
60 endpoint_(endpoint), 60 endpoint_(endpoint),
61 auth_(auth), 61 auth_(tunnel ?
62 new HttpAuthController(HttpAuth::AUTH_PROXY,
63 GURL("http://" + proxy_server.ToString()),
64 session) : NULL),
62 tunnel_(tunnel), 65 tunnel_(tunnel),
63 net_log_(transport_socket->socket()->NetLog()) { 66 net_log_(transport_socket->socket()->NetLog()) {
64 DCHECK_EQ(tunnel, auth != NULL);
65 // Synthesize the bits of a request that we actually use. 67 // Synthesize the bits of a request that we actually use.
66 request_.url = request_url; 68 request_.url = request_url;
67 request_.method = "GET"; 69 request_.method = "GET";
68 } 70 }
69 71
70 HttpProxyClientSocket::~HttpProxyClientSocket() { 72 HttpProxyClientSocket::~HttpProxyClientSocket() {
71 Disconnect(); 73 Disconnect();
72 } 74 }
73 75
74 int HttpProxyClientSocket::Connect(CompletionCallback* callback) { 76 int HttpProxyClientSocket::Connect(CompletionCallback* callback) {
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
119 } 121 }
120 keep_alive = true; 122 keep_alive = true;
121 } 123 }
122 124
123 // We don't need to drain the response body, so we act as if we had drained 125 // We don't need to drain the response body, so we act as if we had drained
124 // the response body. 126 // the response body.
125 return DidDrainBodyForAuthRestart(keep_alive); 127 return DidDrainBodyForAuthRestart(keep_alive);
126 } 128 }
127 129
128 int HttpProxyClientSocket::DidDrainBodyForAuthRestart(bool keep_alive) { 130 int HttpProxyClientSocket::DidDrainBodyForAuthRestart(bool keep_alive) {
129 int rc = OK;
130 if (keep_alive && transport_->socket()->IsConnectedAndIdle()) { 131 if (keep_alive && transport_->socket()->IsConnectedAndIdle()) {
131 next_state_ = STATE_GENERATE_AUTH_TOKEN; 132 next_state_ = STATE_GENERATE_AUTH_TOKEN;
132 transport_->set_is_reused(true); 133 transport_->set_is_reused(true);
133 } else { 134 } else {
135 // This assumes that the underlying transport socket is a TCP socket,
136 // since only TCP sockets are restartable.
137 next_state_ = STATE_TCP_RESTART;
134 transport_->socket()->Disconnect(); 138 transport_->socket()->Disconnect();
135 rc = ERR_RETRY_CONNECTION;
136 } 139 }
137 140
138 // Reset the other member variables. 141 // Reset the other member variables.
139 drain_buf_ = NULL; 142 drain_buf_ = NULL;
140 http_stream_.reset(); 143 http_stream_.reset();
141 request_headers_.clear(); 144 request_headers_.clear();
142 response_ = HttpResponseInfo(); 145 response_ = HttpResponseInfo();
143 return rc; 146 return OK;
144 } 147 }
145 148
146 void HttpProxyClientSocket::LogBlockedTunnelResponse(int response_code) const { 149 void HttpProxyClientSocket::LogBlockedTunnelResponse(int response_code) const {
147 LOG(WARNING) << "Blocked proxy response with status " << response_code 150 LOG(WARNING) << "Blocked proxy response with status " << response_code
148 << " to CONNECT request for " 151 << " to CONNECT request for "
149 << GetHostAndPort(request_.url) << "."; 152 << GetHostAndPort(request_.url) << ".";
150 } 153 }
151 154
152 void HttpProxyClientSocket::Disconnect() { 155 void HttpProxyClientSocket::Disconnect() {
153 transport_->socket()->Disconnect(); 156 transport_->socket()->Disconnect();
154 157
155 // Reset other states to make sure they aren't mistakenly used later. 158 // Reset other states to make sure they aren't mistakenly used later.
156 // These are the states initialized by Connect(). 159 // These are the states initialized by Connect().
157 next_state_ = STATE_NONE; 160 next_state_ = STATE_NONE;
158 user_callback_ = NULL; 161 user_callback_ = NULL;
159 } 162 }
160 163
161 bool HttpProxyClientSocket::IsConnected() const { 164 bool HttpProxyClientSocket::IsConnected() const {
162 return transport_->socket()->IsConnected(); 165 return next_state_ == STATE_DONE && transport_->socket()->IsConnected();
163 } 166 }
164 167
165 bool HttpProxyClientSocket::IsConnectedAndIdle() const { 168 bool HttpProxyClientSocket::IsConnectedAndIdle() const {
166 return transport_->socket()->IsConnectedAndIdle(); 169 return next_state_ == STATE_DONE &&
167 } 170 transport_->socket()->IsConnectedAndIdle();
168
169 bool HttpProxyClientSocket::NeedsRestartWithAuth() const {
170 return next_state_ != STATE_DONE;
171 } 171 }
172 172
173 int HttpProxyClientSocket::Read(IOBuffer* buf, int buf_len, 173 int HttpProxyClientSocket::Read(IOBuffer* buf, int buf_len,
174 CompletionCallback* callback) { 174 CompletionCallback* callback) {
175 DCHECK(!user_callback_); 175 DCHECK(!user_callback_);
176 if (next_state_ != STATE_DONE) { 176 if (next_state_ != STATE_DONE) {
177 // We're trying to read the body of the response but we're still trying 177 // We're trying to read the body of the response but we're still trying
178 // to establish an SSL tunnel through the proxy. We can't read these 178 // to establish an SSL tunnel through the proxy. We can't read these
179 // bytes when establishing a tunnel because they might be controlled by 179 // bytes when establishing a tunnel because they might be controlled by
180 // an active network attacker. We don't worry about this for HTTP 180 // an active network attacker. We don't worry about this for HTTP
181 // because an active network attacker can already control HTTP sessions. 181 // because an active network attacker can already control HTTP sessions.
182 // We reach this case when the user cancels a 407 proxy auth prompt. 182 // We reach this case when the user cancels a 407 proxy auth prompt.
183 // See http://crbug.com/8473. 183 // See http://crbug.com/8473.
184 DCHECK_EQ(407, response_.headers->response_code()); 184 DCHECK_EQ(407, response_.headers->response_code());
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
266 net_log_.EndEvent(NetLog::TYPE_HTTP_TRANSACTION_TUNNEL_READ_HEADERS, 266 net_log_.EndEvent(NetLog::TYPE_HTTP_TRANSACTION_TUNNEL_READ_HEADERS,
267 NULL); 267 NULL);
268 break; 268 break;
269 case STATE_DRAIN_BODY: 269 case STATE_DRAIN_BODY:
270 DCHECK_EQ(OK, rv); 270 DCHECK_EQ(OK, rv);
271 rv = DoDrainBody(); 271 rv = DoDrainBody();
272 break; 272 break;
273 case STATE_DRAIN_BODY_COMPLETE: 273 case STATE_DRAIN_BODY_COMPLETE:
274 rv = DoDrainBodyComplete(rv); 274 rv = DoDrainBodyComplete(rv);
275 break; 275 break;
276 case STATE_TCP_RESTART:
277 DCHECK_EQ(OK, rv);
278 rv = DoTCPRestart();
279 break;
280 case STATE_TCP_RESTART_COMPLETE:
281 rv = DoTCPRestartComplete(rv);
282 break;
276 case STATE_DONE: 283 case STATE_DONE:
277 break; 284 break;
278 default: 285 default:
279 NOTREACHED() << "bad state"; 286 NOTREACHED() << "bad state";
280 rv = ERR_UNEXPECTED; 287 rv = ERR_UNEXPECTED;
281 break; 288 break;
282 } 289 }
283 } while (rv != ERR_IO_PENDING && next_state_ != STATE_NONE 290 } while (rv != ERR_IO_PENDING && next_state_ != STATE_NONE &&
284 && next_state_ != STATE_DONE); 291 next_state_ != STATE_DONE);
285 return rv; 292 return rv;
286 } 293 }
287 294
288 int HttpProxyClientSocket::DoGenerateAuthToken() { 295 int HttpProxyClientSocket::DoGenerateAuthToken() {
289 next_state_ = STATE_GENERATE_AUTH_TOKEN_COMPLETE; 296 next_state_ = STATE_GENERATE_AUTH_TOKEN_COMPLETE;
290 return auth_->MaybeGenerateAuthToken(&request_, &io_callback_, net_log_); 297 return auth_->MaybeGenerateAuthToken(&request_, &io_callback_, net_log_);
291 } 298 }
292 299
293 int HttpProxyClientSocket::DoGenerateAuthTokenComplete(int result) { 300 int HttpProxyClientSocket::DoGenerateAuthTokenComplete(int result) {
294 DCHECK_NE(ERR_IO_PENDING, result); 301 DCHECK_NE(ERR_IO_PENDING, result);
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
399 return result; 406 return result;
400 407
401 if (http_stream_->IsResponseBodyComplete()) 408 if (http_stream_->IsResponseBodyComplete())
402 return DidDrainBodyForAuthRestart(true); 409 return DidDrainBodyForAuthRestart(true);
403 410
404 // Keep draining. 411 // Keep draining.
405 next_state_ = STATE_DRAIN_BODY; 412 next_state_ = STATE_DRAIN_BODY;
406 return OK; 413 return OK;
407 } 414 }
408 415
416 int HttpProxyClientSocket::DoTCPRestart() {
417 next_state_ = STATE_TCP_RESTART_COMPLETE;
418 return transport_->socket()->Connect(&io_callback_);
419 }
420
421 int HttpProxyClientSocket::DoTCPRestartComplete(int result) {
422 if (result != OK)
423 return result;
424
425 next_state_ = STATE_GENERATE_AUTH_TOKEN;
426 return result;
427 }
428
409 int HttpProxyClientSocket::HandleAuthChallenge() { 429 int HttpProxyClientSocket::HandleAuthChallenge() {
410 DCHECK(response_.headers); 430 DCHECK(response_.headers);
411 431
412 int rv = auth_->HandleAuthChallenge(response_.headers, false, true, net_log_); 432 int rv = auth_->HandleAuthChallenge(response_.headers, false, true, net_log_);
413 response_.auth_challenge = auth_->auth_info(); 433 response_.auth_challenge = auth_->auth_info();
414 if (rv == OK) 434 if (rv == OK)
415 return ERR_PROXY_AUTH_REQUESTED; 435 return ERR_PROXY_AUTH_REQUESTED;
416 436
417 return rv; 437 return rv;
418 } 438 }
419 439
420 } // namespace net 440 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698