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

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

Issue 8502024: Allow chrome to handle 407 auth challenges to CONNECT requests (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: fix typo in unittest Created 9 years, 1 month 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
« no previous file with comments | « net/http/http_proxy_client_socket.h ('k') | net/http/http_proxy_client_socket_pool_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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/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 "base/stringprintf.h" 8 #include "base/stringprintf.h"
9 #include "googleurl/src/gurl.h" 9 #include "googleurl/src/gurl.h"
10 #include "net/base/auth.h" 10 #include "net/base/auth.h"
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
61 61
62 HttpProxyClientSocket::~HttpProxyClientSocket() { 62 HttpProxyClientSocket::~HttpProxyClientSocket() {
63 Disconnect(); 63 Disconnect();
64 } 64 }
65 65
66 int HttpProxyClientSocket::RestartWithAuth(OldCompletionCallback* callback) { 66 int HttpProxyClientSocket::RestartWithAuth(OldCompletionCallback* callback) {
67 DCHECK_EQ(STATE_NONE, next_state_); 67 DCHECK_EQ(STATE_NONE, next_state_);
68 DCHECK(!user_callback_); 68 DCHECK(!user_callback_);
69 69
70 int rv = PrepareForAuthRestart(); 70 int rv = PrepareForAuthRestart();
71 if (rv != OK) 71 if (rv != OK || next_state_ == STATE_NONE)
72 return rv; 72 return rv;
73 73
74 rv = DoLoop(OK); 74 rv = DoLoop(OK);
75 if (rv == ERR_IO_PENDING) 75 if (rv == ERR_IO_PENDING)
76 user_callback_ = callback; 76 user_callback_ = callback;
77 return rv; 77 return rv;
78 } 78 }
79 79
80 const
81 scoped_refptr<HttpAuthController>& HttpProxyClientSocket::auth_controller() {
82 return auth_;
83 }
84
80 const HttpResponseInfo* HttpProxyClientSocket::GetConnectResponseInfo() const { 85 const HttpResponseInfo* HttpProxyClientSocket::GetConnectResponseInfo() const {
81 return response_.headers ? &response_ : NULL; 86 return response_.headers ? &response_ : NULL;
82 } 87 }
83 88
84 HttpStream* HttpProxyClientSocket::CreateConnectResponseStream() { 89 HttpStream* HttpProxyClientSocket::CreateConnectResponseStream() {
85 return new HttpBasicStream(transport_.release(), 90 return new HttpBasicStream(transport_.release(),
86 http_stream_parser_.release(), false); 91 http_stream_parser_.release(), false);
87 } 92 }
88 93
89 94
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after
244 // We don't need to drain the response body, so we act as if we had drained 249 // We don't need to drain the response body, so we act as if we had drained
245 // the response body. 250 // the response body.
246 return DidDrainBodyForAuthRestart(keep_alive); 251 return DidDrainBodyForAuthRestart(keep_alive);
247 } 252 }
248 253
249 int HttpProxyClientSocket::DidDrainBodyForAuthRestart(bool keep_alive) { 254 int HttpProxyClientSocket::DidDrainBodyForAuthRestart(bool keep_alive) {
250 if (keep_alive && transport_->socket()->IsConnectedAndIdle()) { 255 if (keep_alive && transport_->socket()->IsConnectedAndIdle()) {
251 next_state_ = STATE_GENERATE_AUTH_TOKEN; 256 next_state_ = STATE_GENERATE_AUTH_TOKEN;
252 transport_->set_is_reused(true); 257 transport_->set_is_reused(true);
253 } else { 258 } else {
254 // This assumes that the underlying transport socket is a TCP socket, 259 next_state_ = STATE_NONE;
255 // since only TCP sockets are restartable.
256 next_state_ = STATE_TCP_RESTART;
257 transport_->socket()->Disconnect();
258 } 260 }
259 261
260 // Reset the other member variables. 262 // Reset the other member variables.
261 drain_buf_ = NULL; 263 drain_buf_ = NULL;
262 parser_buf_ = NULL; 264 parser_buf_ = NULL;
263 http_stream_parser_.reset(); 265 http_stream_parser_.reset();
264 request_line_.clear(); 266 request_line_.clear();
265 request_headers_.Clear(); 267 request_headers_.Clear();
266 response_ = HttpResponseInfo(); 268 response_ = HttpResponseInfo();
267 return OK; 269 return OK;
268 } 270 }
269 271
270 int HttpProxyClientSocket::HandleAuthChallenge() {
271 DCHECK(response_.headers);
272
273 int rv = auth_->HandleAuthChallenge(response_.headers, false, true, net_log_);
274 response_.auth_challenge = auth_->auth_info();
275 if (rv == OK)
276 return ERR_PROXY_AUTH_REQUESTED;
277
278 return rv;
279 }
280
281 void HttpProxyClientSocket::LogBlockedTunnelResponse(int response_code) const { 272 void HttpProxyClientSocket::LogBlockedTunnelResponse(int response_code) const {
282 LOG(WARNING) << "Blocked proxy response with status " << response_code 273 LOG(WARNING) << "Blocked proxy response with status " << response_code
283 << " to CONNECT request for " 274 << " to CONNECT request for "
284 << GetHostAndPort(request_.url) << "."; 275 << GetHostAndPort(request_.url) << ".";
285 } 276 }
286 277
287 void HttpProxyClientSocket::DoCallback(int result) { 278 void HttpProxyClientSocket::DoCallback(int result) {
288 DCHECK_NE(ERR_IO_PENDING, result); 279 DCHECK_NE(ERR_IO_PENDING, result);
289 DCHECK(user_callback_); 280 DCHECK(user_callback_);
290 281
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
340 net_log_.EndEventWithNetErrorCode( 331 net_log_.EndEventWithNetErrorCode(
341 NetLog::TYPE_HTTP_TRANSACTION_TUNNEL_READ_HEADERS, rv); 332 NetLog::TYPE_HTTP_TRANSACTION_TUNNEL_READ_HEADERS, rv);
342 break; 333 break;
343 case STATE_DRAIN_BODY: 334 case STATE_DRAIN_BODY:
344 DCHECK_EQ(OK, rv); 335 DCHECK_EQ(OK, rv);
345 rv = DoDrainBody(); 336 rv = DoDrainBody();
346 break; 337 break;
347 case STATE_DRAIN_BODY_COMPLETE: 338 case STATE_DRAIN_BODY_COMPLETE:
348 rv = DoDrainBodyComplete(rv); 339 rv = DoDrainBodyComplete(rv);
349 break; 340 break;
350 case STATE_TCP_RESTART:
351 DCHECK_EQ(OK, rv);
352 rv = DoTCPRestart();
353 break;
354 case STATE_TCP_RESTART_COMPLETE:
355 rv = DoTCPRestartComplete(rv);
356 break;
357 case STATE_DONE: 341 case STATE_DONE:
358 break; 342 break;
359 default: 343 default:
360 NOTREACHED() << "bad state"; 344 NOTREACHED() << "bad state";
361 rv = ERR_UNEXPECTED; 345 rv = ERR_UNEXPECTED;
362 break; 346 break;
363 } 347 }
364 } while (rv != ERR_IO_PENDING && next_state_ != STATE_NONE && 348 } while (rv != ERR_IO_PENDING && next_state_ != STATE_NONE &&
365 next_state_ != STATE_DONE); 349 next_state_ != STATE_DONE);
366 return rv; 350 return rv;
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
445 // need to be very suspicious about the response because an active network 429 // need to be very suspicious about the response because an active network
446 // attacker can force us into this state by masquerading as the proxy. 430 // attacker can force us into this state by masquerading as the proxy.
447 // The only safe thing to do here is to fail the connection because our 431 // The only safe thing to do here is to fail the connection because our
448 // client is expecting an SSL protected response. 432 // client is expecting an SSL protected response.
449 // See http://crbug.com/7338. 433 // See http://crbug.com/7338.
450 case 407: // Proxy Authentication Required 434 case 407: // Proxy Authentication Required
451 // We need this status code to allow proxy authentication. Our 435 // We need this status code to allow proxy authentication. Our
452 // authentication code is smart enough to avoid being tricked by an 436 // authentication code is smart enough to avoid being tricked by an
453 // active network attacker. 437 // active network attacker.
454 // The next state is intentionally not set as it should be STATE_NONE; 438 // The next state is intentionally not set as it should be STATE_NONE;
455 return HandleAuthChallenge(); 439 return HandleAuthChallenge(auth_, &response_, net_log_);
456 440
457 default: 441 default:
458 if (is_https_proxy_) 442 if (is_https_proxy_)
459 return ERR_HTTPS_PROXY_TUNNEL_RESPONSE; 443 return ERR_HTTPS_PROXY_TUNNEL_RESPONSE;
460 // For all other status codes, we conservatively fail the CONNECT 444 // For all other status codes, we conservatively fail the CONNECT
461 // request. 445 // request.
462 // We lose something by doing this. We have seen proxy 403, 404, and 446 // We lose something by doing this. We have seen proxy 403, 404, and
463 // 501 response bodies that contain a useful error message. For 447 // 501 response bodies that contain a useful error message. For
464 // example, Squid uses a 404 response to report the DNS error: "The 448 // example, Squid uses a 404 response to report the DNS error: "The
465 // domain name does not exist." 449 // domain name does not exist."
(...skipping 15 matching lines...) Expand all
481 return result; 465 return result;
482 466
483 if (http_stream_parser_->IsResponseBodyComplete()) 467 if (http_stream_parser_->IsResponseBodyComplete())
484 return DidDrainBodyForAuthRestart(true); 468 return DidDrainBodyForAuthRestart(true);
485 469
486 // Keep draining. 470 // Keep draining.
487 next_state_ = STATE_DRAIN_BODY; 471 next_state_ = STATE_DRAIN_BODY;
488 return OK; 472 return OK;
489 } 473 }
490 474
491 int HttpProxyClientSocket::DoTCPRestart() {
492 next_state_ = STATE_TCP_RESTART_COMPLETE;
493 return transport_->socket()->Connect(&io_callback_);
494 }
495
496 int HttpProxyClientSocket::DoTCPRestartComplete(int result) {
497 if (result != OK)
498 return result;
499
500 next_state_ = STATE_GENERATE_AUTH_TOKEN;
501 return result;
502 }
503
504 } // namespace net 475 } // namespace net
OLDNEW
« no previous file with comments | « net/http/http_proxy_client_socket.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