| 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" |
| 11 #include "base/callback_helpers.h" |
| 11 #include "base/logging.h" | 12 #include "base/logging.h" |
| 12 #include "base/string_util.h" | 13 #include "base/string_util.h" |
| 13 #include "base/values.h" | 14 #include "base/values.h" |
| 14 #include "googleurl/src/gurl.h" | 15 #include "googleurl/src/gurl.h" |
| 15 #include "net/base/auth.h" | 16 #include "net/base/auth.h" |
| 16 #include "net/base/io_buffer.h" | 17 #include "net/base/io_buffer.h" |
| 17 #include "net/base/net_util.h" | 18 #include "net/base/net_util.h" |
| 18 #include "net/http/http_auth_cache.h" | 19 #include "net/http/http_auth_cache.h" |
| 19 #include "net/http/http_auth_handler_factory.h" | 20 #include "net/http/http_auth_handler_factory.h" |
| 20 #include "net/http/http_response_headers.h" | 21 #include "net/http/http_response_headers.h" |
| (...skipping 13 matching lines...) Expand all Loading... |
| 34 : next_state_(STATE_DISCONNECTED), | 35 : next_state_(STATE_DISCONNECTED), |
| 35 spdy_stream_(spdy_stream), | 36 spdy_stream_(spdy_stream), |
| 36 endpoint_(endpoint), | 37 endpoint_(endpoint), |
| 37 auth_( | 38 auth_( |
| 38 new HttpAuthController(HttpAuth::AUTH_PROXY, | 39 new HttpAuthController(HttpAuth::AUTH_PROXY, |
| 39 GURL("https://" + proxy_server.ToString()), | 40 GURL("https://" + proxy_server.ToString()), |
| 40 auth_cache, | 41 auth_cache, |
| 41 auth_handler_factory)), | 42 auth_handler_factory)), |
| 42 user_buffer_len_(0), | 43 user_buffer_len_(0), |
| 43 write_buffer_len_(0), | 44 write_buffer_len_(0), |
| 44 write_bytes_outstanding_(0), | |
| 45 weak_factory_(this), | 45 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); |
| 53 | 53 |
| 54 net_log_.BeginEvent(NetLog::TYPE_SOCKET_ALIVE, | 54 net_log_.BeginEvent(NetLog::TYPE_SOCKET_ALIVE, |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 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_queue_.Clear(); |
| 131 user_buffer_ = NULL; | 131 user_buffer_ = NULL; |
| 132 user_buffer_len_ = 0; | 132 user_buffer_len_ = 0; |
| 133 read_callback_.Reset(); | 133 read_callback_.Reset(); |
| 134 | 134 |
| 135 write_buffer_len_ = 0; | 135 write_buffer_len_ = 0; |
| 136 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_); | 144 DCHECK(!spdy_stream_); |
| 146 } | 145 } |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 220 return read_buffer_queue_.Dequeue(data, len); | 219 return read_buffer_queue_.Dequeue(data, len); |
| 221 } | 220 } |
| 222 | 221 |
| 223 int SpdyProxyClientSocket::Write(IOBuffer* buf, int buf_len, | 222 int SpdyProxyClientSocket::Write(IOBuffer* buf, int buf_len, |
| 224 const CompletionCallback& callback) { | 223 const CompletionCallback& callback) { |
| 225 DCHECK(write_callback_.is_null()); | 224 DCHECK(write_callback_.is_null()); |
| 226 if (next_state_ != STATE_OPEN) | 225 if (next_state_ != STATE_OPEN) |
| 227 return ERR_SOCKET_NOT_CONNECTED; | 226 return ERR_SOCKET_NOT_CONNECTED; |
| 228 | 227 |
| 229 DCHECK(spdy_stream_); | 228 DCHECK(spdy_stream_); |
| 230 write_bytes_outstanding_= buf_len; | 229 spdy_stream_->SendStreamData(buf, buf_len, DATA_FLAG_NONE); |
| 231 if (buf_len <= kMaxSpdyFrameChunkSize) { | 230 net_log_.AddByteTransferEvent(NetLog::TYPE_SOCKET_BYTES_SENT, |
| 232 spdy_stream_->QueueStreamData(buf, buf_len, DATA_FLAG_NONE); | 231 buf_len, buf->data()); |
| 233 net_log_.AddByteTransferEvent(NetLog::TYPE_SOCKET_BYTES_SENT, | 232 write_callback_ = callback; |
| 234 buf_len, buf->data()); | 233 write_buffer_len_ = buf_len; |
| 235 write_callback_ = callback; | 234 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 | |
| 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 } | 235 } |
| 258 | 236 |
| 259 bool SpdyProxyClientSocket::SetReceiveBufferSize(int32 size) { | 237 bool SpdyProxyClientSocket::SetReceiveBufferSize(int32 size) { |
| 260 // Since this StreamSocket sits on top of a shared SpdySession, it | 238 // Since this StreamSocket sits on top of a shared SpdySession, it |
| 261 // is not safe for callers to set change this underlying socket. | 239 // is not safe for callers to set change this underlying socket. |
| 262 return false; | 240 return false; |
| 263 } | 241 } |
| 264 | 242 |
| 265 bool SpdyProxyClientSocket::SetSendBufferSize(int32 size) { | 243 bool SpdyProxyClientSocket::SetSendBufferSize(int32 size) { |
| 266 // Since this StreamSocket sits on top of a shared SpdySession, it | 244 // 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). | 445 // STATE_OPEN (ala WebSockets). |
| 468 return NO_MORE_DATA_TO_SEND; | 446 return NO_MORE_DATA_TO_SEND; |
| 469 } | 447 } |
| 470 | 448 |
| 471 void SpdyProxyClientSocket::OnSendBody() { | 449 void SpdyProxyClientSocket::OnSendBody() { |
| 472 // Because we use |spdy_stream_| via STATE_OPEN (ala WebSockets) | 450 // Because we use |spdy_stream_| via STATE_OPEN (ala WebSockets) |
| 473 // OnSendBody() must never be called. | 451 // OnSendBody() must never be called. |
| 474 CHECK(false); | 452 CHECK(false); |
| 475 } | 453 } |
| 476 | 454 |
| 477 SpdySendStatus SpdyProxyClientSocket::OnSendBodyComplete( | 455 SpdySendStatus SpdyProxyClientSocket::OnSendBodyComplete() { |
| 478 size_t /*bytes_sent*/) { | |
| 479 // Because we use |spdy_stream_| via STATE_OPEN (ala WebSockets) | 456 // Because we use |spdy_stream_| via STATE_OPEN (ala WebSockets) |
| 480 // OnSendBodyComplete() must never be called. | 457 // OnSendBodyComplete() must never be called. |
| 481 CHECK(false); | 458 CHECK(false); |
| 482 return NO_MORE_DATA_TO_SEND; | 459 return NO_MORE_DATA_TO_SEND; |
| 483 } | 460 } |
| 484 | 461 |
| 485 int SpdyProxyClientSocket::OnResponseReceived( | 462 int SpdyProxyClientSocket::OnResponseReceived( |
| 486 const SpdyHeaderBlock& response, | 463 const SpdyHeaderBlock& response, |
| 487 base::Time response_time, | 464 base::Time response_time, |
| 488 int status) { | 465 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_); | 498 int rv = PopulateUserReadBuffer(user_buffer_->data(), user_buffer_len_); |
| 522 CompletionCallback c = read_callback_; | 499 CompletionCallback c = read_callback_; |
| 523 read_callback_.Reset(); | 500 read_callback_.Reset(); |
| 524 user_buffer_ = NULL; | 501 user_buffer_ = NULL; |
| 525 user_buffer_len_ = 0; | 502 user_buffer_len_ = 0; |
| 526 c.Run(rv); | 503 c.Run(rv); |
| 527 } | 504 } |
| 528 return OK; | 505 return OK; |
| 529 } | 506 } |
| 530 | 507 |
| 531 void SpdyProxyClientSocket::OnDataSent(size_t bytes_sent) { | 508 void SpdyProxyClientSocket::OnDataSent() { |
| 532 DCHECK(!write_callback_.is_null()); | 509 DCHECK(!write_callback_.is_null()); |
| 533 | 510 |
| 534 DCHECK_LE(static_cast<int>(bytes_sent), write_bytes_outstanding_); | 511 int rv = write_buffer_len_; |
| 535 write_bytes_outstanding_ -= static_cast<int>(bytes_sent); | 512 write_buffer_len_ = 0; |
| 536 | 513 ResetAndReturn(&write_callback_).Run(rv); |
| 537 if (write_bytes_outstanding_ == 0) { | |
| 538 int rv = write_buffer_len_; | |
| 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 } | 514 } |
| 546 | 515 |
| 547 void SpdyProxyClientSocket::OnClose(int status) { | 516 void SpdyProxyClientSocket::OnClose(int status) { |
| 548 was_ever_used_ = spdy_stream_->WasEverUsed(); | 517 was_ever_used_ = spdy_stream_->WasEverUsed(); |
| 549 spdy_stream_.reset(); | 518 spdy_stream_.reset(); |
| 550 | 519 |
| 551 bool connecting = next_state_ != STATE_DISCONNECTED && | 520 bool connecting = next_state_ != STATE_DISCONNECTED && |
| 552 next_state_ < STATE_OPEN; | 521 next_state_ < STATE_OPEN; |
| 553 if (next_state_ == STATE_OPEN) | 522 if (next_state_ == STATE_OPEN) |
| 554 next_state_ = STATE_CLOSED; | 523 next_state_ = STATE_CLOSED; |
| 555 else | 524 else |
| 556 next_state_ = STATE_DISCONNECTED; | 525 next_state_ = STATE_DISCONNECTED; |
| 557 | 526 |
| 558 base::WeakPtr<SpdyProxyClientSocket> weak_ptr = weak_factory_.GetWeakPtr(); | 527 base::WeakPtr<SpdyProxyClientSocket> weak_ptr = weak_factory_.GetWeakPtr(); |
| 559 CompletionCallback write_callback = write_callback_; | 528 CompletionCallback write_callback = write_callback_; |
| 560 write_callback_.Reset(); | 529 write_callback_.Reset(); |
| 561 write_buffer_len_ = 0; | 530 write_buffer_len_ = 0; |
| 562 write_bytes_outstanding_ = 0; | |
| 563 | 531 |
| 564 // If we're in the middle of connecting, we need to make sure | 532 // If we're in the middle of connecting, we need to make sure |
| 565 // we invoke the connect callback. | 533 // we invoke the connect callback. |
| 566 if (connecting) { | 534 if (connecting) { |
| 567 DCHECK(!read_callback_.is_null()); | 535 DCHECK(!read_callback_.is_null()); |
| 568 CompletionCallback read_callback = read_callback_; | 536 CompletionCallback read_callback = read_callback_; |
| 569 read_callback_.Reset(); | 537 read_callback_.Reset(); |
| 570 read_callback.Run(status); | 538 read_callback.Run(status); |
| 571 } else if (!read_callback_.is_null()) { | 539 } else if (!read_callback_.is_null()) { |
| 572 // If we have a read_callback_, the we need to make sure we call it back. | 540 // If we have a read_callback_, the we need to make sure we call it back. |
| 573 OnDataReceived(scoped_ptr<SpdyBuffer>()); | 541 OnDataReceived(scoped_ptr<SpdyBuffer>()); |
| 574 } | 542 } |
| 575 // This may have been deleted by read_callback_, so check first. | 543 // This may have been deleted by read_callback_, so check first. |
| 576 if (weak_ptr && !write_callback.is_null()) | 544 if (weak_ptr && !write_callback.is_null()) |
| 577 write_callback.Run(ERR_CONNECTION_CLOSED); | 545 write_callback.Run(ERR_CONNECTION_CLOSED); |
| 578 } | 546 } |
| 579 | 547 |
| 580 } // namespace net | 548 } // namespace net |
| OLD | NEW |