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 |