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

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

Issue 266243004: Clang format slam. Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 7 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
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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/strings/string_util.h" 9 #include "base/strings/string_util.h"
10 #include "base/strings/stringprintf.h" 10 #include "base/strings/stringprintf.h"
(...skipping 23 matching lines...) Expand all
34 HttpAuthHandlerFactory* http_auth_handler_factory, 34 HttpAuthHandlerFactory* http_auth_handler_factory,
35 bool tunnel, 35 bool tunnel,
36 bool using_spdy, 36 bool using_spdy,
37 NextProto protocol_negotiated, 37 NextProto protocol_negotiated,
38 bool is_https_proxy) 38 bool is_https_proxy)
39 : io_callback_(base::Bind(&HttpProxyClientSocket::OnIOComplete, 39 : io_callback_(base::Bind(&HttpProxyClientSocket::OnIOComplete,
40 base::Unretained(this))), 40 base::Unretained(this))),
41 next_state_(STATE_NONE), 41 next_state_(STATE_NONE),
42 transport_(transport_socket), 42 transport_(transport_socket),
43 endpoint_(endpoint), 43 endpoint_(endpoint),
44 auth_(tunnel ? 44 auth_(tunnel ? new HttpAuthController(
45 new HttpAuthController(HttpAuth::AUTH_PROXY, 45 HttpAuth::AUTH_PROXY,
46 GURL((is_https_proxy ? "https://" : "http://") 46 GURL((is_https_proxy ? "https://" : "http://") +
47 + proxy_server.ToString()), 47 proxy_server.ToString()),
48 http_auth_cache, 48 http_auth_cache,
49 http_auth_handler_factory) 49 http_auth_handler_factory)
50 : NULL), 50 : NULL),
51 tunnel_(tunnel), 51 tunnel_(tunnel),
52 using_spdy_(using_spdy), 52 using_spdy_(using_spdy),
53 protocol_negotiated_(protocol_negotiated), 53 protocol_negotiated_(protocol_negotiated),
54 is_https_proxy_(is_https_proxy), 54 is_https_proxy_(is_https_proxy),
55 redirect_has_load_timing_info_(false), 55 redirect_has_load_timing_info_(false),
56 net_log_(transport_socket->socket()->NetLog()) { 56 net_log_(transport_socket->socket()->NetLog()) {
57 // Synthesize the bits of a request that we actually use. 57 // Synthesize the bits of a request that we actually use.
58 request_.url = request_url; 58 request_.url = request_url;
59 request_.method = "GET"; 59 request_.method = "GET";
60 if (!user_agent.empty()) 60 if (!user_agent.empty())
61 request_.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent, 61 request_.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
62 user_agent); 62 user_agent);
63 } 63 }
64 64
65 HttpProxyClientSocket::~HttpProxyClientSocket() { 65 HttpProxyClientSocket::~HttpProxyClientSocket() {
66 Disconnect(); 66 Disconnect();
67 } 67 }
68 68
69 int HttpProxyClientSocket::RestartWithAuth(const CompletionCallback& callback) { 69 int HttpProxyClientSocket::RestartWithAuth(const CompletionCallback& callback) {
70 DCHECK_EQ(STATE_NONE, next_state_); 70 DCHECK_EQ(STATE_NONE, next_state_);
71 DCHECK(user_callback_.is_null()); 71 DCHECK(user_callback_.is_null());
72 72
73 int rv = PrepareForAuthRestart(); 73 int rv = PrepareForAuthRestart();
74 if (rv != OK) 74 if (rv != OK)
75 return rv; 75 return rv;
76 76
77 rv = DoLoop(OK); 77 rv = DoLoop(OK);
78 if (rv == ERR_IO_PENDING) { 78 if (rv == ERR_IO_PENDING) {
79 if (!callback.is_null()) 79 if (!callback.is_null())
80 user_callback_ = callback; 80 user_callback_ = callback;
81 } 81 }
82 82
83 return rv; 83 return rv;
84 } 84 }
85 85
86 const scoped_refptr<HttpAuthController>& 86 const scoped_refptr<HttpAuthController>&
87 HttpProxyClientSocket::GetAuthController() const { 87 HttpProxyClientSocket::GetAuthController() const {
88 return auth_; 88 return auth_;
89 } 89 }
90 90
91 bool HttpProxyClientSocket::IsUsingSpdy() const { 91 bool HttpProxyClientSocket::IsUsingSpdy() const {
92 return using_spdy_; 92 return using_spdy_;
93 } 93 }
94 94
95 NextProto HttpProxyClientSocket::GetProtocolNegotiated() const { 95 NextProto HttpProxyClientSocket::GetProtocolNegotiated() const {
96 return protocol_negotiated_; 96 return protocol_negotiated_;
97 } 97 }
98 98
99 const HttpResponseInfo* HttpProxyClientSocket::GetConnectResponseInfo() const { 99 const HttpResponseInfo* HttpProxyClientSocket::GetConnectResponseInfo() const {
100 return response_.headers.get() ? &response_ : NULL; 100 return response_.headers.get() ? &response_ : NULL;
101 } 101 }
102 102
103 HttpStream* HttpProxyClientSocket::CreateConnectResponseStream() { 103 HttpStream* HttpProxyClientSocket::CreateConnectResponseStream() {
104 return new ProxyConnectRedirectHttpStream( 104 return new ProxyConnectRedirectHttpStream(
105 redirect_has_load_timing_info_ ? &redirect_load_timing_info_ : NULL); 105 redirect_has_load_timing_info_ ? &redirect_load_timing_info_ : NULL);
106 } 106 }
107 107
108
109 int HttpProxyClientSocket::Connect(const CompletionCallback& callback) { 108 int HttpProxyClientSocket::Connect(const CompletionCallback& callback) {
110 DCHECK(transport_.get()); 109 DCHECK(transport_.get());
111 DCHECK(transport_->socket()); 110 DCHECK(transport_->socket());
112 DCHECK(user_callback_.is_null()); 111 DCHECK(user_callback_.is_null());
113 112
114 // TODO(rch): figure out the right way to set up a tunnel with SPDY. 113 // TODO(rch): figure out the right way to set up a tunnel with SPDY.
115 // This approach sends the complete HTTPS request to the proxy 114 // This approach sends the complete HTTPS request to the proxy
116 // which allows the proxy to see "private" data. Instead, we should 115 // which allows the proxy to see "private" data. Instead, we should
117 // create an SSL tunnel to the origin server using the CONNECT method 116 // create an SSL tunnel to the origin server using the CONNECT method
118 // inside a single SPDY stream. 117 // inside a single SPDY stream.
(...skipping 20 matching lines...) Expand all
139 next_state_ = STATE_NONE; 138 next_state_ = STATE_NONE;
140 user_callback_.Reset(); 139 user_callback_.Reset();
141 } 140 }
142 141
143 bool HttpProxyClientSocket::IsConnected() const { 142 bool HttpProxyClientSocket::IsConnected() const {
144 return next_state_ == STATE_DONE && transport_->socket()->IsConnected(); 143 return next_state_ == STATE_DONE && transport_->socket()->IsConnected();
145 } 144 }
146 145
147 bool HttpProxyClientSocket::IsConnectedAndIdle() const { 146 bool HttpProxyClientSocket::IsConnectedAndIdle() const {
148 return next_state_ == STATE_DONE && 147 return next_state_ == STATE_DONE &&
149 transport_->socket()->IsConnectedAndIdle(); 148 transport_->socket()->IsConnectedAndIdle();
150 } 149 }
151 150
152 const BoundNetLog& HttpProxyClientSocket::NetLog() const { 151 const BoundNetLog& HttpProxyClientSocket::NetLog() const {
153 return net_log_; 152 return net_log_;
154 } 153 }
155 154
156 void HttpProxyClientSocket::SetSubresourceSpeculation() { 155 void HttpProxyClientSocket::SetSubresourceSpeculation() {
157 if (transport_.get() && transport_->socket()) { 156 if (transport_.get() && transport_->socket()) {
158 transport_->socket()->SetSubresourceSpeculation(); 157 transport_->socket()->SetSubresourceSpeculation();
159 } else { 158 } else {
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
202 } 201 }
203 202
204 bool HttpProxyClientSocket::GetSSLInfo(SSLInfo* ssl_info) { 203 bool HttpProxyClientSocket::GetSSLInfo(SSLInfo* ssl_info) {
205 if (transport_.get() && transport_->socket()) { 204 if (transport_.get() && transport_->socket()) {
206 return transport_->socket()->GetSSLInfo(ssl_info); 205 return transport_->socket()->GetSSLInfo(ssl_info);
207 } 206 }
208 NOTREACHED(); 207 NOTREACHED();
209 return false; 208 return false;
210 } 209 }
211 210
212 int HttpProxyClientSocket::Read(IOBuffer* buf, int buf_len, 211 int HttpProxyClientSocket::Read(IOBuffer* buf,
212 int buf_len,
213 const CompletionCallback& callback) { 213 const CompletionCallback& callback) {
214 DCHECK(user_callback_.is_null()); 214 DCHECK(user_callback_.is_null());
215 if (next_state_ != STATE_DONE) { 215 if (next_state_ != STATE_DONE) {
216 // We're trying to read the body of the response but we're still trying 216 // We're trying to read the body of the response but we're still trying
217 // to establish an SSL tunnel through the proxy. We can't read these 217 // to establish an SSL tunnel through the proxy. We can't read these
218 // bytes when establishing a tunnel because they might be controlled by 218 // bytes when establishing a tunnel because they might be controlled by
219 // an active network attacker. We don't worry about this for HTTP 219 // an active network attacker. We don't worry about this for HTTP
220 // because an active network attacker can already control HTTP sessions. 220 // because an active network attacker can already control HTTP sessions.
221 // We reach this case when the user cancels a 407 proxy auth prompt. 221 // We reach this case when the user cancels a 407 proxy auth prompt.
222 // See http://crbug.com/8473. 222 // See http://crbug.com/8473.
223 DCHECK_EQ(407, response_.headers->response_code()); 223 DCHECK_EQ(407, response_.headers->response_code());
224 LogBlockedTunnelResponse(); 224 LogBlockedTunnelResponse();
225 225
226 return ERR_TUNNEL_CONNECTION_FAILED; 226 return ERR_TUNNEL_CONNECTION_FAILED;
227 } 227 }
228 228
229 return transport_->socket()->Read(buf, buf_len, callback); 229 return transport_->socket()->Read(buf, buf_len, callback);
230 } 230 }
231 231
232 int HttpProxyClientSocket::Write(IOBuffer* buf, int buf_len, 232 int HttpProxyClientSocket::Write(IOBuffer* buf,
233 int buf_len,
233 const CompletionCallback& callback) { 234 const CompletionCallback& callback) {
234 DCHECK_EQ(STATE_DONE, next_state_); 235 DCHECK_EQ(STATE_DONE, next_state_);
235 DCHECK(user_callback_.is_null()); 236 DCHECK(user_callback_.is_null());
236 237
237 return transport_->socket()->Write(buf, buf_len, callback); 238 return transport_->socket()->Write(buf, buf_len, callback);
238 } 239 }
239 240
240 int HttpProxyClientSocket::SetReceiveBufferSize(int32 size) { 241 int HttpProxyClientSocket::SetReceiveBufferSize(int32 size) {
241 return transport_->socket()->SetReceiveBufferSize(size); 242 return transport_->socket()->SetReceiveBufferSize(size);
242 } 243 }
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
289 parser_buf_ = NULL; 290 parser_buf_ = NULL;
290 http_stream_parser_.reset(); 291 http_stream_parser_.reset();
291 request_line_.clear(); 292 request_line_.clear();
292 request_headers_.Clear(); 293 request_headers_.Clear();
293 response_ = HttpResponseInfo(); 294 response_ = HttpResponseInfo();
294 return OK; 295 return OK;
295 } 296 }
296 297
297 void HttpProxyClientSocket::LogBlockedTunnelResponse() const { 298 void HttpProxyClientSocket::LogBlockedTunnelResponse() const {
298 ProxyClientSocket::LogBlockedTunnelResponse( 299 ProxyClientSocket::LogBlockedTunnelResponse(
299 response_.headers->response_code(), 300 response_.headers->response_code(), request_.url, is_https_proxy_);
300 request_.url,
301 is_https_proxy_);
302 } 301 }
303 302
304 void HttpProxyClientSocket::DoCallback(int result) { 303 void HttpProxyClientSocket::DoCallback(int result) {
305 DCHECK_NE(ERR_IO_PENDING, result); 304 DCHECK_NE(ERR_IO_PENDING, result);
306 DCHECK(!user_callback_.is_null()); 305 DCHECK(!user_callback_.is_null());
307 306
308 // Since Run() may result in Read being called, 307 // Since Run() may result in Read being called,
309 // clear user_callback_ up front. 308 // clear user_callback_ up front.
310 CompletionCallback c = user_callback_; 309 CompletionCallback c = user_callback_;
311 user_callback_.Reset(); 310 user_callback_.Reset();
(...skipping 18 matching lines...) Expand all
330 switch (state) { 329 switch (state) {
331 case STATE_GENERATE_AUTH_TOKEN: 330 case STATE_GENERATE_AUTH_TOKEN:
332 DCHECK_EQ(OK, rv); 331 DCHECK_EQ(OK, rv);
333 rv = DoGenerateAuthToken(); 332 rv = DoGenerateAuthToken();
334 break; 333 break;
335 case STATE_GENERATE_AUTH_TOKEN_COMPLETE: 334 case STATE_GENERATE_AUTH_TOKEN_COMPLETE:
336 rv = DoGenerateAuthTokenComplete(rv); 335 rv = DoGenerateAuthTokenComplete(rv);
337 break; 336 break;
338 case STATE_SEND_REQUEST: 337 case STATE_SEND_REQUEST:
339 DCHECK_EQ(OK, rv); 338 DCHECK_EQ(OK, rv);
340 net_log_.BeginEvent( 339 net_log_.BeginEvent(NetLog::TYPE_HTTP_TRANSACTION_TUNNEL_SEND_REQUEST);
341 NetLog::TYPE_HTTP_TRANSACTION_TUNNEL_SEND_REQUEST);
342 rv = DoSendRequest(); 340 rv = DoSendRequest();
343 break; 341 break;
344 case STATE_SEND_REQUEST_COMPLETE: 342 case STATE_SEND_REQUEST_COMPLETE:
345 rv = DoSendRequestComplete(rv); 343 rv = DoSendRequestComplete(rv);
346 net_log_.EndEventWithNetErrorCode( 344 net_log_.EndEventWithNetErrorCode(
347 NetLog::TYPE_HTTP_TRANSACTION_TUNNEL_SEND_REQUEST, rv); 345 NetLog::TYPE_HTTP_TRANSACTION_TUNNEL_SEND_REQUEST, rv);
348 break; 346 break;
349 case STATE_READ_HEADERS: 347 case STATE_READ_HEADERS:
350 DCHECK_EQ(OK, rv); 348 DCHECK_EQ(OK, rv);
351 net_log_.BeginEvent( 349 net_log_.BeginEvent(NetLog::TYPE_HTTP_TRANSACTION_TUNNEL_READ_HEADERS);
352 NetLog::TYPE_HTTP_TRANSACTION_TUNNEL_READ_HEADERS);
353 rv = DoReadHeaders(); 350 rv = DoReadHeaders();
354 break; 351 break;
355 case STATE_READ_HEADERS_COMPLETE: 352 case STATE_READ_HEADERS_COMPLETE:
356 rv = DoReadHeadersComplete(rv); 353 rv = DoReadHeadersComplete(rv);
357 net_log_.EndEventWithNetErrorCode( 354 net_log_.EndEventWithNetErrorCode(
358 NetLog::TYPE_HTTP_TRANSACTION_TUNNEL_READ_HEADERS, rv); 355 NetLog::TYPE_HTTP_TRANSACTION_TUNNEL_READ_HEADERS, rv);
359 break; 356 break;
360 case STATE_DRAIN_BODY: 357 case STATE_DRAIN_BODY:
361 DCHECK_EQ(OK, rv); 358 DCHECK_EQ(OK, rv);
362 rv = DoDrainBody(); 359 rv = DoDrainBody();
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
398 int HttpProxyClientSocket::DoSendRequest() { 395 int HttpProxyClientSocket::DoSendRequest() {
399 next_state_ = STATE_SEND_REQUEST_COMPLETE; 396 next_state_ = STATE_SEND_REQUEST_COMPLETE;
400 397
401 // This is constructed lazily (instead of within our Start method), so that 398 // This is constructed lazily (instead of within our Start method), so that
402 // we have proxy info available. 399 // we have proxy info available.
403 if (request_line_.empty()) { 400 if (request_line_.empty()) {
404 DCHECK(request_headers_.IsEmpty()); 401 DCHECK(request_headers_.IsEmpty());
405 HttpRequestHeaders authorization_headers; 402 HttpRequestHeaders authorization_headers;
406 if (auth_->HaveAuth()) 403 if (auth_->HaveAuth())
407 auth_->AddAuthorizationHeader(&authorization_headers); 404 auth_->AddAuthorizationHeader(&authorization_headers);
408 BuildTunnelRequest(request_, authorization_headers, endpoint_, 405 BuildTunnelRequest(request_,
409 &request_line_, &request_headers_); 406 authorization_headers,
407 endpoint_,
408 &request_line_,
409 &request_headers_);
410 410
411 net_log_.AddEvent( 411 net_log_.AddEvent(NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
412 NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS, 412 base::Bind(&HttpRequestHeaders::NetLogCallback,
413 base::Bind(&HttpRequestHeaders::NetLogCallback, 413 base::Unretained(&request_headers_),
414 base::Unretained(&request_headers_), 414 &request_line_));
415 &request_line_));
416 } 415 }
417 416
418 parser_buf_ = new GrowableIOBuffer(); 417 parser_buf_ = new GrowableIOBuffer();
419 http_stream_parser_.reset(new HttpStreamParser( 418 http_stream_parser_.reset(new HttpStreamParser(
420 transport_.get(), &request_, parser_buf_.get(), net_log_)); 419 transport_.get(), &request_, parser_buf_.get(), net_log_));
421 return http_stream_parser_->SendRequest( 420 return http_stream_parser_->SendRequest(
422 request_line_, request_headers_, &response_, io_callback_); 421 request_line_, request_headers_, &response_, io_callback_);
423 } 422 }
424 423
425 int HttpProxyClientSocket::DoSendRequestComplete(int result) { 424 int HttpProxyClientSocket::DoSendRequestComplete(int result) {
(...skipping 23 matching lines...) Expand all
449 448
450 switch (response_.headers->response_code()) { 449 switch (response_.headers->response_code()) {
451 case 200: // OK 450 case 200: // OK
452 if (http_stream_parser_->IsMoreDataBuffered()) 451 if (http_stream_parser_->IsMoreDataBuffered())
453 // The proxy sent extraneous data after the headers. 452 // The proxy sent extraneous data after the headers.
454 return ERR_TUNNEL_CONNECTION_FAILED; 453 return ERR_TUNNEL_CONNECTION_FAILED;
455 454
456 next_state_ = STATE_DONE; 455 next_state_ = STATE_DONE;
457 return OK; 456 return OK;
458 457
459 // We aren't able to CONNECT to the remote host through the proxy. We 458 // We aren't able to CONNECT to the remote host through the proxy. We
460 // need to be very suspicious about the response because an active network 459 // need to be very suspicious about the response because an active network
461 // attacker can force us into this state by masquerading as the proxy. 460 // attacker can force us into this state by masquerading as the proxy.
462 // The only safe thing to do here is to fail the connection because our 461 // The only safe thing to do here is to fail the connection because our
463 // client is expecting an SSL protected response. 462 // client is expecting an SSL protected response.
464 // See http://crbug.com/7338. 463 // See http://crbug.com/7338.
465 464
466 case 302: // Found / Moved Temporarily 465 case 302: // Found / Moved Temporarily
467 // Attempt to follow redirects from HTTPS proxies, but only if we can 466 // Attempt to follow redirects from HTTPS proxies, but only if we can
468 // sanitize the response. This still allows a rogue HTTPS proxy to 467 // sanitize the response. This still allows a rogue HTTPS proxy to
469 // redirect an HTTPS site load to a similar-looking site, but no longer 468 // redirect an HTTPS site load to a similar-looking site, but no longer
470 // allows it to impersonate the site the user requested. 469 // allows it to impersonate the site the user requested.
471 if (is_https_proxy_ && SanitizeProxyRedirect(&response_, request_.url)) { 470 if (is_https_proxy_ && SanitizeProxyRedirect(&response_, request_.url)) {
472 bool is_connection_reused = http_stream_parser_->IsConnectionReused(); 471 bool is_connection_reused = http_stream_parser_->IsConnectionReused();
473 redirect_has_load_timing_info_ = 472 redirect_has_load_timing_info_ = transport_->GetLoadTimingInfo(
474 transport_->GetLoadTimingInfo( 473 is_connection_reused, &redirect_load_timing_info_);
475 is_connection_reused, &redirect_load_timing_info_);
476 transport_.reset(); 474 transport_.reset();
477 http_stream_parser_.reset(); 475 http_stream_parser_.reset();
478 return ERR_HTTPS_PROXY_TUNNEL_RESPONSE; 476 return ERR_HTTPS_PROXY_TUNNEL_RESPONSE;
479 } 477 }
480 478
481 // We're not using an HTTPS proxy, or we couldn't sanitize the redirect. 479 // We're not using an HTTPS proxy, or we couldn't sanitize the redirect.
482 LogBlockedTunnelResponse(); 480 LogBlockedTunnelResponse();
483 return ERR_TUNNEL_CONNECTION_FAILED; 481 return ERR_TUNNEL_CONNECTION_FAILED;
484 482
485 case 407: // Proxy Authentication Required 483 case 407: // Proxy Authentication Required
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
529 527
530 int HttpProxyClientSocket::DoTCPRestartComplete(int result) { 528 int HttpProxyClientSocket::DoTCPRestartComplete(int result) {
531 if (result != OK) 529 if (result != OK)
532 return result; 530 return result;
533 531
534 next_state_ = STATE_GENERATE_AUTH_TOKEN; 532 next_state_ = STATE_GENERATE_AUTH_TOKEN;
535 return result; 533 return result;
536 } 534 }
537 535
538 } // namespace net 536 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698