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 old_write_callback_(NULL), | 37 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 old_write_callback_ = NULL; | 129 write_callback_ = NULL; |
130 write_callback_.Reset(); | |
131 | 130 |
132 next_state_ = STATE_DISCONNECTED; | 131 next_state_ = STATE_DISCONNECTED; |
133 | 132 |
134 if (spdy_stream_) | 133 if (spdy_stream_) |
135 // This will cause OnClose to be invoked, which takes care of | 134 // This will cause OnClose to be invoked, which takes care of |
136 // cleaning up all the internal state. | 135 // cleaning up all the internal state. |
137 spdy_stream_->Cancel(); | 136 spdy_stream_->Cancel(); |
138 } | 137 } |
139 | 138 |
140 bool SpdyProxyClientSocket::IsConnected() const { | 139 bool SpdyProxyClientSocket::IsConnected() const { |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
238 } else { | 237 } else { |
239 data->DidConsume(bytes_to_copy); | 238 data->DidConsume(bytes_to_copy); |
240 } | 239 } |
241 } | 240 } |
242 | 241 |
243 return user_buffer_->BytesConsumed(); | 242 return user_buffer_->BytesConsumed(); |
244 } | 243 } |
245 | 244 |
246 int SpdyProxyClientSocket::Write(IOBuffer* buf, int buf_len, | 245 int SpdyProxyClientSocket::Write(IOBuffer* buf, int buf_len, |
247 OldCompletionCallback* callback) { | 246 OldCompletionCallback* callback) { |
248 DCHECK(!old_write_callback_ && write_callback_.is_null()); | 247 DCHECK(!write_callback_); |
249 if (next_state_ != STATE_OPEN) | 248 if (next_state_ != STATE_OPEN) |
250 return ERR_SOCKET_NOT_CONNECTED; | 249 return ERR_SOCKET_NOT_CONNECTED; |
251 | 250 |
252 DCHECK(spdy_stream_); | 251 DCHECK(spdy_stream_); |
253 write_bytes_outstanding_= buf_len; | 252 write_bytes_outstanding_= buf_len; |
254 if (buf_len <= kMaxSpdyFrameChunkSize) { | 253 if (buf_len <= kMaxSpdyFrameChunkSize) { |
255 int rv = spdy_stream_->WriteStreamData(buf, buf_len, spdy::DATA_FLAG_NONE); | 254 int rv = spdy_stream_->WriteStreamData(buf, buf_len, spdy::DATA_FLAG_NONE); |
256 if (rv == ERR_IO_PENDING) { | 255 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 | |
290 DCHECK(spdy_stream_); | |
291 write_bytes_outstanding_= buf_len; | |
292 if (buf_len <= kMaxSpdyFrameChunkSize) { | |
293 int rv = spdy_stream_->WriteStreamData(buf, buf_len, spdy::DATA_FLAG_NONE); | |
294 if (rv == ERR_IO_PENDING) { | |
295 write_callback_ = callback; | 256 write_callback_ = callback; |
296 write_buffer_len_ = buf_len; | 257 write_buffer_len_ = buf_len; |
297 } | 258 } |
298 return rv; | 259 return rv; |
299 } | 260 } |
300 | 261 |
301 // Since a SPDY Data frame can only include kMaxSpdyFrameChunkSize bytes | 262 // Since a SPDY Data frame can only include kMaxSpdyFrameChunkSize bytes |
302 // we need to send multiple data frames | 263 // we need to send multiple data frames |
303 for (int i = 0; i < buf_len; i += kMaxSpdyFrameChunkSize) { | 264 for (int i = 0; i < buf_len; i += kMaxSpdyFrameChunkSize) { |
304 int len = std::min(kMaxSpdyFrameChunkSize, buf_len - i); | 265 int len = std::min(kMaxSpdyFrameChunkSize, buf_len - i); |
(...skipping 259 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
564 } else if (!read_callback_.is_null()) { | 525 } else if (!read_callback_.is_null()) { |
565 int rv = PopulateUserReadBuffer(); | 526 int rv = PopulateUserReadBuffer(); |
566 CompletionCallback c = read_callback_; | 527 CompletionCallback c = read_callback_; |
567 read_callback_.Reset(); | 528 read_callback_.Reset(); |
568 user_buffer_ = NULL; | 529 user_buffer_ = NULL; |
569 c.Run(rv); | 530 c.Run(rv); |
570 } | 531 } |
571 } | 532 } |
572 | 533 |
573 void SpdyProxyClientSocket::OnDataSent(int length) { | 534 void SpdyProxyClientSocket::OnDataSent(int length) { |
574 DCHECK(old_write_callback_ || !write_callback_.is_null()); | 535 DCHECK(write_callback_); |
575 | 536 |
576 write_bytes_outstanding_ -= length; | 537 write_bytes_outstanding_ -= length; |
577 | 538 |
578 DCHECK_GE(write_bytes_outstanding_, 0); | 539 DCHECK_GE(write_bytes_outstanding_, 0); |
579 | 540 |
580 if (write_bytes_outstanding_ == 0) { | 541 if (write_bytes_outstanding_ == 0) { |
581 int rv = write_buffer_len_; | 542 int rv = write_buffer_len_; |
582 write_buffer_len_ = 0; | 543 write_buffer_len_ = 0; |
583 write_bytes_outstanding_ = 0; | 544 write_bytes_outstanding_ = 0; |
584 if (old_write_callback_) { | 545 OldCompletionCallback* c = write_callback_; |
585 OldCompletionCallback* c = old_write_callback_; | 546 write_callback_ = NULL; |
586 old_write_callback_ = NULL; | 547 c->Run(rv); |
587 c->Run(rv); | |
588 } else { | |
589 CompletionCallback c = write_callback_; | |
590 write_callback_.Reset(); | |
591 c.Run(rv); | |
592 } | |
593 } | 548 } |
594 } | 549 } |
595 | 550 |
596 void SpdyProxyClientSocket::OnClose(int status) { | 551 void SpdyProxyClientSocket::OnClose(int status) { |
597 DCHECK(spdy_stream_); | 552 DCHECK(spdy_stream_); |
598 was_ever_used_ = spdy_stream_->WasEverUsed(); | 553 was_ever_used_ = spdy_stream_->WasEverUsed(); |
599 spdy_stream_ = NULL; | 554 spdy_stream_ = NULL; |
600 | 555 |
601 bool connecting = next_state_ != STATE_DISCONNECTED && | 556 bool connecting = next_state_ != STATE_DISCONNECTED && |
602 next_state_ < STATE_OPEN; | 557 next_state_ < STATE_OPEN; |
603 if (next_state_ == STATE_OPEN) | 558 if (next_state_ == STATE_OPEN) |
604 next_state_ = STATE_CLOSED; | 559 next_state_ = STATE_CLOSED; |
605 else | 560 else |
606 next_state_ = STATE_DISCONNECTED; | 561 next_state_ = STATE_DISCONNECTED; |
607 | 562 |
608 base::WeakPtr<SpdyProxyClientSocket> weak_ptr = weak_factory_.GetWeakPtr(); | 563 base::WeakPtr<SpdyProxyClientSocket> weak_ptr = weak_factory_.GetWeakPtr(); |
609 OldCompletionCallback* old_write_callback = old_write_callback_; | 564 OldCompletionCallback* write_callback = write_callback_; |
610 CompletionCallback write_callback = write_callback_; | 565 write_callback_ = NULL; |
611 old_write_callback_ = NULL; | |
612 write_callback_.Reset(); | |
613 write_buffer_len_ = 0; | 566 write_buffer_len_ = 0; |
614 write_bytes_outstanding_ = 0; | 567 write_bytes_outstanding_ = 0; |
615 | 568 |
616 // If we're in the middle of connecting, we need to make sure | 569 // If we're in the middle of connecting, we need to make sure |
617 // we invoke the connect callback. | 570 // we invoke the connect callback. |
618 if (connecting) { | 571 if (connecting) { |
619 DCHECK(old_read_callback_ || !read_callback_.is_null()); | 572 DCHECK(old_read_callback_ || !read_callback_.is_null()); |
620 if (old_read_callback_) { | 573 if (old_read_callback_) { |
621 OldCompletionCallback* read_callback = old_read_callback_; | 574 OldCompletionCallback* read_callback = old_read_callback_; |
622 old_read_callback_ = NULL; | 575 old_read_callback_ = NULL; |
623 read_callback->Run(status); | 576 read_callback->Run(status); |
624 } else { | 577 } else { |
625 CompletionCallback read_callback = read_callback_; | 578 CompletionCallback read_callback = read_callback_; |
626 read_callback_.Reset(); | 579 read_callback_.Reset(); |
627 read_callback.Run(status); | 580 read_callback.Run(status); |
628 } | 581 } |
629 } else if (old_read_callback_ || !read_callback_.is_null()) { | 582 } else if (old_read_callback_ || !read_callback_.is_null()) { |
630 // If we have a read_callback_, the we need to make sure we call it back. | 583 // If we have a read_callback_, the we need to make sure we call it back. |
631 OnDataReceived(NULL, 0); | 584 OnDataReceived(NULL, 0); |
632 } | 585 } |
633 // This may have been deleted by read_callback_, so check first. | 586 // This may have been deleted by read_callback_, so check first. |
634 if (weak_ptr && (old_write_callback || !write_callback.is_null())) { | 587 if (weak_ptr && write_callback) |
635 if (old_write_callback) | 588 write_callback->Run(ERR_CONNECTION_CLOSED); |
636 old_write_callback->Run(ERR_CONNECTION_CLOSED); | |
637 else | |
638 write_callback.Run(ERR_CONNECTION_CLOSED); | |
639 } | |
640 } | 589 } |
641 | 590 |
642 void SpdyProxyClientSocket::set_chunk_callback(ChunkCallback* /*callback*/) { | 591 void SpdyProxyClientSocket::set_chunk_callback(ChunkCallback* /*callback*/) { |
643 } | 592 } |
644 | 593 |
645 } // namespace net | 594 } // namespace net |
OLD | NEW |