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