Chromium Code Reviews| 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 |