| OLD | NEW |
| 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/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" |
| (...skipping 21 matching lines...) Expand all Loading... |
| 32 HttpAuthCache* auth_cache, | 32 HttpAuthCache* auth_cache, |
| 33 HttpAuthHandlerFactory* auth_handler_factory) | 33 HttpAuthHandlerFactory* auth_handler_factory) |
| 34 : next_state_(STATE_DISCONNECTED), | 34 : next_state_(STATE_DISCONNECTED), |
| 35 spdy_stream_(spdy_stream), | 35 spdy_stream_(spdy_stream), |
| 36 endpoint_(endpoint), | 36 endpoint_(endpoint), |
| 37 auth_( | 37 auth_( |
| 38 new HttpAuthController(HttpAuth::AUTH_PROXY, | 38 new HttpAuthController(HttpAuth::AUTH_PROXY, |
| 39 GURL("https://" + proxy_server.ToString()), | 39 GURL("https://" + proxy_server.ToString()), |
| 40 auth_cache, | 40 auth_cache, |
| 41 auth_handler_factory)), | 41 auth_handler_factory)), |
| 42 user_buffer_len_(0), | 42 user_buffer_(NULL), |
| 43 write_buffer_len_(0), | 43 write_buffer_len_(0), |
| 44 write_bytes_outstanding_(0), | 44 write_bytes_outstanding_(0), |
| 45 ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)), | 45 ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)), |
| 46 net_log_(BoundNetLog::Make(spdy_stream->net_log().net_log(), | 46 net_log_(BoundNetLog::Make(spdy_stream->net_log().net_log(), |
| 47 NetLog::SOURCE_PROXY_CLIENT_SOCKET)) { | 47 NetLog::SOURCE_PROXY_CLIENT_SOCKET)) { |
| 48 request_.method = "CONNECT"; | 48 request_.method = "CONNECT"; |
| 49 request_.url = url; | 49 request_.url = url; |
| 50 if (!user_agent.empty()) | 50 if (!user_agent.empty()) |
| 51 request_.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent, | 51 request_.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent, |
| 52 user_agent); | 52 user_agent); |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 120 DCHECK_EQ(STATE_DISCONNECTED, next_state_); | 120 DCHECK_EQ(STATE_DISCONNECTED, next_state_); |
| 121 next_state_ = STATE_GENERATE_AUTH_TOKEN; | 121 next_state_ = STATE_GENERATE_AUTH_TOKEN; |
| 122 | 122 |
| 123 int rv = DoLoop(OK); | 123 int rv = DoLoop(OK); |
| 124 if (rv == ERR_IO_PENDING) | 124 if (rv == ERR_IO_PENDING) |
| 125 read_callback_ = callback; | 125 read_callback_ = callback; |
| 126 return rv; | 126 return rv; |
| 127 } | 127 } |
| 128 | 128 |
| 129 void SpdyProxyClientSocket::Disconnect() { | 129 void SpdyProxyClientSocket::Disconnect() { |
| 130 read_buffer_queue_.Clear(); | 130 read_buffer_.clear(); |
| 131 user_buffer_ = NULL; | 131 user_buffer_ = NULL; |
| 132 user_buffer_len_ = 0; | |
| 133 read_callback_.Reset(); | 132 read_callback_.Reset(); |
| 134 | 133 |
| 135 write_buffer_len_ = 0; | 134 write_buffer_len_ = 0; |
| 136 write_bytes_outstanding_ = 0; | 135 write_bytes_outstanding_ = 0; |
| 137 write_callback_.Reset(); | 136 write_callback_.Reset(); |
| 138 | 137 |
| 139 next_state_ = STATE_DISCONNECTED; | 138 next_state_ = STATE_DISCONNECTED; |
| 140 | 139 |
| 141 if (spdy_stream_) { | 140 if (spdy_stream_) { |
| 142 // This will cause OnClose to be invoked, which takes care of | 141 // This will cause OnClose to be invoked, which takes care of |
| 143 // cleaning up all the internal state. | 142 // cleaning up all the internal state. |
| 144 spdy_stream_->Cancel(); | 143 spdy_stream_->Cancel(); |
| 145 DCHECK(!spdy_stream_.get()); | 144 DCHECK(!spdy_stream_.get()); |
| 146 } | 145 } |
| 147 } | 146 } |
| 148 | 147 |
| 149 bool SpdyProxyClientSocket::IsConnected() const { | 148 bool SpdyProxyClientSocket::IsConnected() const { |
| 150 return next_state_ == STATE_OPEN; | 149 return next_state_ == STATE_OPEN; |
| 151 } | 150 } |
| 152 | 151 |
| 153 bool SpdyProxyClientSocket::IsConnectedAndIdle() const { | 152 bool SpdyProxyClientSocket::IsConnectedAndIdle() const { |
| 154 return IsConnected() && read_buffer_queue_.IsEmpty() && | 153 return IsConnected() && read_buffer_.empty() && spdy_stream_->is_idle(); |
| 155 spdy_stream_->is_idle(); | |
| 156 } | 154 } |
| 157 | 155 |
| 158 const BoundNetLog& SpdyProxyClientSocket::NetLog() const { | 156 const BoundNetLog& SpdyProxyClientSocket::NetLog() const { |
| 159 return net_log_; | 157 return net_log_; |
| 160 } | 158 } |
| 161 | 159 |
| 162 void SpdyProxyClientSocket::SetSubresourceSpeculation() { | 160 void SpdyProxyClientSocket::SetSubresourceSpeculation() { |
| 163 // TODO(rch): what should this implementation be? | 161 // TODO(rch): what should this implementation be? |
| 164 } | 162 } |
| 165 | 163 |
| (...skipping 25 matching lines...) Expand all Loading... |
| 191 } | 189 } |
| 192 | 190 |
| 193 int SpdyProxyClientSocket::Read(IOBuffer* buf, int buf_len, | 191 int SpdyProxyClientSocket::Read(IOBuffer* buf, int buf_len, |
| 194 const CompletionCallback& callback) { | 192 const CompletionCallback& callback) { |
| 195 DCHECK(read_callback_.is_null()); | 193 DCHECK(read_callback_.is_null()); |
| 196 DCHECK(!user_buffer_); | 194 DCHECK(!user_buffer_); |
| 197 | 195 |
| 198 if (next_state_ == STATE_DISCONNECTED) | 196 if (next_state_ == STATE_DISCONNECTED) |
| 199 return ERR_SOCKET_NOT_CONNECTED; | 197 return ERR_SOCKET_NOT_CONNECTED; |
| 200 | 198 |
| 201 if (next_state_ == STATE_CLOSED && read_buffer_queue_.IsEmpty()) { | 199 if (next_state_ == STATE_CLOSED && read_buffer_.empty()) { |
| 202 return 0; | 200 return 0; |
| 203 } | 201 } |
| 204 | 202 |
| 205 DCHECK(next_state_ == STATE_OPEN || next_state_ == STATE_CLOSED); | 203 DCHECK(next_state_ == STATE_OPEN || next_state_ == STATE_CLOSED); |
| 206 DCHECK(buf); | 204 DCHECK(buf); |
| 207 size_t result = PopulateUserReadBuffer(buf->data(), buf_len); | 205 user_buffer_ = new DrainableIOBuffer(buf, buf_len); |
| 206 int result = PopulateUserReadBuffer(); |
| 208 if (result == 0) { | 207 if (result == 0) { |
| 209 user_buffer_ = buf; | |
| 210 user_buffer_len_ = static_cast<size_t>(buf_len); | |
| 211 DCHECK(!callback.is_null()); | 208 DCHECK(!callback.is_null()); |
| 212 read_callback_ = callback; | 209 read_callback_ = callback; |
| 213 return ERR_IO_PENDING; | 210 return ERR_IO_PENDING; |
| 214 } | 211 } |
| 215 user_buffer_ = NULL; | 212 user_buffer_ = NULL; |
| 216 return result; | 213 return result; |
| 217 } | 214 } |
| 218 | 215 |
| 219 size_t SpdyProxyClientSocket::PopulateUserReadBuffer(char* data, size_t len) { | 216 int SpdyProxyClientSocket::PopulateUserReadBuffer() { |
| 220 size_t bytes_consumed = read_buffer_queue_.Dequeue(data, len); | 217 if (!user_buffer_) |
| 218 return ERR_IO_PENDING; |
| 221 | 219 |
| 222 if (bytes_consumed > 0 && spdy_stream_) | 220 int bytes_read = 0; |
| 223 spdy_stream_->IncreaseRecvWindowSize(bytes_consumed); | 221 while (!read_buffer_.empty() && user_buffer_->BytesRemaining() > 0) { |
| 222 scoped_refptr<DrainableIOBuffer> data = read_buffer_.front(); |
| 223 const int bytes_to_copy = std::min(user_buffer_->BytesRemaining(), |
| 224 data->BytesRemaining()); |
| 225 memcpy(user_buffer_->data(), data->data(), bytes_to_copy); |
| 226 user_buffer_->DidConsume(bytes_to_copy); |
| 227 bytes_read += bytes_to_copy; |
| 228 if (data->BytesRemaining() == bytes_to_copy) { |
| 229 // Consumed all data from this buffer |
| 230 read_buffer_.pop_front(); |
| 231 } else { |
| 232 data->DidConsume(bytes_to_copy); |
| 233 } |
| 234 } |
| 224 | 235 |
| 225 return bytes_consumed; | 236 if (bytes_read > 0 && spdy_stream_) |
| 237 spdy_stream_->IncreaseRecvWindowSize(bytes_read); |
| 238 |
| 239 return user_buffer_->BytesConsumed(); |
| 226 } | 240 } |
| 227 | 241 |
| 228 int SpdyProxyClientSocket::Write(IOBuffer* buf, int buf_len, | 242 int SpdyProxyClientSocket::Write(IOBuffer* buf, int buf_len, |
| 229 const CompletionCallback& callback) { | 243 const CompletionCallback& callback) { |
| 230 DCHECK(write_callback_.is_null()); | 244 DCHECK(write_callback_.is_null()); |
| 231 if (next_state_ != STATE_OPEN) | 245 if (next_state_ != STATE_OPEN) |
| 232 return ERR_SOCKET_NOT_CONNECTED; | 246 return ERR_SOCKET_NOT_CONNECTED; |
| 233 | 247 |
| 234 DCHECK(spdy_stream_); | 248 DCHECK(spdy_stream_); |
| 235 write_bytes_outstanding_= buf_len; | 249 write_bytes_outstanding_= buf_len; |
| (...skipping 269 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 505 | 519 |
| 506 OnIOComplete(status); | 520 OnIOComplete(status); |
| 507 return OK; | 521 return OK; |
| 508 } | 522 } |
| 509 | 523 |
| 510 void SpdyProxyClientSocket::OnHeadersSent() { | 524 void SpdyProxyClientSocket::OnHeadersSent() { |
| 511 // Proxy client sockets don't send any HEADERS frame. | 525 // Proxy client sockets don't send any HEADERS frame. |
| 512 NOTREACHED(); | 526 NOTREACHED(); |
| 513 } | 527 } |
| 514 | 528 |
| 515 // Called when data is received or on EOF (if |buffer| is NULL). | 529 // Called when data is received. |
| 516 int SpdyProxyClientSocket::OnDataReceived(scoped_ptr<SpdyBuffer> buffer) { | 530 int SpdyProxyClientSocket::OnDataReceived(const char* data, int length) { |
| 517 if (buffer) { | 531 net_log_.AddByteTransferEvent(NetLog::TYPE_SOCKET_BYTES_RECEIVED, |
| 518 net_log_.AddByteTransferEvent(NetLog::TYPE_SOCKET_BYTES_RECEIVED, | 532 length, data); |
| 519 buffer->GetRemainingSize(), | 533 if (length > 0) { |
| 520 buffer->GetRemainingData()); | 534 // Save the received data. |
| 521 read_buffer_queue_.Enqueue(buffer.Pass()); | 535 scoped_refptr<IOBuffer> io_buffer(new IOBuffer(length)); |
| 522 } else { | 536 memcpy(io_buffer->data(), data, length); |
| 523 net_log_.AddByteTransferEvent(NetLog::TYPE_SOCKET_BYTES_RECEIVED, 0, NULL); | 537 read_buffer_.push_back( |
| 538 make_scoped_refptr(new DrainableIOBuffer(io_buffer, length))); |
| 524 } | 539 } |
| 525 | 540 |
| 526 if (!read_callback_.is_null()) { | 541 if (!read_callback_.is_null()) { |
| 527 int rv = PopulateUserReadBuffer(user_buffer_->data(), user_buffer_len_); | 542 int rv = PopulateUserReadBuffer(); |
| 528 CompletionCallback c = read_callback_; | 543 CompletionCallback c = read_callback_; |
| 529 read_callback_.Reset(); | 544 read_callback_.Reset(); |
| 530 user_buffer_ = NULL; | 545 user_buffer_ = NULL; |
| 531 user_buffer_len_ = 0; | |
| 532 c.Run(rv); | 546 c.Run(rv); |
| 533 } | 547 } |
| 534 return OK; | 548 return OK; |
| 535 } | 549 } |
| 536 | 550 |
| 537 void SpdyProxyClientSocket::OnDataSent(size_t bytes_sent) { | 551 void SpdyProxyClientSocket::OnDataSent(size_t bytes_sent) { |
| 538 DCHECK(!write_callback_.is_null()); | 552 DCHECK(!write_callback_.is_null()); |
| 539 | 553 |
| 540 DCHECK_LE(static_cast<int>(bytes_sent), write_bytes_outstanding_); | 554 DCHECK_LE(static_cast<int>(bytes_sent), write_bytes_outstanding_); |
| 541 write_bytes_outstanding_ -= static_cast<int>(bytes_sent); | 555 write_bytes_outstanding_ -= static_cast<int>(bytes_sent); |
| (...skipping 28 matching lines...) Expand all Loading... |
| 570 | 584 |
| 571 // If we're in the middle of connecting, we need to make sure | 585 // If we're in the middle of connecting, we need to make sure |
| 572 // we invoke the connect callback. | 586 // we invoke the connect callback. |
| 573 if (connecting) { | 587 if (connecting) { |
| 574 DCHECK(!read_callback_.is_null()); | 588 DCHECK(!read_callback_.is_null()); |
| 575 CompletionCallback read_callback = read_callback_; | 589 CompletionCallback read_callback = read_callback_; |
| 576 read_callback_.Reset(); | 590 read_callback_.Reset(); |
| 577 read_callback.Run(status); | 591 read_callback.Run(status); |
| 578 } else if (!read_callback_.is_null()) { | 592 } else if (!read_callback_.is_null()) { |
| 579 // If we have a read_callback_, the we need to make sure we call it back. | 593 // If we have a read_callback_, the we need to make sure we call it back. |
| 580 OnDataReceived(scoped_ptr<SpdyBuffer>()); | 594 OnDataReceived(NULL, 0); |
| 581 } | 595 } |
| 582 // This may have been deleted by read_callback_, so check first. | 596 // This may have been deleted by read_callback_, so check first. |
| 583 if (weak_ptr && !write_callback.is_null()) | 597 if (weak_ptr && !write_callback.is_null()) |
| 584 write_callback.Run(ERR_CONNECTION_CLOSED); | 598 write_callback.Run(ERR_CONNECTION_CLOSED); |
| 585 } | 599 } |
| 586 | 600 |
| 587 } // namespace net | 601 } // namespace net |
| OLD | NEW |