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

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

Issue 4935001: Allow a non-200 (or non-407) response for a CONNECT request from an HTTPS pro... (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: '' Created 10 years 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) 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
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
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
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
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