| 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/logging.h" | 9 #include "base/logging.h" |
| 10 #include "base/string_util.h" | 10 #include "base/string_util.h" |
| (...skipping 15 matching lines...) Expand all Loading... |
| 26 const std::string& user_agent, | 26 const std::string& user_agent, |
| 27 const HostPortPair& endpoint, | 27 const HostPortPair& endpoint, |
| 28 const GURL& url, | 28 const GURL& url, |
| 29 const HostPortPair& proxy_server, | 29 const HostPortPair& proxy_server, |
| 30 HttpAuthCache* auth_cache, | 30 HttpAuthCache* auth_cache, |
| 31 HttpAuthHandlerFactory* auth_handler_factory) | 31 HttpAuthHandlerFactory* auth_handler_factory) |
| 32 : ALLOW_THIS_IN_INITIALIZER_LIST( | 32 : ALLOW_THIS_IN_INITIALIZER_LIST( |
| 33 io_callback_(this, &SpdyProxyClientSocket::OnIOComplete)), | 33 io_callback_(this, &SpdyProxyClientSocket::OnIOComplete)), |
| 34 next_state_(STATE_DISCONNECTED), | 34 next_state_(STATE_DISCONNECTED), |
| 35 spdy_stream_(spdy_stream), | 35 spdy_stream_(spdy_stream), |
| 36 read_callback_(NULL), | 36 old_read_callback_(NULL), |
| 37 write_callback_(NULL), | 37 write_callback_(NULL), |
| 38 endpoint_(endpoint), | 38 endpoint_(endpoint), |
| 39 auth_( | 39 auth_( |
| 40 new HttpAuthController(HttpAuth::AUTH_PROXY, | 40 new HttpAuthController(HttpAuth::AUTH_PROXY, |
| 41 GURL("https://" + proxy_server.ToString()), | 41 GURL("https://" + proxy_server.ToString()), |
| 42 auth_cache, | 42 auth_cache, |
| 43 auth_handler_factory)), | 43 auth_handler_factory)), |
| 44 user_buffer_(NULL), | 44 user_buffer_(NULL), |
| 45 write_buffer_len_(0), | 45 write_buffer_len_(0), |
| 46 write_bytes_outstanding_(0), | 46 write_bytes_outstanding_(0), |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 85 // for the specified endpoint. Waits for the server to send back | 85 // for the specified endpoint. Waits for the server to send back |
| 86 // a SYN_REPLY frame. OK will be returned if the status is 200. | 86 // a SYN_REPLY frame. OK will be returned if the status is 200. |
| 87 // ERR_TUNNEL_CONNECTION_FAILED will be returned for any other status. | 87 // ERR_TUNNEL_CONNECTION_FAILED will be returned for any other status. |
| 88 // In any of these cases, Read() may be called to retrieve the HTTP | 88 // In any of these cases, Read() may be called to retrieve the HTTP |
| 89 // response body. Any other return values should be considered fatal. | 89 // response body. Any other return values should be considered fatal. |
| 90 // TODO(rch): handle 407 proxy auth requested correctly, perhaps | 90 // TODO(rch): handle 407 proxy auth requested correctly, perhaps |
| 91 // by creating a new stream for the subsequent request. | 91 // by creating a new stream for the subsequent request. |
| 92 // TODO(rch): create a more appropriate error code to disambiguate | 92 // TODO(rch): create a more appropriate error code to disambiguate |
| 93 // the HTTPS Proxy tunnel failure from an HTTP Proxy tunnel failure. | 93 // the HTTPS Proxy tunnel failure from an HTTP Proxy tunnel failure. |
| 94 int SpdyProxyClientSocket::Connect(OldCompletionCallback* callback) { | 94 int SpdyProxyClientSocket::Connect(OldCompletionCallback* callback) { |
| 95 DCHECK(!read_callback_); | 95 DCHECK(!old_read_callback_ && read_callback_.is_null()); |
| 96 if (next_state_ == STATE_OPEN) | 96 if (next_state_ == STATE_OPEN) |
| 97 return OK; | 97 return OK; |
| 98 | 98 |
| 99 DCHECK_EQ(STATE_DISCONNECTED, next_state_); |
| 100 next_state_ = STATE_GENERATE_AUTH_TOKEN; |
| 101 |
| 102 int rv = DoLoop(OK); |
| 103 if (rv == ERR_IO_PENDING) |
| 104 old_read_callback_ = callback; |
| 105 return rv; |
| 106 } |
| 107 int SpdyProxyClientSocket::Connect(const CompletionCallback& callback) { |
| 108 DCHECK(!old_read_callback_ && read_callback_.is_null()); |
| 109 if (next_state_ == STATE_OPEN) |
| 110 return OK; |
| 111 |
| 99 DCHECK_EQ(STATE_DISCONNECTED, next_state_); | 112 DCHECK_EQ(STATE_DISCONNECTED, next_state_); |
| 100 next_state_ = STATE_GENERATE_AUTH_TOKEN; | 113 next_state_ = STATE_GENERATE_AUTH_TOKEN; |
| 101 | 114 |
| 102 int rv = DoLoop(OK); | 115 int rv = DoLoop(OK); |
| 103 if (rv == ERR_IO_PENDING) | 116 if (rv == ERR_IO_PENDING) |
| 104 read_callback_ = callback; | 117 read_callback_ = callback; |
| 105 return rv; | 118 return rv; |
| 106 } | 119 } |
| 107 | 120 |
| 108 void SpdyProxyClientSocket::Disconnect() { | 121 void SpdyProxyClientSocket::Disconnect() { |
| 109 read_buffer_.clear(); | 122 read_buffer_.clear(); |
| 110 user_buffer_ = NULL; | 123 user_buffer_ = NULL; |
| 111 read_callback_ = NULL; | 124 old_read_callback_ = NULL; |
| 125 read_callback_.Reset(); |
| 112 | 126 |
| 113 write_buffer_len_ = 0; | 127 write_buffer_len_ = 0; |
| 114 write_bytes_outstanding_ = 0; | 128 write_bytes_outstanding_ = 0; |
| 115 write_callback_ = NULL; | 129 write_callback_ = NULL; |
| 116 | 130 |
| 117 next_state_ = STATE_DISCONNECTED; | 131 next_state_ = STATE_DISCONNECTED; |
| 118 | 132 |
| 119 if (spdy_stream_) | 133 if (spdy_stream_) |
| 120 // This will cause OnClose to be invoked, which takes care of | 134 // This will cause OnClose to be invoked, which takes care of |
| 121 // cleaning up all the internal state. | 135 // cleaning up all the internal state. |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 153 int64 SpdyProxyClientSocket::NumBytesRead() const { | 167 int64 SpdyProxyClientSocket::NumBytesRead() const { |
| 154 return -1; | 168 return -1; |
| 155 } | 169 } |
| 156 | 170 |
| 157 base::TimeDelta SpdyProxyClientSocket::GetConnectTimeMicros() const { | 171 base::TimeDelta SpdyProxyClientSocket::GetConnectTimeMicros() const { |
| 158 return base::TimeDelta::FromMicroseconds(-1); | 172 return base::TimeDelta::FromMicroseconds(-1); |
| 159 } | 173 } |
| 160 | 174 |
| 161 int SpdyProxyClientSocket::Read(IOBuffer* buf, int buf_len, | 175 int SpdyProxyClientSocket::Read(IOBuffer* buf, int buf_len, |
| 162 OldCompletionCallback* callback) { | 176 OldCompletionCallback* callback) { |
| 163 DCHECK(!read_callback_); | 177 DCHECK(!old_read_callback_ && read_callback_.is_null()); |
| 164 DCHECK(!user_buffer_); | 178 DCHECK(!user_buffer_); |
| 165 | 179 |
| 166 if (next_state_ == STATE_DISCONNECTED) | 180 if (next_state_ == STATE_DISCONNECTED) |
| 167 return ERR_SOCKET_NOT_CONNECTED; | 181 return ERR_SOCKET_NOT_CONNECTED; |
| 168 | 182 |
| 169 if (next_state_ == STATE_CLOSED && read_buffer_.empty()) { | 183 if (next_state_ == STATE_CLOSED && read_buffer_.empty()) { |
| 170 return 0; | 184 return 0; |
| 171 } | 185 } |
| 172 | 186 |
| 173 DCHECK(next_state_ == STATE_OPEN || next_state_ == STATE_CLOSED); | 187 DCHECK(next_state_ == STATE_OPEN || next_state_ == STATE_CLOSED); |
| 174 DCHECK(buf); | 188 DCHECK(buf); |
| 175 user_buffer_ = new DrainableIOBuffer(buf, buf_len); | 189 user_buffer_ = new DrainableIOBuffer(buf, buf_len); |
| 176 int result = PopulateUserReadBuffer(); | 190 int result = PopulateUserReadBuffer(); |
| 177 if (result == 0) { | 191 if (result == 0) { |
| 178 DCHECK(callback); | 192 DCHECK(callback); |
| 179 read_callback_ = callback; | 193 old_read_callback_ = callback; |
| 180 return ERR_IO_PENDING; | 194 return ERR_IO_PENDING; |
| 181 } | 195 } |
| 182 user_buffer_ = NULL; | 196 user_buffer_ = NULL; |
| 183 return result; | 197 return result; |
| 184 } | 198 } |
| 185 | 199 |
| 186 int SpdyProxyClientSocket::PopulateUserReadBuffer() { | 200 int SpdyProxyClientSocket::PopulateUserReadBuffer() { |
| 187 if (!user_buffer_) | 201 if (!user_buffer_) |
| 188 return ERR_IO_PENDING; | 202 return ERR_IO_PENDING; |
| 189 | 203 |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 264 int SpdyProxyClientSocket::GetLocalAddress(IPEndPoint* address) const { | 278 int SpdyProxyClientSocket::GetLocalAddress(IPEndPoint* address) const { |
| 265 if (!IsConnected()) | 279 if (!IsConnected()) |
| 266 return ERR_SOCKET_NOT_CONNECTED; | 280 return ERR_SOCKET_NOT_CONNECTED; |
| 267 return spdy_stream_->GetLocalAddress(address); | 281 return spdy_stream_->GetLocalAddress(address); |
| 268 } | 282 } |
| 269 | 283 |
| 270 void SpdyProxyClientSocket::OnIOComplete(int result) { | 284 void SpdyProxyClientSocket::OnIOComplete(int result) { |
| 271 DCHECK_NE(STATE_DISCONNECTED, next_state_); | 285 DCHECK_NE(STATE_DISCONNECTED, next_state_); |
| 272 int rv = DoLoop(result); | 286 int rv = DoLoop(result); |
| 273 if (rv != ERR_IO_PENDING) { | 287 if (rv != ERR_IO_PENDING) { |
| 274 OldCompletionCallback* c = read_callback_; | 288 if (old_read_callback_) { |
| 275 read_callback_ = NULL; | 289 OldCompletionCallback* c = old_read_callback_; |
| 276 c->Run(rv); | 290 old_read_callback_ = NULL; |
| 291 c->Run(rv); |
| 292 } else { |
| 293 CompletionCallback c = read_callback_; |
| 294 read_callback_.Reset(); |
| 295 c.Run(rv); |
| 296 } |
| 277 } | 297 } |
| 278 } | 298 } |
| 279 | 299 |
| 280 int SpdyProxyClientSocket::DoLoop(int last_io_result) { | 300 int SpdyProxyClientSocket::DoLoop(int last_io_result) { |
| 281 DCHECK_NE(next_state_, STATE_DISCONNECTED); | 301 DCHECK_NE(next_state_, STATE_DISCONNECTED); |
| 282 int rv = last_io_result; | 302 int rv = last_io_result; |
| 283 do { | 303 do { |
| 284 State state = next_state_; | 304 State state = next_state_; |
| 285 next_state_ = STATE_DISCONNECTED; | 305 next_state_ = STATE_DISCONNECTED; |
| 286 switch (state) { | 306 switch (state) { |
| (...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 465 // Called when data is received. | 485 // Called when data is received. |
| 466 void SpdyProxyClientSocket::OnDataReceived(const char* data, int length) { | 486 void SpdyProxyClientSocket::OnDataReceived(const char* data, int length) { |
| 467 if (length > 0) { | 487 if (length > 0) { |
| 468 // Save the received data. | 488 // Save the received data. |
| 469 scoped_refptr<IOBuffer> io_buffer(new IOBuffer(length)); | 489 scoped_refptr<IOBuffer> io_buffer(new IOBuffer(length)); |
| 470 memcpy(io_buffer->data(), data, length); | 490 memcpy(io_buffer->data(), data, length); |
| 471 read_buffer_.push_back( | 491 read_buffer_.push_back( |
| 472 make_scoped_refptr(new DrainableIOBuffer(io_buffer, length))); | 492 make_scoped_refptr(new DrainableIOBuffer(io_buffer, length))); |
| 473 } | 493 } |
| 474 | 494 |
| 475 if (read_callback_) { | 495 if (old_read_callback_) { |
| 476 int rv = PopulateUserReadBuffer(); | 496 int rv = PopulateUserReadBuffer(); |
| 477 OldCompletionCallback* c = read_callback_; | 497 OldCompletionCallback* c = old_read_callback_; |
| 478 read_callback_ = NULL; | 498 old_read_callback_ = NULL; |
| 479 user_buffer_ = NULL; | 499 user_buffer_ = NULL; |
| 480 c->Run(rv); | 500 c->Run(rv); |
| 501 } else if (!read_callback_.is_null()) { |
| 502 int rv = PopulateUserReadBuffer(); |
| 503 CompletionCallback c = read_callback_; |
| 504 read_callback_.Reset(); |
| 505 user_buffer_ = NULL; |
| 506 c.Run(rv); |
| 481 } | 507 } |
| 482 } | 508 } |
| 483 | 509 |
| 484 void SpdyProxyClientSocket::OnDataSent(int length) { | 510 void SpdyProxyClientSocket::OnDataSent(int length) { |
| 485 DCHECK(write_callback_); | 511 DCHECK(write_callback_); |
| 486 | 512 |
| 487 write_bytes_outstanding_ -= length; | 513 write_bytes_outstanding_ -= length; |
| 488 | 514 |
| 489 DCHECK_GE(write_bytes_outstanding_, 0); | 515 DCHECK_GE(write_bytes_outstanding_, 0); |
| 490 | 516 |
| (...skipping 21 matching lines...) Expand all Loading... |
| 512 | 538 |
| 513 base::WeakPtr<SpdyProxyClientSocket> weak_ptr = weak_factory_.GetWeakPtr(); | 539 base::WeakPtr<SpdyProxyClientSocket> weak_ptr = weak_factory_.GetWeakPtr(); |
| 514 OldCompletionCallback* write_callback = write_callback_; | 540 OldCompletionCallback* write_callback = write_callback_; |
| 515 write_callback_ = NULL; | 541 write_callback_ = NULL; |
| 516 write_buffer_len_ = 0; | 542 write_buffer_len_ = 0; |
| 517 write_bytes_outstanding_ = 0; | 543 write_bytes_outstanding_ = 0; |
| 518 | 544 |
| 519 // If we're in the middle of connecting, we need to make sure | 545 // If we're in the middle of connecting, we need to make sure |
| 520 // we invoke the connect callback. | 546 // we invoke the connect callback. |
| 521 if (connecting) { | 547 if (connecting) { |
| 522 DCHECK(read_callback_); | 548 DCHECK(old_read_callback_ || !read_callback_.is_null()); |
| 523 OldCompletionCallback* read_callback = read_callback_; | 549 if (old_read_callback_) { |
| 524 read_callback_ = NULL; | 550 OldCompletionCallback* read_callback = old_read_callback_; |
| 525 read_callback->Run(status); | 551 old_read_callback_ = NULL; |
| 526 } else if (read_callback_) { | 552 read_callback->Run(status); |
| 553 } else { |
| 554 CompletionCallback read_callback = read_callback_; |
| 555 read_callback_.Reset(); |
| 556 read_callback.Run(status); |
| 557 } |
| 558 } else if (old_read_callback_ || !read_callback_.is_null()) { |
| 527 // If we have a read_callback_, the we need to make sure we call it back. | 559 // If we have a read_callback_, the we need to make sure we call it back. |
| 528 OnDataReceived(NULL, 0); | 560 OnDataReceived(NULL, 0); |
| 529 } | 561 } |
| 530 // This may have been deleted by read_callback_, so check first. | 562 // This may have been deleted by read_callback_, so check first. |
| 531 if (weak_ptr && write_callback) | 563 if (weak_ptr && write_callback) |
| 532 write_callback->Run(ERR_CONNECTION_CLOSED); | 564 write_callback->Run(ERR_CONNECTION_CLOSED); |
| 533 } | 565 } |
| 534 | 566 |
| 535 void SpdyProxyClientSocket::set_chunk_callback(ChunkCallback* /*callback*/) { | 567 void SpdyProxyClientSocket::set_chunk_callback(ChunkCallback* /*callback*/) { |
| 536 } | 568 } |
| 537 | 569 |
| 538 } // namespace net | 570 } // namespace net |
| OLD | NEW |