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 |