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

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

Issue 9316101: Revert 118950 - Allow chrome to handle 407 auth challenges to CONNECT requests (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 8 years, 10 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
« no previous file with comments | « net/http/http_proxy_client_socket.h ('k') | net/http/http_proxy_client_socket_pool.h » ('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) 2012 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/bind.h" 7 #include "base/bind.h"
8 #include "base/bind_helpers.h" 8 #include "base/bind_helpers.h"
9 #include "base/string_util.h" 9 #include "base/string_util.h"
10 #include "base/stringprintf.h" 10 #include "base/stringprintf.h"
11 #include "googleurl/src/gurl.h" 11 #include "googleurl/src/gurl.h"
(...skipping 12 matching lines...) Expand all
24 #include "net/socket/client_socket_handle.h" 24 #include "net/socket/client_socket_handle.h"
25 25
26 namespace net { 26 namespace net {
27 27
28 HttpProxyClientSocket::HttpProxyClientSocket( 28 HttpProxyClientSocket::HttpProxyClientSocket(
29 ClientSocketHandle* transport_socket, 29 ClientSocketHandle* transport_socket,
30 const GURL& request_url, 30 const GURL& request_url,
31 const std::string& user_agent, 31 const std::string& user_agent,
32 const HostPortPair& endpoint, 32 const HostPortPair& endpoint,
33 const HostPortPair& proxy_server, 33 const HostPortPair& proxy_server,
34 HttpAuthController* http_auth_controller, 34 HttpAuthCache* http_auth_cache,
35 HttpAuthHandlerFactory* http_auth_handler_factory,
35 bool tunnel, 36 bool tunnel,
36 bool using_spdy, 37 bool using_spdy,
37 SSLClientSocket::NextProto protocol_negotiated, 38 SSLClientSocket::NextProto protocol_negotiated,
38 bool is_https_proxy) 39 bool is_https_proxy)
39 : ALLOW_THIS_IN_INITIALIZER_LIST(io_callback_( 40 : ALLOW_THIS_IN_INITIALIZER_LIST(io_callback_(
40 base::Bind(&HttpProxyClientSocket::OnIOComplete, 41 base::Bind(&HttpProxyClientSocket::OnIOComplete,
41 base::Unretained(this)))), 42 base::Unretained(this)))),
42 next_state_(STATE_NONE), 43 next_state_(STATE_NONE),
43 transport_(transport_socket), 44 transport_(transport_socket),
44 endpoint_(endpoint), 45 endpoint_(endpoint),
45 auth_(http_auth_controller), 46 auth_(tunnel ?
47 new HttpAuthController(HttpAuth::AUTH_PROXY,
48 GURL((is_https_proxy ? "https://" : "http://")
49 + proxy_server.ToString()),
50 http_auth_cache,
51 http_auth_handler_factory)
52 : NULL),
46 tunnel_(tunnel), 53 tunnel_(tunnel),
47 using_spdy_(using_spdy), 54 using_spdy_(using_spdy),
48 protocol_negotiated_(protocol_negotiated), 55 protocol_negotiated_(protocol_negotiated),
49 is_https_proxy_(is_https_proxy), 56 is_https_proxy_(is_https_proxy),
50 net_log_(transport_socket->socket()->NetLog()) { 57 net_log_(transport_socket->socket()->NetLog()) {
51 // Synthesize the bits of a request that we actually use. 58 // Synthesize the bits of a request that we actually use.
52 request_.url = request_url; 59 request_.url = request_url;
53 request_.method = "GET"; 60 request_.method = "GET";
54 if (!user_agent.empty()) 61 if (!user_agent.empty())
55 request_.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent, 62 request_.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
56 user_agent); 63 user_agent);
57 } 64 }
58 65
59 HttpProxyClientSocket::~HttpProxyClientSocket() { 66 HttpProxyClientSocket::~HttpProxyClientSocket() {
60 Disconnect(); 67 Disconnect();
61 } 68 }
62 69
63 const
64 scoped_refptr<HttpAuthController>& HttpProxyClientSocket::GetAuthController() {
65 return auth_;
66 }
67
68 int HttpProxyClientSocket::RestartWithAuth(const CompletionCallback& callback) { 70 int HttpProxyClientSocket::RestartWithAuth(const CompletionCallback& callback) {
69 DCHECK_EQ(STATE_NONE, next_state_); 71 DCHECK_EQ(STATE_NONE, next_state_);
70 DCHECK(user_callback_.is_null()); 72 DCHECK(user_callback_.is_null());
71 73
72 int rv = PrepareForAuthRestart(); 74 int rv = PrepareForAuthRestart();
73 if (rv != OK) 75 if (rv != OK)
74 return rv; 76 return rv;
75 77
76 rv = DoLoop(OK); 78 rv = DoLoop(OK);
77 if (rv == ERR_IO_PENDING) { 79 if (rv == ERR_IO_PENDING) {
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after
245 } 247 }
246 keep_alive = true; 248 keep_alive = true;
247 } 249 }
248 250
249 // We don't need to drain the response body, so we act as if we had drained 251 // We don't need to drain the response body, so we act as if we had drained
250 // the response body. 252 // the response body.
251 return DidDrainBodyForAuthRestart(keep_alive); 253 return DidDrainBodyForAuthRestart(keep_alive);
252 } 254 }
253 255
254 int HttpProxyClientSocket::DidDrainBodyForAuthRestart(bool keep_alive) { 256 int HttpProxyClientSocket::DidDrainBodyForAuthRestart(bool keep_alive) {
255 int rv = OK;
256 if (keep_alive && transport_->socket()->IsConnectedAndIdle()) { 257 if (keep_alive && transport_->socket()->IsConnectedAndIdle()) {
257 next_state_ = STATE_GENERATE_AUTH_TOKEN; 258 next_state_ = STATE_GENERATE_AUTH_TOKEN;
258 transport_->set_is_reused(true); 259 transport_->set_is_reused(true);
259 } else { 260 } else {
260 next_state_ = STATE_NONE; 261 // This assumes that the underlying transport socket is a TCP socket,
262 // since only TCP sockets are restartable.
263 next_state_ = STATE_TCP_RESTART;
261 transport_->socket()->Disconnect(); 264 transport_->socket()->Disconnect();
262 rv = ERR_NO_KEEP_ALIVE_ON_AUTH_RESTART;
263 } 265 }
264 266
265 // Reset the other member variables. 267 // Reset the other member variables.
266 drain_buf_ = NULL; 268 drain_buf_ = NULL;
267 parser_buf_ = NULL; 269 parser_buf_ = NULL;
268 http_stream_parser_.reset(); 270 http_stream_parser_.reset();
269 request_line_.clear(); 271 request_line_.clear();
270 request_headers_.Clear(); 272 request_headers_.Clear();
271 response_ = HttpResponseInfo(); 273 response_ = HttpResponseInfo();
274 return OK;
275 }
276
277 int HttpProxyClientSocket::HandleAuthChallenge() {
278 DCHECK(response_.headers);
279
280 int rv = auth_->HandleAuthChallenge(response_.headers, false, true, net_log_);
281 response_.auth_challenge = auth_->auth_info();
282 if (rv == OK)
283 return ERR_PROXY_AUTH_REQUESTED;
284
272 return rv; 285 return rv;
273 } 286 }
274 287
275 void HttpProxyClientSocket::LogBlockedTunnelResponse(int response_code) const { 288 void HttpProxyClientSocket::LogBlockedTunnelResponse(int response_code) const {
276 LOG(WARNING) << "Blocked proxy response with status " << response_code 289 LOG(WARNING) << "Blocked proxy response with status " << response_code
277 << " to CONNECT request for " 290 << " to CONNECT request for "
278 << GetHostAndPort(request_.url) << "."; 291 << GetHostAndPort(request_.url) << ".";
279 } 292 }
280 293
281 void HttpProxyClientSocket::DoCallback(int result) { 294 void HttpProxyClientSocket::DoCallback(int result) {
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
334 net_log_.EndEventWithNetErrorCode( 347 net_log_.EndEventWithNetErrorCode(
335 NetLog::TYPE_HTTP_TRANSACTION_TUNNEL_READ_HEADERS, rv); 348 NetLog::TYPE_HTTP_TRANSACTION_TUNNEL_READ_HEADERS, rv);
336 break; 349 break;
337 case STATE_DRAIN_BODY: 350 case STATE_DRAIN_BODY:
338 DCHECK_EQ(OK, rv); 351 DCHECK_EQ(OK, rv);
339 rv = DoDrainBody(); 352 rv = DoDrainBody();
340 break; 353 break;
341 case STATE_DRAIN_BODY_COMPLETE: 354 case STATE_DRAIN_BODY_COMPLETE:
342 rv = DoDrainBodyComplete(rv); 355 rv = DoDrainBodyComplete(rv);
343 break; 356 break;
357 case STATE_TCP_RESTART:
358 DCHECK_EQ(OK, rv);
359 rv = DoTCPRestart();
360 break;
361 case STATE_TCP_RESTART_COMPLETE:
362 rv = DoTCPRestartComplete(rv);
363 break;
344 case STATE_DONE: 364 case STATE_DONE:
345 break; 365 break;
346 default: 366 default:
347 NOTREACHED() << "bad state"; 367 NOTREACHED() << "bad state";
348 rv = ERR_UNEXPECTED; 368 rv = ERR_UNEXPECTED;
349 break; 369 break;
350 } 370 }
351 } while (rv != ERR_IO_PENDING && next_state_ != STATE_NONE && 371 } while (rv != ERR_IO_PENDING && next_state_ != STATE_NONE &&
352 next_state_ != STATE_DONE); 372 next_state_ != STATE_DONE);
353 return rv; 373 return rv;
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
432 // need to be very suspicious about the response because an active network 452 // need to be very suspicious about the response because an active network
433 // attacker can force us into this state by masquerading as the proxy. 453 // attacker can force us into this state by masquerading as the proxy.
434 // The only safe thing to do here is to fail the connection because our 454 // The only safe thing to do here is to fail the connection because our
435 // client is expecting an SSL protected response. 455 // client is expecting an SSL protected response.
436 // See http://crbug.com/7338. 456 // See http://crbug.com/7338.
437 case 407: // Proxy Authentication Required 457 case 407: // Proxy Authentication Required
438 // We need this status code to allow proxy authentication. Our 458 // We need this status code to allow proxy authentication. Our
439 // authentication code is smart enough to avoid being tricked by an 459 // authentication code is smart enough to avoid being tricked by an
440 // active network attacker. 460 // active network attacker.
441 // The next state is intentionally not set as it should be STATE_NONE; 461 // The next state is intentionally not set as it should be STATE_NONE;
442 return HandleAuthChallenge(auth_, &response_, net_log_); 462 return HandleAuthChallenge();
443 463
444 default: 464 default:
445 if (is_https_proxy_) 465 if (is_https_proxy_)
446 return ERR_HTTPS_PROXY_TUNNEL_RESPONSE; 466 return ERR_HTTPS_PROXY_TUNNEL_RESPONSE;
447 // For all other status codes, we conservatively fail the CONNECT 467 // For all other status codes, we conservatively fail the CONNECT
448 // request. 468 // request.
449 // We lose something by doing this. We have seen proxy 403, 404, and 469 // We lose something by doing this. We have seen proxy 403, 404, and
450 // 501 response bodies that contain a useful error message. For 470 // 501 response bodies that contain a useful error message. For
451 // example, Squid uses a 404 response to report the DNS error: "The 471 // example, Squid uses a 404 response to report the DNS error: "The
452 // domain name does not exist." 472 // domain name does not exist."
(...skipping 15 matching lines...) Expand all
468 return result; 488 return result;
469 489
470 if (http_stream_parser_->IsResponseBodyComplete()) 490 if (http_stream_parser_->IsResponseBodyComplete())
471 return DidDrainBodyForAuthRestart(true); 491 return DidDrainBodyForAuthRestart(true);
472 492
473 // Keep draining. 493 // Keep draining.
474 next_state_ = STATE_DRAIN_BODY; 494 next_state_ = STATE_DRAIN_BODY;
475 return OK; 495 return OK;
476 } 496 }
477 497
498 int HttpProxyClientSocket::DoTCPRestart() {
499 next_state_ = STATE_TCP_RESTART_COMPLETE;
500 return transport_->socket()->Connect(
501 base::Bind(&HttpProxyClientSocket::OnIOComplete, base::Unretained(this)));
502 }
503
504 int HttpProxyClientSocket::DoTCPRestartComplete(int result) {
505 if (result != OK)
506 return result;
507
508 next_state_ = STATE_GENERATE_AUTH_TOKEN;
509 return result;
510 }
511
478 } // namespace net 512 } // namespace net
OLDNEW
« no previous file with comments | « net/http/http_proxy_client_socket.h ('k') | net/http/http_proxy_client_socket_pool.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698