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 23 matching lines...) Expand all Loading... | |
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_len_(0), |
43 write_buffer_len_(0), | 43 write_buffer_len_(0), |
44 write_bytes_outstanding_(0), | |
45 weak_factory_(this), | 44 weak_factory_(this), |
46 net_log_(BoundNetLog::Make(spdy_stream->net_log().net_log(), | 45 net_log_(BoundNetLog::Make(spdy_stream->net_log().net_log(), |
47 NetLog::SOURCE_PROXY_CLIENT_SOCKET)) { | 46 NetLog::SOURCE_PROXY_CLIENT_SOCKET)) { |
48 request_.method = "CONNECT"; | 47 request_.method = "CONNECT"; |
49 request_.url = url; | 48 request_.url = url; |
50 if (!user_agent.empty()) | 49 if (!user_agent.empty()) |
51 request_.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent, | 50 request_.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent, |
52 user_agent); | 51 user_agent); |
53 | 52 |
54 net_log_.BeginEvent(NetLog::TYPE_SOCKET_ALIVE, | 53 net_log_.BeginEvent(NetLog::TYPE_SOCKET_ALIVE, |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
126 return rv; | 125 return rv; |
127 } | 126 } |
128 | 127 |
129 void SpdyProxyClientSocket::Disconnect() { | 128 void SpdyProxyClientSocket::Disconnect() { |
130 read_buffer_queue_.Clear(); | 129 read_buffer_queue_.Clear(); |
131 user_buffer_ = NULL; | 130 user_buffer_ = NULL; |
132 user_buffer_len_ = 0; | 131 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; | |
137 write_callback_.Reset(); | 135 write_callback_.Reset(); |
138 | 136 |
139 next_state_ = STATE_DISCONNECTED; | 137 next_state_ = STATE_DISCONNECTED; |
140 | 138 |
141 if (spdy_stream_) { | 139 if (spdy_stream_) { |
142 // This will cause OnClose to be invoked, which takes care of | 140 // This will cause OnClose to be invoked, which takes care of |
143 // cleaning up all the internal state. | 141 // cleaning up all the internal state. |
144 spdy_stream_->Cancel(); | 142 spdy_stream_->Cancel(); |
145 DCHECK(!spdy_stream_); | 143 DCHECK(!spdy_stream_); |
146 } | 144 } |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
220 return read_buffer_queue_.Dequeue(data, len); | 218 return read_buffer_queue_.Dequeue(data, len); |
221 } | 219 } |
222 | 220 |
223 int SpdyProxyClientSocket::Write(IOBuffer* buf, int buf_len, | 221 int SpdyProxyClientSocket::Write(IOBuffer* buf, int buf_len, |
224 const CompletionCallback& callback) { | 222 const CompletionCallback& callback) { |
225 DCHECK(write_callback_.is_null()); | 223 DCHECK(write_callback_.is_null()); |
226 if (next_state_ != STATE_OPEN) | 224 if (next_state_ != STATE_OPEN) |
227 return ERR_SOCKET_NOT_CONNECTED; | 225 return ERR_SOCKET_NOT_CONNECTED; |
228 | 226 |
229 DCHECK(spdy_stream_); | 227 DCHECK(spdy_stream_); |
230 write_bytes_outstanding_= buf_len; | 228 spdy_stream_->SendStreamData(buf, buf_len, DATA_FLAG_NONE); |
231 if (buf_len <= kMaxSpdyFrameChunkSize) { | 229 net_log_.AddByteTransferEvent(NetLog::TYPE_SOCKET_BYTES_SENT, |
232 spdy_stream_->QueueStreamData(buf, buf_len, DATA_FLAG_NONE); | 230 buf_len, buf->data()); |
233 net_log_.AddByteTransferEvent(NetLog::TYPE_SOCKET_BYTES_SENT, | 231 write_callback_ = callback; |
234 buf_len, buf->data()); | 232 write_buffer_len_ = buf_len; |
235 write_callback_ = callback; | 233 return ERR_IO_PENDING; |
236 write_buffer_len_ = buf_len; | |
237 return ERR_IO_PENDING; | |
238 } | |
239 | |
240 // Since a SPDY Data frame can only include kMaxSpdyFrameChunkSize bytes | |
241 // we need to send multiple data frames | |
Ryan Hamilton
2013/05/23 04:12:00
I gather we no longer need this logic because it's
akalin
2013/05/23 05:29:38
Yeap, that's right.
| |
242 for (int i = 0; i < buf_len; i += kMaxSpdyFrameChunkSize) { | |
243 int len = std::min(kMaxSpdyFrameChunkSize, buf_len - i); | |
244 scoped_refptr<DrainableIOBuffer> iobuf(new DrainableIOBuffer(buf, i + len)); | |
245 iobuf->SetOffset(i); | |
246 spdy_stream_->QueueStreamData(iobuf, len, DATA_FLAG_NONE); | |
247 net_log_.AddByteTransferEvent(NetLog::TYPE_SOCKET_BYTES_SENT, | |
248 len, buf->data()); | |
249 } | |
250 if (write_bytes_outstanding_ > 0) { | |
251 write_callback_ = callback; | |
252 write_buffer_len_ = buf_len; | |
253 return ERR_IO_PENDING; | |
254 } else { | |
255 return buf_len; | |
256 } | |
257 } | 234 } |
258 | 235 |
259 bool SpdyProxyClientSocket::SetReceiveBufferSize(int32 size) { | 236 bool SpdyProxyClientSocket::SetReceiveBufferSize(int32 size) { |
260 // Since this StreamSocket sits on top of a shared SpdySession, it | 237 // Since this StreamSocket sits on top of a shared SpdySession, it |
261 // is not safe for callers to set change this underlying socket. | 238 // is not safe for callers to set change this underlying socket. |
262 return false; | 239 return false; |
263 } | 240 } |
264 | 241 |
265 bool SpdyProxyClientSocket::SetSendBufferSize(int32 size) { | 242 bool SpdyProxyClientSocket::SetSendBufferSize(int32 size) { |
266 // Since this StreamSocket sits on top of a shared SpdySession, it | 243 // Since this StreamSocket sits on top of a shared SpdySession, it |
(...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
467 // STATE_OPEN (ala WebSockets). | 444 // STATE_OPEN (ala WebSockets). |
468 return NO_MORE_DATA_TO_SEND; | 445 return NO_MORE_DATA_TO_SEND; |
469 } | 446 } |
470 | 447 |
471 void SpdyProxyClientSocket::OnSendBody() { | 448 void SpdyProxyClientSocket::OnSendBody() { |
472 // Because we use |spdy_stream_| via STATE_OPEN (ala WebSockets) | 449 // Because we use |spdy_stream_| via STATE_OPEN (ala WebSockets) |
473 // OnSendBody() must never be called. | 450 // OnSendBody() must never be called. |
474 CHECK(false); | 451 CHECK(false); |
475 } | 452 } |
476 | 453 |
477 SpdySendStatus SpdyProxyClientSocket::OnSendBodyComplete( | 454 SpdySendStatus SpdyProxyClientSocket::OnSendBodyComplete() { |
478 size_t /*bytes_sent*/) { | |
479 // Because we use |spdy_stream_| via STATE_OPEN (ala WebSockets) | 455 // Because we use |spdy_stream_| via STATE_OPEN (ala WebSockets) |
480 // OnSendBodyComplete() must never be called. | 456 // OnSendBodyComplete() must never be called. |
481 CHECK(false); | 457 CHECK(false); |
482 return NO_MORE_DATA_TO_SEND; | 458 return NO_MORE_DATA_TO_SEND; |
483 } | 459 } |
484 | 460 |
485 int SpdyProxyClientSocket::OnResponseReceived( | 461 int SpdyProxyClientSocket::OnResponseReceived( |
486 const SpdyHeaderBlock& response, | 462 const SpdyHeaderBlock& response, |
487 base::Time response_time, | 463 base::Time response_time, |
488 int status) { | 464 int status) { |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
521 int rv = PopulateUserReadBuffer(user_buffer_->data(), user_buffer_len_); | 497 int rv = PopulateUserReadBuffer(user_buffer_->data(), user_buffer_len_); |
522 CompletionCallback c = read_callback_; | 498 CompletionCallback c = read_callback_; |
523 read_callback_.Reset(); | 499 read_callback_.Reset(); |
524 user_buffer_ = NULL; | 500 user_buffer_ = NULL; |
525 user_buffer_len_ = 0; | 501 user_buffer_len_ = 0; |
526 c.Run(rv); | 502 c.Run(rv); |
527 } | 503 } |
528 return OK; | 504 return OK; |
529 } | 505 } |
530 | 506 |
531 void SpdyProxyClientSocket::OnDataSent(size_t bytes_sent) { | 507 void SpdyProxyClientSocket::OnDataSent() { |
532 DCHECK(!write_callback_.is_null()); | 508 DCHECK(!write_callback_.is_null()); |
533 | 509 |
534 DCHECK_LE(static_cast<int>(bytes_sent), write_bytes_outstanding_); | 510 int rv = write_buffer_len_; |
535 write_bytes_outstanding_ -= static_cast<int>(bytes_sent); | 511 write_buffer_len_ = 0; |
536 | 512 CompletionCallback c = write_callback_; |
Ryan Hamilton
2013/05/23 04:12:00
nit: I think you can use ResetAndReturn() here.
akalin
2013/05/23 05:29:38
Done.
| |
537 if (write_bytes_outstanding_ == 0) { | 513 write_callback_.Reset(); |
538 int rv = write_buffer_len_; | 514 c.Run(rv); |
539 write_buffer_len_ = 0; | |
540 write_bytes_outstanding_ = 0; | |
541 CompletionCallback c = write_callback_; | |
542 write_callback_.Reset(); | |
543 c.Run(rv); | |
544 } | |
545 } | 515 } |
546 | 516 |
547 void SpdyProxyClientSocket::OnClose(int status) { | 517 void SpdyProxyClientSocket::OnClose(int status) { |
548 was_ever_used_ = spdy_stream_->WasEverUsed(); | 518 was_ever_used_ = spdy_stream_->WasEverUsed(); |
549 spdy_stream_.reset(); | 519 spdy_stream_.reset(); |
550 | 520 |
551 bool connecting = next_state_ != STATE_DISCONNECTED && | 521 bool connecting = next_state_ != STATE_DISCONNECTED && |
552 next_state_ < STATE_OPEN; | 522 next_state_ < STATE_OPEN; |
553 if (next_state_ == STATE_OPEN) | 523 if (next_state_ == STATE_OPEN) |
554 next_state_ = STATE_CLOSED; | 524 next_state_ = STATE_CLOSED; |
555 else | 525 else |
556 next_state_ = STATE_DISCONNECTED; | 526 next_state_ = STATE_DISCONNECTED; |
557 | 527 |
558 base::WeakPtr<SpdyProxyClientSocket> weak_ptr = weak_factory_.GetWeakPtr(); | 528 base::WeakPtr<SpdyProxyClientSocket> weak_ptr = weak_factory_.GetWeakPtr(); |
559 CompletionCallback write_callback = write_callback_; | 529 CompletionCallback write_callback = write_callback_; |
560 write_callback_.Reset(); | 530 write_callback_.Reset(); |
561 write_buffer_len_ = 0; | 531 write_buffer_len_ = 0; |
562 write_bytes_outstanding_ = 0; | |
563 | 532 |
564 // If we're in the middle of connecting, we need to make sure | 533 // If we're in the middle of connecting, we need to make sure |
565 // we invoke the connect callback. | 534 // we invoke the connect callback. |
566 if (connecting) { | 535 if (connecting) { |
567 DCHECK(!read_callback_.is_null()); | 536 DCHECK(!read_callback_.is_null()); |
568 CompletionCallback read_callback = read_callback_; | 537 CompletionCallback read_callback = read_callback_; |
569 read_callback_.Reset(); | 538 read_callback_.Reset(); |
570 read_callback.Run(status); | 539 read_callback.Run(status); |
571 } else if (!read_callback_.is_null()) { | 540 } else if (!read_callback_.is_null()) { |
572 // If we have a read_callback_, the we need to make sure we call it back. | 541 // If we have a read_callback_, the we need to make sure we call it back. |
573 OnDataReceived(scoped_ptr<SpdyBuffer>()); | 542 OnDataReceived(scoped_ptr<SpdyBuffer>()); |
574 } | 543 } |
575 // This may have been deleted by read_callback_, so check first. | 544 // This may have been deleted by read_callback_, so check first. |
576 if (weak_ptr && !write_callback.is_null()) | 545 if (weak_ptr && !write_callback.is_null()) |
577 write_callback.Run(ERR_CONNECTION_CLOSED); | 546 write_callback.Run(ERR_CONNECTION_CLOSED); |
578 } | 547 } |
579 | 548 |
580 } // namespace net | 549 } // namespace net |
OLD | NEW |