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 |