OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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/logging.h" | 9 #include "base/logging.h" |
10 #include "base/string_util.h" | 10 #include "base/string_util.h" |
(...skipping 16 matching lines...) Expand all Loading... |
27 const HostPortPair& endpoint, | 27 const HostPortPair& endpoint, |
28 const GURL& url, | 28 const GURL& url, |
29 const HostPortPair& proxy_server, | 29 const HostPortPair& proxy_server, |
30 HttpAuthCache* auth_cache, | 30 HttpAuthCache* auth_cache, |
31 HttpAuthHandlerFactory* auth_handler_factory) | 31 HttpAuthHandlerFactory* auth_handler_factory) |
32 : ALLOW_THIS_IN_INITIALIZER_LIST( | 32 : ALLOW_THIS_IN_INITIALIZER_LIST( |
33 io_callback_(this, &SpdyProxyClientSocket::OnIOComplete)), | 33 io_callback_(this, &SpdyProxyClientSocket::OnIOComplete)), |
34 next_state_(STATE_DISCONNECTED), | 34 next_state_(STATE_DISCONNECTED), |
35 spdy_stream_(spdy_stream), | 35 spdy_stream_(spdy_stream), |
36 old_read_callback_(NULL), | 36 old_read_callback_(NULL), |
37 write_callback_(NULL), | 37 old_write_callback_(NULL), |
38 endpoint_(endpoint), | 38 endpoint_(endpoint), |
39 auth_( | 39 auth_( |
40 new HttpAuthController(HttpAuth::AUTH_PROXY, | 40 new HttpAuthController(HttpAuth::AUTH_PROXY, |
41 GURL("https://" + proxy_server.ToString()), | 41 GURL("https://" + proxy_server.ToString()), |
42 auth_cache, | 42 auth_cache, |
43 auth_handler_factory)), | 43 auth_handler_factory)), |
44 user_buffer_(NULL), | 44 user_buffer_(NULL), |
45 write_buffer_len_(0), | 45 write_buffer_len_(0), |
46 write_bytes_outstanding_(0), | 46 write_bytes_outstanding_(0), |
47 ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)), | 47 ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)), |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
119 } | 119 } |
120 | 120 |
121 void SpdyProxyClientSocket::Disconnect() { | 121 void SpdyProxyClientSocket::Disconnect() { |
122 read_buffer_.clear(); | 122 read_buffer_.clear(); |
123 user_buffer_ = NULL; | 123 user_buffer_ = NULL; |
124 old_read_callback_ = NULL; | 124 old_read_callback_ = NULL; |
125 read_callback_.Reset(); | 125 read_callback_.Reset(); |
126 | 126 |
127 write_buffer_len_ = 0; | 127 write_buffer_len_ = 0; |
128 write_bytes_outstanding_ = 0; | 128 write_bytes_outstanding_ = 0; |
129 write_callback_ = NULL; | 129 old_write_callback_ = NULL; |
| 130 write_callback_.Reset(); |
130 | 131 |
131 next_state_ = STATE_DISCONNECTED; | 132 next_state_ = STATE_DISCONNECTED; |
132 | 133 |
133 if (spdy_stream_) | 134 if (spdy_stream_) |
134 // This will cause OnClose to be invoked, which takes care of | 135 // This will cause OnClose to be invoked, which takes care of |
135 // cleaning up all the internal state. | 136 // cleaning up all the internal state. |
136 spdy_stream_->Cancel(); | 137 spdy_stream_->Cancel(); |
137 } | 138 } |
138 | 139 |
139 bool SpdyProxyClientSocket::IsConnected() const { | 140 bool SpdyProxyClientSocket::IsConnected() const { |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
237 } else { | 238 } else { |
238 data->DidConsume(bytes_to_copy); | 239 data->DidConsume(bytes_to_copy); |
239 } | 240 } |
240 } | 241 } |
241 | 242 |
242 return user_buffer_->BytesConsumed(); | 243 return user_buffer_->BytesConsumed(); |
243 } | 244 } |
244 | 245 |
245 int SpdyProxyClientSocket::Write(IOBuffer* buf, int buf_len, | 246 int SpdyProxyClientSocket::Write(IOBuffer* buf, int buf_len, |
246 OldCompletionCallback* callback) { | 247 OldCompletionCallback* callback) { |
247 DCHECK(!write_callback_); | 248 DCHECK(!old_write_callback_ && write_callback_.is_null()); |
248 if (next_state_ != STATE_OPEN) | 249 if (next_state_ != STATE_OPEN) |
249 return ERR_SOCKET_NOT_CONNECTED; | 250 return ERR_SOCKET_NOT_CONNECTED; |
250 | 251 |
| 252 DCHECK(spdy_stream_); |
| 253 write_bytes_outstanding_= buf_len; |
| 254 if (buf_len <= kMaxSpdyFrameChunkSize) { |
| 255 int rv = spdy_stream_->WriteStreamData(buf, buf_len, spdy::DATA_FLAG_NONE); |
| 256 if (rv == ERR_IO_PENDING) { |
| 257 old_write_callback_ = callback; |
| 258 write_buffer_len_ = buf_len; |
| 259 } |
| 260 return rv; |
| 261 } |
| 262 |
| 263 // Since a SPDY Data frame can only include kMaxSpdyFrameChunkSize bytes |
| 264 // we need to send multiple data frames |
| 265 for (int i = 0; i < buf_len; i += kMaxSpdyFrameChunkSize) { |
| 266 int len = std::min(kMaxSpdyFrameChunkSize, buf_len - i); |
| 267 scoped_refptr<DrainableIOBuffer> iobuf(new DrainableIOBuffer(buf, i + len)); |
| 268 iobuf->SetOffset(i); |
| 269 int rv = spdy_stream_->WriteStreamData(iobuf, len, spdy::DATA_FLAG_NONE); |
| 270 if (rv > 0) { |
| 271 write_bytes_outstanding_ -= rv; |
| 272 } else if (rv != ERR_IO_PENDING) { |
| 273 return rv; |
| 274 } |
| 275 } |
| 276 if (write_bytes_outstanding_ > 0) { |
| 277 old_write_callback_ = callback; |
| 278 write_buffer_len_ = buf_len; |
| 279 return ERR_IO_PENDING; |
| 280 } else { |
| 281 return buf_len; |
| 282 } |
| 283 } |
| 284 int SpdyProxyClientSocket::Write(IOBuffer* buf, int buf_len, |
| 285 const CompletionCallback& callback) { |
| 286 DCHECK(!old_write_callback_ && write_callback_.is_null()); |
| 287 if (next_state_ != STATE_OPEN) |
| 288 return ERR_SOCKET_NOT_CONNECTED; |
| 289 |
251 DCHECK(spdy_stream_); | 290 DCHECK(spdy_stream_); |
252 write_bytes_outstanding_= buf_len; | 291 write_bytes_outstanding_= buf_len; |
253 if (buf_len <= kMaxSpdyFrameChunkSize) { | 292 if (buf_len <= kMaxSpdyFrameChunkSize) { |
254 int rv = spdy_stream_->WriteStreamData(buf, buf_len, spdy::DATA_FLAG_NONE); | 293 int rv = spdy_stream_->WriteStreamData(buf, buf_len, spdy::DATA_FLAG_NONE); |
255 if (rv == ERR_IO_PENDING) { | 294 if (rv == ERR_IO_PENDING) { |
256 write_callback_ = callback; | 295 write_callback_ = callback; |
257 write_buffer_len_ = buf_len; | 296 write_buffer_len_ = buf_len; |
258 } | 297 } |
259 return rv; | 298 return rv; |
260 } | 299 } |
(...skipping 264 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
525 } else if (!read_callback_.is_null()) { | 564 } else if (!read_callback_.is_null()) { |
526 int rv = PopulateUserReadBuffer(); | 565 int rv = PopulateUserReadBuffer(); |
527 CompletionCallback c = read_callback_; | 566 CompletionCallback c = read_callback_; |
528 read_callback_.Reset(); | 567 read_callback_.Reset(); |
529 user_buffer_ = NULL; | 568 user_buffer_ = NULL; |
530 c.Run(rv); | 569 c.Run(rv); |
531 } | 570 } |
532 } | 571 } |
533 | 572 |
534 void SpdyProxyClientSocket::OnDataSent(int length) { | 573 void SpdyProxyClientSocket::OnDataSent(int length) { |
535 DCHECK(write_callback_); | 574 DCHECK(old_write_callback_ || !write_callback_.is_null()); |
536 | 575 |
537 write_bytes_outstanding_ -= length; | 576 write_bytes_outstanding_ -= length; |
538 | 577 |
539 DCHECK_GE(write_bytes_outstanding_, 0); | 578 DCHECK_GE(write_bytes_outstanding_, 0); |
540 | 579 |
541 if (write_bytes_outstanding_ == 0) { | 580 if (write_bytes_outstanding_ == 0) { |
542 int rv = write_buffer_len_; | 581 int rv = write_buffer_len_; |
543 write_buffer_len_ = 0; | 582 write_buffer_len_ = 0; |
544 write_bytes_outstanding_ = 0; | 583 write_bytes_outstanding_ = 0; |
545 OldCompletionCallback* c = write_callback_; | 584 if (old_write_callback_) { |
546 write_callback_ = NULL; | 585 OldCompletionCallback* c = old_write_callback_; |
547 c->Run(rv); | 586 old_write_callback_ = NULL; |
| 587 c->Run(rv); |
| 588 } else { |
| 589 CompletionCallback c = write_callback_; |
| 590 write_callback_.Reset(); |
| 591 c.Run(rv); |
| 592 } |
548 } | 593 } |
549 } | 594 } |
550 | 595 |
551 void SpdyProxyClientSocket::OnClose(int status) { | 596 void SpdyProxyClientSocket::OnClose(int status) { |
552 DCHECK(spdy_stream_); | 597 DCHECK(spdy_stream_); |
553 was_ever_used_ = spdy_stream_->WasEverUsed(); | 598 was_ever_used_ = spdy_stream_->WasEverUsed(); |
554 spdy_stream_ = NULL; | 599 spdy_stream_ = NULL; |
555 | 600 |
556 bool connecting = next_state_ != STATE_DISCONNECTED && | 601 bool connecting = next_state_ != STATE_DISCONNECTED && |
557 next_state_ < STATE_OPEN; | 602 next_state_ < STATE_OPEN; |
558 if (next_state_ == STATE_OPEN) | 603 if (next_state_ == STATE_OPEN) |
559 next_state_ = STATE_CLOSED; | 604 next_state_ = STATE_CLOSED; |
560 else | 605 else |
561 next_state_ = STATE_DISCONNECTED; | 606 next_state_ = STATE_DISCONNECTED; |
562 | 607 |
563 base::WeakPtr<SpdyProxyClientSocket> weak_ptr = weak_factory_.GetWeakPtr(); | 608 base::WeakPtr<SpdyProxyClientSocket> weak_ptr = weak_factory_.GetWeakPtr(); |
564 OldCompletionCallback* write_callback = write_callback_; | 609 OldCompletionCallback* old_write_callback = old_write_callback_; |
565 write_callback_ = NULL; | 610 CompletionCallback write_callback = write_callback_; |
| 611 old_write_callback_ = NULL; |
| 612 write_callback_.Reset(); |
566 write_buffer_len_ = 0; | 613 write_buffer_len_ = 0; |
567 write_bytes_outstanding_ = 0; | 614 write_bytes_outstanding_ = 0; |
568 | 615 |
569 // If we're in the middle of connecting, we need to make sure | 616 // If we're in the middle of connecting, we need to make sure |
570 // we invoke the connect callback. | 617 // we invoke the connect callback. |
571 if (connecting) { | 618 if (connecting) { |
572 DCHECK(old_read_callback_ || !read_callback_.is_null()); | 619 DCHECK(old_read_callback_ || !read_callback_.is_null()); |
573 if (old_read_callback_) { | 620 if (old_read_callback_) { |
574 OldCompletionCallback* read_callback = old_read_callback_; | 621 OldCompletionCallback* read_callback = old_read_callback_; |
575 old_read_callback_ = NULL; | 622 old_read_callback_ = NULL; |
576 read_callback->Run(status); | 623 read_callback->Run(status); |
577 } else { | 624 } else { |
578 CompletionCallback read_callback = read_callback_; | 625 CompletionCallback read_callback = read_callback_; |
579 read_callback_.Reset(); | 626 read_callback_.Reset(); |
580 read_callback.Run(status); | 627 read_callback.Run(status); |
581 } | 628 } |
582 } else if (old_read_callback_ || !read_callback_.is_null()) { | 629 } else if (old_read_callback_ || !read_callback_.is_null()) { |
583 // If we have a read_callback_, the we need to make sure we call it back. | 630 // If we have a read_callback_, the we need to make sure we call it back. |
584 OnDataReceived(NULL, 0); | 631 OnDataReceived(NULL, 0); |
585 } | 632 } |
586 // This may have been deleted by read_callback_, so check first. | 633 // This may have been deleted by read_callback_, so check first. |
587 if (weak_ptr && write_callback) | 634 if (weak_ptr && (old_write_callback || !write_callback.is_null())) { |
588 write_callback->Run(ERR_CONNECTION_CLOSED); | 635 if (old_write_callback) |
| 636 old_write_callback->Run(ERR_CONNECTION_CLOSED); |
| 637 else |
| 638 write_callback.Run(ERR_CONNECTION_CLOSED); |
| 639 } |
589 } | 640 } |
590 | 641 |
591 void SpdyProxyClientSocket::set_chunk_callback(ChunkCallback* /*callback*/) { | 642 void SpdyProxyClientSocket::set_chunk_callback(ChunkCallback* /*callback*/) { |
592 } | 643 } |
593 | 644 |
594 } // namespace net | 645 } // namespace net |
OLD | NEW |