Chromium Code Reviews| 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.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" |
| 11 #include "net/base/host_port_pair.h" | 11 #include "net/base/host_port_pair.h" |
| 12 #include "net/base/io_buffer.h" | 12 #include "net/base/io_buffer.h" |
| 13 #include "net/base/net_log.h" | 13 #include "net/base/net_log.h" |
| 14 #include "net/base/net_util.h" | 14 #include "net/base/net_util.h" |
| 15 #include "net/http/connect_response_http_stream.h" | |
| 16 #include "net/http/http_basic_stream.h" | |
| 15 #include "net/http/http_net_log_params.h" | 17 #include "net/http/http_net_log_params.h" |
| 16 #include "net/http/http_network_session.h" | 18 #include "net/http/http_network_session.h" |
| 17 #include "net/http/http_proxy_utils.h" | 19 #include "net/http/http_proxy_utils.h" |
| 18 #include "net/http/http_request_info.h" | 20 #include "net/http/http_request_info.h" |
| 19 #include "net/http/http_response_headers.h" | 21 #include "net/http/http_response_headers.h" |
| 20 #include "net/http/http_stream_parser.h" | 22 #include "net/http/http_stream_parser.h" |
| 21 #include "net/socket/client_socket_handle.h" | 23 #include "net/socket/client_socket_handle.h" |
| 22 | 24 |
| 23 namespace net { | 25 namespace net { |
| 24 | 26 |
| 25 HttpProxyClientSocket::HttpProxyClientSocket( | 27 HttpProxyClientSocket::HttpProxyClientSocket( |
| 26 ClientSocketHandle* transport_socket, | 28 ClientSocketHandle* transport_socket, |
| 27 const GURL& request_url, | 29 const GURL& request_url, |
| 28 const std::string& user_agent, | 30 const std::string& user_agent, |
| 29 const HostPortPair& endpoint, | 31 const HostPortPair& endpoint, |
| 30 const HostPortPair& proxy_server, | 32 const HostPortPair& proxy_server, |
| 31 HttpAuthCache* http_auth_cache, | 33 HttpAuthCache* http_auth_cache, |
| 32 HttpAuthHandlerFactory* http_auth_handler_factory, | 34 HttpAuthHandlerFactory* http_auth_handler_factory, |
| 33 bool tunnel, | 35 bool tunnel, |
| 34 bool using_spdy) | 36 bool using_spdy, |
| 37 bool is_https_proxy) | |
| 35 : ALLOW_THIS_IN_INITIALIZER_LIST( | 38 : ALLOW_THIS_IN_INITIALIZER_LIST( |
| 36 io_callback_(this, &HttpProxyClientSocket::OnIOComplete)), | 39 io_callback_(this, &HttpProxyClientSocket::OnIOComplete)), |
| 37 next_state_(STATE_NONE), | 40 next_state_(STATE_NONE), |
| 38 user_callback_(NULL), | 41 user_callback_(NULL), |
| 39 transport_(transport_socket), | 42 transport_(transport_socket), |
| 40 endpoint_(endpoint), | 43 endpoint_(endpoint), |
| 41 auth_(tunnel ? | 44 auth_(tunnel ? |
| 42 new HttpAuthController(HttpAuth::AUTH_PROXY, | 45 new HttpAuthController(HttpAuth::AUTH_PROXY, |
| 43 GURL("http://" + proxy_server.ToString()), | 46 GURL("http://" + proxy_server.ToString()), |
| 44 http_auth_cache, | 47 http_auth_cache, |
| 45 http_auth_handler_factory) | 48 http_auth_handler_factory) |
| 46 : NULL), | 49 : NULL), |
| 47 tunnel_(tunnel), | 50 tunnel_(tunnel), |
| 48 using_spdy_(using_spdy), | 51 using_spdy_(using_spdy), |
| 52 is_https_proxy_(is_https_proxy), | |
| 49 net_log_(transport_socket->socket()->NetLog()) { | 53 net_log_(transport_socket->socket()->NetLog()) { |
| 50 // Synthesize the bits of a request that we actually use. | 54 // Synthesize the bits of a request that we actually use. |
| 51 request_.url = request_url; | 55 request_.url = request_url; |
| 52 request_.method = "GET"; | 56 request_.method = "GET"; |
| 53 if (!user_agent.empty()) | 57 if (!user_agent.empty()) |
| 54 request_.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent, | 58 request_.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent, |
| 55 user_agent); | 59 user_agent); |
| 56 } | 60 } |
| 57 | 61 |
| 58 HttpProxyClientSocket::~HttpProxyClientSocket() { | 62 HttpProxyClientSocket::~HttpProxyClientSocket() { |
| 59 Disconnect(); | 63 Disconnect(); |
| 60 } | 64 } |
| 61 | 65 |
| 66 HttpStream* HttpProxyClientSocket::GetConnectResponseStream() { | |
| 67 return new HttpBasicStream(http_stream_parser_.release(), | |
| 68 transport_.release()); | |
| 69 } | |
| 70 | |
| 71 | |
| 62 int HttpProxyClientSocket::Connect(CompletionCallback* callback) { | 72 int HttpProxyClientSocket::Connect(CompletionCallback* callback) { |
| 63 DCHECK(transport_.get()); | 73 DCHECK(transport_.get()); |
| 64 DCHECK(transport_->socket()); | 74 DCHECK(transport_->socket()); |
| 65 DCHECK(!user_callback_); | 75 DCHECK(!user_callback_); |
| 66 | 76 |
| 67 // TODO(rch): figure out the right way to set up a tunnel with SPDY. | 77 // TODO(rch): figure out the right way to set up a tunnel with SPDY. |
| 68 // This approach sends the complete HTTPS request to the proxy | 78 // This approach sends the complete HTTPS request to the proxy |
| 69 // which allows the proxy to see "private" data. Instead, we should | 79 // which allows the proxy to see "private" data. Instead, we should |
| 70 // create an SSL tunnel to the origin server using the CONNECT method | 80 // create an SSL tunnel to the origin server using the CONNECT method |
| 71 // inside a single SPDY stream. | 81 // inside a single SPDY stream. |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 138 return OK; | 148 return OK; |
| 139 } | 149 } |
| 140 | 150 |
| 141 void HttpProxyClientSocket::LogBlockedTunnelResponse(int response_code) const { | 151 void HttpProxyClientSocket::LogBlockedTunnelResponse(int response_code) const { |
| 142 LOG(WARNING) << "Blocked proxy response with status " << response_code | 152 LOG(WARNING) << "Blocked proxy response with status " << response_code |
| 143 << " to CONNECT request for " | 153 << " to CONNECT request for " |
| 144 << GetHostAndPort(request_.url) << "."; | 154 << GetHostAndPort(request_.url) << "."; |
| 145 } | 155 } |
| 146 | 156 |
| 147 void HttpProxyClientSocket::Disconnect() { | 157 void HttpProxyClientSocket::Disconnect() { |
| 148 transport_->socket()->Disconnect(); | 158 if (transport_.get()) |
| 159 transport_->socket()->Disconnect(); | |
| 149 | 160 |
| 150 // Reset other states to make sure they aren't mistakenly used later. | 161 // Reset other states to make sure they aren't mistakenly used later. |
| 151 // These are the states initialized by Connect(). | 162 // These are the states initialized by Connect(). |
| 152 next_state_ = STATE_NONE; | 163 next_state_ = STATE_NONE; |
| 153 user_callback_ = NULL; | 164 user_callback_ = NULL; |
| 154 } | 165 } |
| 155 | 166 |
| 156 bool HttpProxyClientSocket::IsConnected() const { | 167 bool HttpProxyClientSocket::IsConnected() const { |
| 157 return next_state_ == STATE_DONE && transport_->socket()->IsConnected(); | 168 return next_state_ == STATE_DONE && transport_->socket()->IsConnected(); |
| 158 } | 169 } |
| (...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 398 // client is expecting an SSL protected response. | 409 // client is expecting an SSL protected response. |
| 399 // See http://crbug.com/7338. | 410 // See http://crbug.com/7338. |
| 400 case 407: // Proxy Authentication Required | 411 case 407: // Proxy Authentication Required |
| 401 // We need this status code to allow proxy authentication. Our | 412 // We need this status code to allow proxy authentication. Our |
| 402 // authentication code is smart enough to avoid being tricked by an | 413 // authentication code is smart enough to avoid being tricked by an |
| 403 // active network attacker. | 414 // active network attacker. |
| 404 // The next state is intentionally not set as it should be STATE_NONE; | 415 // The next state is intentionally not set as it should be STATE_NONE; |
| 405 return HandleAuthChallenge(); | 416 return HandleAuthChallenge(); |
| 406 | 417 |
| 407 default: | 418 default: |
| 408 // For all other status codes, we conservatively fail the CONNECT | 419 if (is_https_proxy_) { |
| 409 // request. | 420 return ERR_HTTPS_PROXY_TUNNEL_CONNECTION_RESPONSE; |
| 410 // We lose something by doing this. We have seen proxy 403, 404, and | 421 } else { |
|
vandebo (ex-Chrome)
2010/12/11 02:47:49
You don't need the else part because of the return
Ryan Hamilton
2010/12/13 19:41:12
Done.
| |
| 411 // 501 response bodies that contain a useful error message. For | 422 // For all other status codes, we conservatively fail the CONNECT |
| 412 // example, Squid uses a 404 response to report the DNS error: "The | 423 // request. |
| 413 // domain name does not exist." | 424 // We lose something by doing this. We have seen proxy 403, 404, and |
| 414 LogBlockedTunnelResponse(response_.headers->response_code()); | 425 // 501 response bodies that contain a useful error message. For |
| 415 return ERR_TUNNEL_CONNECTION_FAILED; | 426 // example, Squid uses a 404 response to report the DNS error: "The |
| 427 // domain name does not exist." | |
| 428 LogBlockedTunnelResponse(response_.headers->response_code()); | |
| 429 return ERR_TUNNEL_CONNECTION_FAILED; | |
| 430 } | |
| 416 } | 431 } |
| 417 } | 432 } |
| 418 | 433 |
| 419 int HttpProxyClientSocket::DoDrainBody() { | 434 int HttpProxyClientSocket::DoDrainBody() { |
| 420 DCHECK(drain_buf_); | 435 DCHECK(drain_buf_); |
| 421 DCHECK(transport_->is_initialized()); | 436 DCHECK(transport_->is_initialized()); |
| 422 next_state_ = STATE_DRAIN_BODY_COMPLETE; | 437 next_state_ = STATE_DRAIN_BODY_COMPLETE; |
| 423 return http_stream_parser_->ReadResponseBody(drain_buf_, kDrainBodyBufferSize, | 438 return http_stream_parser_->ReadResponseBody(drain_buf_, kDrainBodyBufferSize, |
| 424 &io_callback_); | 439 &io_callback_); |
| 425 } | 440 } |
| (...skipping 28 matching lines...) Expand all Loading... | |
| 454 | 469 |
| 455 int rv = auth_->HandleAuthChallenge(response_.headers, false, true, net_log_); | 470 int rv = auth_->HandleAuthChallenge(response_.headers, false, true, net_log_); |
| 456 response_.auth_challenge = auth_->auth_info(); | 471 response_.auth_challenge = auth_->auth_info(); |
| 457 if (rv == OK) | 472 if (rv == OK) |
| 458 return ERR_PROXY_AUTH_REQUESTED; | 473 return ERR_PROXY_AUTH_REQUESTED; |
| 459 | 474 |
| 460 return rv; | 475 return rv; |
| 461 } | 476 } |
| 462 | 477 |
| 463 } // namespace net | 478 } // namespace net |
| OLD | NEW |