Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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/spdy/spdy_proxy_client_socket.h" | 5 #include "net/spdy/spdy_proxy_client_socket.h" |
| 6 | 6 |
| 7 #include <algorithm> // min | 7 #include <algorithm> // min |
| 8 | 8 |
| 9 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/bind_helpers.h" | 10 #include "base/bind_helpers.h" |
| 11 #include "base/logging.h" | 11 #include "base/logging.h" |
| 12 #include "base/string_util.h" | 12 #include "base/string_util.h" |
| 13 #include "googleurl/src/gurl.h" | 13 #include "googleurl/src/gurl.h" |
| 14 #include "net/base/auth.h" | 14 #include "net/base/auth.h" |
| 15 #include "net/base/io_buffer.h" | 15 #include "net/base/io_buffer.h" |
| 16 #include "net/base/net_util.h" | 16 #include "net/base/net_util.h" |
| 17 #include "net/http/http_auth_cache.h" | |
| 18 #include "net/http/http_auth_handler_factory.h" | |
| 19 #include "net/http/http_net_log_params.h" | 17 #include "net/http/http_net_log_params.h" |
| 20 #include "net/http/http_proxy_utils.h" | 18 #include "net/http/http_proxy_utils.h" |
| 21 #include "net/http/http_response_headers.h" | 19 #include "net/http/http_response_headers.h" |
| 22 #include "net/spdy/spdy_http_utils.h" | 20 #include "net/spdy/spdy_http_utils.h" |
| 23 | 21 |
| 24 namespace net { | 22 namespace net { |
| 25 | 23 |
| 26 SpdyProxyClientSocket::SpdyProxyClientSocket( | 24 SpdyProxyClientSocket::SpdyProxyClientSocket( |
| 27 SpdyStream* spdy_stream, | 25 SpdyStream* spdy_stream, |
| 28 const std::string& user_agent, | 26 const std::string& user_agent, |
| 29 const HostPortPair& endpoint, | 27 const HostPortPair& endpoint, |
| 30 const GURL& url, | 28 const GURL& url, |
| 31 const HostPortPair& proxy_server, | 29 const HostPortPair& proxy_server, |
| 32 HttpAuthCache* auth_cache, | 30 HttpAuthController* http_auth_controller) |
| 33 HttpAuthHandlerFactory* auth_handler_factory) | |
| 34 : next_state_(STATE_DISCONNECTED), | 31 : next_state_(STATE_DISCONNECTED), |
| 35 spdy_stream_(spdy_stream), | 32 spdy_stream_(spdy_stream), |
| 36 endpoint_(endpoint), | 33 endpoint_(endpoint), |
| 37 auth_( | 34 auth_(http_auth_controller), |
| 38 new HttpAuthController(HttpAuth::AUTH_PROXY, | |
| 39 GURL("https://" + proxy_server.ToString()), | |
| 40 auth_cache, | |
| 41 auth_handler_factory)), | |
| 42 user_buffer_(NULL), | 35 user_buffer_(NULL), |
| 43 write_buffer_len_(0), | 36 write_buffer_len_(0), |
| 44 write_bytes_outstanding_(0), | 37 write_bytes_outstanding_(0), |
| 45 ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)), | 38 ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)), |
| 46 net_log_(spdy_stream->net_log()) { | 39 net_log_(spdy_stream->net_log()) { |
| 47 request_.method = "CONNECT"; | 40 request_.method = "CONNECT"; |
| 48 request_.url = url; | 41 request_.url = url; |
| 49 if (!user_agent.empty()) | 42 if (!user_agent.empty()) |
| 50 request_.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent, | 43 request_.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent, |
| 51 user_agent); | 44 user_agent); |
| 52 spdy_stream_->SetDelegate(this); | 45 spdy_stream_->SetDelegate(this); |
| 53 was_ever_used_ = spdy_stream_->WasEverUsed(); | 46 was_ever_used_ = spdy_stream_->WasEverUsed(); |
| 54 } | 47 } |
| 55 | 48 |
| 56 SpdyProxyClientSocket::~SpdyProxyClientSocket() { | 49 SpdyProxyClientSocket::~SpdyProxyClientSocket() { |
| 57 Disconnect(); | 50 Disconnect(); |
| 58 } | 51 } |
| 59 | 52 |
| 60 const HttpResponseInfo* SpdyProxyClientSocket::GetConnectResponseInfo() const { | 53 const HttpResponseInfo* SpdyProxyClientSocket::GetConnectResponseInfo() const { |
| 61 return response_.headers ? &response_ : NULL; | 54 return response_.headers ? &response_ : NULL; |
| 62 } | 55 } |
| 63 | 56 |
| 57 const | |
| 58 scoped_refptr<HttpAuthController>& SpdyProxyClientSocket::auth_controller() { | |
| 59 return auth_; | |
| 60 } | |
| 61 | |
| 62 int SpdyProxyClientSocket::RestartWithAuth(const CompletionCallback& callback) { | |
| 63 // A SPDY Stream can only handle a single request, so the underlying | |
| 64 // stream may not be reused and a new SpdyProxyClientSocket must be | |
| 65 // created (possibly on top of the same SPDY Session). | |
| 66 next_state_ = STATE_DISCONNECTED; | |
| 67 return OK; | |
|
vandebo (ex-Chrome)
2012/01/19 20:12:49
Same thing here - why return OK when the proxy poo
Ryan Hamilton
2012/01/19 23:11:19
Done.
| |
| 68 } | |
| 69 | |
| 64 HttpStream* SpdyProxyClientSocket::CreateConnectResponseStream() { | 70 HttpStream* SpdyProxyClientSocket::CreateConnectResponseStream() { |
| 65 DCHECK(response_stream_.get()); | 71 DCHECK(response_stream_.get()); |
| 66 return response_stream_.release(); | 72 return response_stream_.release(); |
| 67 } | 73 } |
| 68 | 74 |
| 69 // Sends a SYN_STREAM frame to the proxy with a CONNECT request | 75 // Sends a SYN_STREAM frame to the proxy with a CONNECT request |
| 70 // for the specified endpoint. Waits for the server to send back | 76 // for the specified endpoint. Waits for the server to send back |
| 71 // a SYN_REPLY frame. OK will be returned if the status is 200. | 77 // a SYN_REPLY frame. OK will be returned if the status is 200. |
| 72 // ERR_TUNNEL_CONNECTION_FAILED will be returned for any other status. | 78 // ERR_TUNNEL_CONNECTION_FAILED will be returned for any other status. |
| 73 // In any of these cases, Read() may be called to retrieve the HTTP | 79 // In any of these cases, Read() may be called to retrieve the HTTP |
| 74 // response body. Any other return values should be considered fatal. | 80 // response body. Any other return values should be considered fatal. |
| 75 // TODO(rch): handle 407 proxy auth requested correctly, perhaps | 81 // TODO(rch): handle 407 proxy auth requested correctly, perhaps |
|
vandebo (ex-Chrome)
2012/01/19 20:12:49
Is this TODO now handled?
Ryan Hamilton
2012/01/19 23:11:19
Done. Yes, I've removed the todo.
| |
| 76 // by creating a new stream for the subsequent request. | 82 // by creating a new stream for the subsequent request. |
| 77 // TODO(rch): create a more appropriate error code to disambiguate | 83 // TODO(rch): create a more appropriate error code to disambiguate |
| 78 // the HTTPS Proxy tunnel failure from an HTTP Proxy tunnel failure. | 84 // the HTTPS Proxy tunnel failure from an HTTP Proxy tunnel failure. |
| 79 int SpdyProxyClientSocket::Connect(const CompletionCallback& callback) { | 85 int SpdyProxyClientSocket::Connect(const CompletionCallback& callback) { |
| 80 DCHECK(read_callback_.is_null()); | 86 DCHECK(read_callback_.is_null()); |
| 81 if (next_state_ == STATE_OPEN) | 87 if (next_state_ == STATE_OPEN) |
| 82 return OK; | 88 return OK; |
| 83 | 89 |
| 84 DCHECK_EQ(STATE_DISCONNECTED, next_state_); | 90 DCHECK_EQ(STATE_DISCONNECTED, next_state_); |
| 85 next_state_ = STATE_GENERATE_AUTH_TOKEN; | 91 next_state_ = STATE_GENERATE_AUTH_TOKEN; |
| (...skipping 286 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 372 next_state_ = STATE_OPEN; | 378 next_state_ = STATE_OPEN; |
| 373 if (net_log_.IsLoggingAllEvents()) { | 379 if (net_log_.IsLoggingAllEvents()) { |
| 374 net_log_.AddEvent( | 380 net_log_.AddEvent( |
| 375 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS, | 381 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS, |
| 376 make_scoped_refptr(new NetLogHttpResponseParameter(response_.headers))); | 382 make_scoped_refptr(new NetLogHttpResponseParameter(response_.headers))); |
| 377 } | 383 } |
| 378 | 384 |
| 379 if (response_.headers->response_code() == 200) { | 385 if (response_.headers->response_code() == 200) { |
| 380 return OK; | 386 return OK; |
| 381 } else if (response_.headers->response_code() == 407) { | 387 } else if (response_.headers->response_code() == 407) { |
| 388 int rv = HandleAuthChallenge(auth_, &response_, net_log_); | |
| 389 if (rv != ERR_PROXY_AUTH_REQUESTED) { | |
| 390 return rv; | |
| 391 } | |
| 392 // SPDY only supports basic and digest auth | |
| 393 if (auth_->auth_info() && | |
| 394 (auth_->auth_info()->scheme == "basic" || | |
| 395 auth_->auth_info()->scheme == "digest")) { | |
| 396 return ERR_PROXY_AUTH_REQUESTED; | |
| 397 } | |
| 382 return ERR_TUNNEL_CONNECTION_FAILED; | 398 return ERR_TUNNEL_CONNECTION_FAILED; |
| 383 } else { | 399 } else { |
| 384 // Immediately hand off our SpdyStream to a newly created SpdyHttpStream | 400 // Immediately hand off our SpdyStream to a newly created SpdyHttpStream |
| 385 // so that any subsequent SpdyFrames are processed in the context of | 401 // so that any subsequent SpdyFrames are processed in the context of |
| 386 // the HttpStream, not the socket. | 402 // the HttpStream, not the socket. |
| 387 DCHECK(spdy_stream_); | 403 DCHECK(spdy_stream_); |
| 388 SpdyStream* stream = spdy_stream_; | 404 SpdyStream* stream = spdy_stream_; |
| 389 spdy_stream_ = NULL; | 405 spdy_stream_ = NULL; |
| 390 response_stream_.reset(new SpdyHttpStream(NULL, false)); | 406 response_stream_.reset(new SpdyHttpStream(NULL, false)); |
| 391 response_stream_->InitializeWithExistingStream(stream); | 407 response_stream_->InitializeWithExistingStream(stream); |
| (...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 507 } | 523 } |
| 508 // This may have been deleted by read_callback_, so check first. | 524 // This may have been deleted by read_callback_, so check first. |
| 509 if (weak_ptr && !write_callback.is_null()) | 525 if (weak_ptr && !write_callback.is_null()) |
| 510 write_callback.Run(ERR_CONNECTION_CLOSED); | 526 write_callback.Run(ERR_CONNECTION_CLOSED); |
| 511 } | 527 } |
| 512 | 528 |
| 513 void SpdyProxyClientSocket::set_chunk_callback(ChunkCallback* /*callback*/) { | 529 void SpdyProxyClientSocket::set_chunk_callback(ChunkCallback* /*callback*/) { |
| 514 } | 530 } |
| 515 | 531 |
| 516 } // namespace net | 532 } // namespace net |
| OLD | NEW |