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" | |
|
vandebo (ex-Chrome)
2010/12/04 00:30:37
Is this header needed?
Ryan Hamilton
2010/12/09 21:19:35
Done.
| |
| 15 #include "net/http/http_net_log_params.h" | 16 #include "net/http/http_net_log_params.h" |
| 16 #include "net/http/http_network_session.h" | 17 #include "net/http/http_network_session.h" |
| 17 #include "net/http/http_proxy_utils.h" | 18 #include "net/http/http_proxy_utils.h" |
| 18 #include "net/http/http_request_info.h" | 19 #include "net/http/http_request_info.h" |
| 19 #include "net/http/http_response_headers.h" | 20 #include "net/http/http_response_headers.h" |
| 20 #include "net/http/http_stream_parser.h" | 21 #include "net/http/http_stream_parser.h" |
| 21 #include "net/socket/client_socket_handle.h" | 22 #include "net/socket/client_socket_handle.h" |
| 22 | 23 |
| 23 namespace net { | 24 namespace net { |
| 24 | 25 |
| 25 HttpProxyClientSocket::HttpProxyClientSocket( | 26 HttpProxyClientSocket::HttpProxyClientSocket( |
| 26 ClientSocketHandle* transport_socket, | 27 ClientSocketHandle* transport_socket, |
| 27 const GURL& request_url, | 28 const GURL& request_url, |
| 28 const std::string& user_agent, | 29 const std::string& user_agent, |
| 29 const HostPortPair& endpoint, | 30 const HostPortPair& endpoint, |
| 30 const HostPortPair& proxy_server, | 31 const HostPortPair& proxy_server, |
| 31 HttpAuthCache* http_auth_cache, | 32 HttpAuthCache* http_auth_cache, |
| 32 HttpAuthHandlerFactory* http_auth_handler_factory, | 33 HttpAuthHandlerFactory* http_auth_handler_factory, |
| 33 bool tunnel, | 34 bool tunnel, |
| 34 bool using_spdy) | 35 bool using_spdy, |
| 36 bool is_https_proxy) | |
| 35 : ALLOW_THIS_IN_INITIALIZER_LIST( | 37 : ALLOW_THIS_IN_INITIALIZER_LIST( |
| 36 io_callback_(this, &HttpProxyClientSocket::OnIOComplete)), | 38 io_callback_(this, &HttpProxyClientSocket::OnIOComplete)), |
| 37 next_state_(STATE_NONE), | 39 next_state_(STATE_NONE), |
| 38 user_callback_(NULL), | 40 user_callback_(NULL), |
| 39 transport_(transport_socket), | 41 transport_(transport_socket), |
| 40 endpoint_(endpoint), | 42 endpoint_(endpoint), |
| 41 auth_(tunnel ? | 43 auth_(tunnel ? |
| 42 new HttpAuthController(HttpAuth::AUTH_PROXY, | 44 new HttpAuthController(HttpAuth::AUTH_PROXY, |
| 43 GURL("http://" + proxy_server.ToString()), | 45 GURL("http://" + proxy_server.ToString()), |
| 44 http_auth_cache, | 46 http_auth_cache, |
| 45 http_auth_handler_factory) | 47 http_auth_handler_factory) |
| 46 : NULL), | 48 : NULL), |
| 47 tunnel_(tunnel), | 49 tunnel_(tunnel), |
| 48 using_spdy_(using_spdy), | 50 using_spdy_(using_spdy), |
| 51 is_https_proxy_(is_https_proxy), | |
| 49 net_log_(transport_socket->socket()->NetLog()) { | 52 net_log_(transport_socket->socket()->NetLog()) { |
| 50 // Synthesize the bits of a request that we actually use. | 53 // Synthesize the bits of a request that we actually use. |
| 51 request_.url = request_url; | 54 request_.url = request_url; |
| 52 request_.method = "GET"; | 55 request_.method = "GET"; |
| 53 if (!user_agent.empty()) | 56 if (!user_agent.empty()) |
| 54 request_.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent, | 57 request_.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent, |
| 55 user_agent); | 58 user_agent); |
| 56 } | 59 } |
| 57 | 60 |
| 58 HttpProxyClientSocket::~HttpProxyClientSocket() { | 61 HttpProxyClientSocket::~HttpProxyClientSocket() { |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 138 return OK; | 141 return OK; |
| 139 } | 142 } |
| 140 | 143 |
| 141 void HttpProxyClientSocket::LogBlockedTunnelResponse(int response_code) const { | 144 void HttpProxyClientSocket::LogBlockedTunnelResponse(int response_code) const { |
| 142 LOG(WARNING) << "Blocked proxy response with status " << response_code | 145 LOG(WARNING) << "Blocked proxy response with status " << response_code |
| 143 << " to CONNECT request for " | 146 << " to CONNECT request for " |
| 144 << GetHostAndPort(request_.url) << "."; | 147 << GetHostAndPort(request_.url) << "."; |
| 145 } | 148 } |
| 146 | 149 |
| 147 void HttpProxyClientSocket::Disconnect() { | 150 void HttpProxyClientSocket::Disconnect() { |
| 148 transport_->socket()->Disconnect(); | 151 if (transport_->socket()) |
|
vandebo (ex-Chrome)
2010/12/04 00:30:37
When is this false?
Ryan Hamilton
2010/12/09 21:19:35
So I think this was somewhat of a bug which I desc
| |
| 152 transport_->socket()->Disconnect(); | |
| 149 | 153 |
| 150 // Reset other states to make sure they aren't mistakenly used later. | 154 // Reset other states to make sure they aren't mistakenly used later. |
| 151 // These are the states initialized by Connect(). | 155 // These are the states initialized by Connect(). |
| 152 next_state_ = STATE_NONE; | 156 next_state_ = STATE_NONE; |
| 153 user_callback_ = NULL; | 157 user_callback_ = NULL; |
| 154 } | 158 } |
| 155 | 159 |
| 156 bool HttpProxyClientSocket::IsConnected() const { | 160 bool HttpProxyClientSocket::IsConnected() const { |
| 157 return next_state_ == STATE_DONE && transport_->socket()->IsConnected(); | 161 return next_state_ == STATE_DONE && transport_->socket()->IsConnected(); |
| 158 } | 162 } |
| (...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 398 // client is expecting an SSL protected response. | 402 // client is expecting an SSL protected response. |
| 399 // See http://crbug.com/7338. | 403 // See http://crbug.com/7338. |
| 400 case 407: // Proxy Authentication Required | 404 case 407: // Proxy Authentication Required |
| 401 // We need this status code to allow proxy authentication. Our | 405 // We need this status code to allow proxy authentication. Our |
| 402 // authentication code is smart enough to avoid being tricked by an | 406 // authentication code is smart enough to avoid being tricked by an |
| 403 // active network attacker. | 407 // active network attacker. |
| 404 // The next state is intentionally not set as it should be STATE_NONE; | 408 // The next state is intentionally not set as it should be STATE_NONE; |
| 405 return HandleAuthChallenge(); | 409 return HandleAuthChallenge(); |
| 406 | 410 |
| 407 default: | 411 default: |
| 408 // For all other status codes, we conservatively fail the CONNECT | |
| 409 // request. | |
| 410 // We lose something by doing this. We have seen proxy 403, 404, and | |
| 411 // 501 response bodies that contain a useful error message. For | |
| 412 // example, Squid uses a 404 response to report the DNS error: "The | |
| 413 // domain name does not exist." | |
| 414 LogBlockedTunnelResponse(response_.headers->response_code()); | 412 LogBlockedTunnelResponse(response_.headers->response_code()); |
|
vandebo (ex-Chrome)
2010/12/04 00:30:37
Shouldn't this Log call be in the else clause?
Ryan Hamilton
2010/12/09 21:19:35
Done.
| |
| 415 return ERR_TUNNEL_CONNECTION_FAILED; | 413 if (is_https_proxy_) { |
| 414 return ERR_HTTPS_PROXY_TUNNEL_CONNECTION_RESPONSE; | |
| 415 } else { | |
| 416 // For all other status codes, we conservatively fail the CONNECT | |
| 417 // request. | |
| 418 // We lose something by doing this. We have seen proxy 403, 404, and | |
| 419 // 501 response bodies that contain a useful error message. For | |
| 420 // example, Squid uses a 404 response to report the DNS error: "The | |
| 421 // domain name does not exist." | |
| 422 return ERR_TUNNEL_CONNECTION_FAILED; | |
| 423 } | |
| 416 } | 424 } |
| 417 } | 425 } |
| 418 | 426 |
| 419 int HttpProxyClientSocket::DoDrainBody() { | 427 int HttpProxyClientSocket::DoDrainBody() { |
| 420 DCHECK(drain_buf_); | 428 DCHECK(drain_buf_); |
| 421 DCHECK(transport_->is_initialized()); | 429 DCHECK(transport_->is_initialized()); |
| 422 next_state_ = STATE_DRAIN_BODY_COMPLETE; | 430 next_state_ = STATE_DRAIN_BODY_COMPLETE; |
| 423 return http_stream_parser_->ReadResponseBody(drain_buf_, kDrainBodyBufferSize, | 431 return http_stream_parser_->ReadResponseBody(drain_buf_, kDrainBodyBufferSize, |
| 424 &io_callback_); | 432 &io_callback_); |
| 425 } | 433 } |
| (...skipping 28 matching lines...) Expand all Loading... | |
| 454 | 462 |
| 455 int rv = auth_->HandleAuthChallenge(response_.headers, false, true, net_log_); | 463 int rv = auth_->HandleAuthChallenge(response_.headers, false, true, net_log_); |
| 456 response_.auth_challenge = auth_->auth_info(); | 464 response_.auth_challenge = auth_->auth_info(); |
| 457 if (rv == OK) | 465 if (rv == OK) |
| 458 return ERR_PROXY_AUTH_REQUESTED; | 466 return ERR_PROXY_AUTH_REQUESTED; |
| 459 | 467 |
| 460 return rv; | 468 return rv; |
| 461 } | 469 } |
| 462 | 470 |
| 463 } // namespace net | 471 } // namespace net |
| OLD | NEW |