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_stream.h" | 5 #include "net/spdy/spdy_stream.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/logging.h" | 8 #include "base/logging.h" |
9 #include "base/message_loop.h" | 9 #include "base/message_loop.h" |
10 #include "base/stringprintf.h" | 10 #include "base/stringprintf.h" |
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
121 } else { | 121 } else { |
122 delegate_->OnDataReceived(NULL, 0); | 122 delegate_->OnDataReceived(NULL, 0); |
123 session_->CloseStream(stream_id_, net::OK); | 123 session_->CloseStream(stream_id_, net::OK); |
124 // Note: |this| may be deleted after calling CloseStream. | 124 // Note: |this| may be deleted after calling CloseStream. |
125 DCHECK_EQ(buffers.size() - 1, i); | 125 DCHECK_EQ(buffers.size() - 1, i); |
126 } | 126 } |
127 } | 127 } |
128 } | 128 } |
129 | 129 |
130 void SpdyStream::DetachDelegate() { | 130 void SpdyStream::DetachDelegate() { |
131 if (delegate_) | |
132 delegate_->set_chunk_callback(NULL); | |
133 delegate_ = NULL; | 131 delegate_ = NULL; |
134 if (!closed()) | 132 if (!closed()) |
135 Cancel(); | 133 Cancel(); |
136 } | 134 } |
137 | 135 |
138 const linked_ptr<SpdyHeaderBlock>& SpdyStream::spdy_headers() const { | 136 const linked_ptr<SpdyHeaderBlock>& SpdyStream::spdy_headers() const { |
139 return request_; | 137 return request_; |
140 } | 138 } |
141 | 139 |
142 void SpdyStream::set_spdy_headers( | 140 void SpdyStream::set_spdy_headers( |
(...skipping 15 matching lines...) Expand all Loading... | |
158 | 156 |
159 void SpdyStream::AdjustSendWindowSize(int32 delta_window_size) { | 157 void SpdyStream::AdjustSendWindowSize(int32 delta_window_size) { |
160 send_window_size_ += delta_window_size; | 158 send_window_size_ += delta_window_size; |
161 PossiblyResumeIfStalled(); | 159 PossiblyResumeIfStalled(); |
162 } | 160 } |
163 | 161 |
164 void SpdyStream::IncreaseSendWindowSize(int32 delta_window_size) { | 162 void SpdyStream::IncreaseSendWindowSize(int32 delta_window_size) { |
165 DCHECK(session_->is_flow_control_enabled()); | 163 DCHECK(session_->is_flow_control_enabled()); |
166 DCHECK_GE(delta_window_size, 1); | 164 DCHECK_GE(delta_window_size, 1); |
167 | 165 |
168 int32 new_window_size = send_window_size_ + delta_window_size; | |
169 | |
170 // We should ignore WINDOW_UPDATEs received before or after this state, | 166 // We should ignore WINDOW_UPDATEs received before or after this state, |
171 // since before means we've not written SYN_STREAM yet (i.e. it's too | 167 // since before means we've not written SYN_STREAM yet (i.e. it's too |
172 // early) and after means we've written a DATA frame with FIN bit. | 168 // early) and after means we've written a DATA frame with FIN bit. |
173 if (io_state_ != STATE_SEND_BODY_COMPLETE) | 169 if (io_state_ != STATE_SEND_BODY_COMPLETE) |
Ryan Hamilton
2012/07/09 17:52:02
I don't like this. While it is OK (mebe) to recei
ramant (doing other things)
2012/07/11 01:36:18
Done.
| |
174 return; | 170 return; |
175 | 171 |
176 // it's valid for send_window_size_ to become negative (via an incoming | 172 int32 new_window_size = send_window_size_ + delta_window_size; |
173 | |
174 // It's valid for send_window_size_ to become negative (via an incoming | |
177 // SETTINGS), in which case incoming WINDOW_UPDATEs will eventually make | 175 // SETTINGS), in which case incoming WINDOW_UPDATEs will eventually make |
178 // it positive; however, if send_window_size_ is positive and incoming | 176 // it positive; however, if send_window_size_ is positive and incoming |
179 // WINDOW_UPDATE makes it negative, we have an overflow. | 177 // WINDOW_UPDATE makes it negative, we have an overflow. |
180 if (send_window_size_ > 0 && new_window_size < 0) { | 178 if (send_window_size_ > 0 && new_window_size < 0) { |
181 std::string desc = base::StringPrintf( | 179 std::string desc = base::StringPrintf( |
182 "Received WINDOW_UPDATE [delta: %d] for stream %d overflows " | 180 "Received WINDOW_UPDATE [delta: %d] for stream %d overflows " |
183 "send_window_size_ [current: %d]", delta_window_size, stream_id_, | 181 "send_window_size_ [current: %d]", delta_window_size, stream_id_, |
184 send_window_size_); | 182 send_window_size_); |
185 session_->ResetStream(stream_id_, FLOW_CONTROL_ERROR, desc); | 183 session_->ResetStream(stream_id_, FLOW_CONTROL_ERROR, desc); |
186 return; | 184 return; |
187 } | 185 } |
188 | 186 |
189 send_window_size_ = new_window_size; | 187 send_window_size_ = new_window_size; |
190 | 188 |
191 net_log_.AddEvent( | 189 net_log_.AddEvent( |
192 NetLog::TYPE_SPDY_STREAM_UPDATE_SEND_WINDOW, | 190 NetLog::TYPE_SPDY_STREAM_UPDATE_SEND_WINDOW, |
193 base::Bind(&NetLogSpdyStreamWindowUpdateCallback, | 191 base::Bind(&NetLogSpdyStreamWindowUpdateCallback, |
194 stream_id_, delta_window_size, send_window_size_)); | 192 stream_id_, delta_window_size, send_window_size_)); |
193 | |
195 PossiblyResumeIfStalled(); | 194 PossiblyResumeIfStalled(); |
196 } | 195 } |
197 | 196 |
198 void SpdyStream::DecreaseSendWindowSize(int32 delta_window_size) { | 197 void SpdyStream::DecreaseSendWindowSize(int32 delta_window_size) { |
199 // we only call this method when sending a frame, therefore | 198 // we only call this method when sending a frame, therefore |
200 // |delta_window_size| should be within the valid frame size range. | 199 // |delta_window_size| should be within the valid frame size range. |
201 DCHECK(session_->is_flow_control_enabled()); | 200 DCHECK(session_->is_flow_control_enabled()); |
202 DCHECK_GE(delta_window_size, 1); | 201 DCHECK_GE(delta_window_size, 1); |
203 DCHECK_LE(delta_window_size, kMaxSpdyFrameChunkSize); | 202 DCHECK_LE(delta_window_size, kMaxSpdyFrameChunkSize); |
204 | 203 |
(...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
427 | 426 |
428 // This function is only called when an entire frame is written. | 427 // This function is only called when an entire frame is written. |
429 void SpdyStream::OnWriteComplete(int bytes) { | 428 void SpdyStream::OnWriteComplete(int bytes) { |
430 DCHECK_LE(0, bytes); | 429 DCHECK_LE(0, bytes); |
431 send_bytes_ += bytes; | 430 send_bytes_ += bytes; |
432 if (cancelled() || closed()) | 431 if (cancelled() || closed()) |
433 return; | 432 return; |
434 DoLoop(bytes); | 433 DoLoop(bytes); |
435 } | 434 } |
436 | 435 |
437 void SpdyStream::OnChunkAvailable() { | |
438 DCHECK(io_state_ == STATE_SEND_HEADERS || io_state_ == STATE_SEND_BODY || | |
439 io_state_ == STATE_SEND_BODY_COMPLETE); | |
440 if (io_state_ == STATE_SEND_BODY) | |
441 OnWriteComplete(0); | |
442 } | |
443 | |
444 int SpdyStream::GetProtocolVersion() const { | 436 int SpdyStream::GetProtocolVersion() const { |
445 return session_->GetProtocolVersion(); | 437 return session_->GetProtocolVersion(); |
446 } | 438 } |
447 | 439 |
448 void SpdyStream::LogStreamError(int status, const std::string& description) { | 440 void SpdyStream::LogStreamError(int status, const std::string& description) { |
449 net_log_.AddEvent(NetLog::TYPE_SPDY_STREAM_ERROR, | 441 net_log_.AddEvent(NetLog::TYPE_SPDY_STREAM_ERROR, |
450 base::Bind(&NetLogSpdyStreamErrorCallback, | 442 base::Bind(&NetLogSpdyStreamErrorCallback, |
451 stream_id_, status, &description)); | 443 stream_id_, status, &description)); |
452 } | 444 } |
453 | 445 |
454 void SpdyStream::OnClose(int status) { | 446 void SpdyStream::OnClose(int status) { |
455 io_state_ = STATE_DONE; | 447 io_state_ = STATE_DONE; |
456 response_status_ = status; | 448 response_status_ = status; |
457 Delegate* delegate = delegate_; | 449 Delegate* delegate = delegate_; |
458 delegate_ = NULL; | 450 delegate_ = NULL; |
459 if (delegate) { | 451 if (delegate) |
460 delegate->set_chunk_callback(NULL); | |
461 delegate->OnClose(status); | 452 delegate->OnClose(status); |
462 } | |
463 } | 453 } |
464 | 454 |
465 void SpdyStream::Cancel() { | 455 void SpdyStream::Cancel() { |
466 if (cancelled()) | 456 if (cancelled()) |
467 return; | 457 return; |
468 | 458 |
469 cancelled_ = true; | 459 cancelled_ = true; |
470 if (session_->IsStreamActive(stream_id_)) | 460 if (session_->IsStreamActive(stream_id_)) |
471 session_->ResetStream(stream_id_, CANCEL, ""); | 461 session_->ResetStream(stream_id_, CANCEL, ""); |
472 } | 462 } |
473 | 463 |
474 void SpdyStream::Close() { | 464 void SpdyStream::Close() { |
475 session_->CloseStream(stream_id_, net::OK); | 465 session_->CloseStream(stream_id_, net::OK); |
476 } | 466 } |
477 | 467 |
478 int SpdyStream::SendRequest(bool has_upload_data) { | 468 int SpdyStream::SendRequest(bool has_upload_data) { |
479 if (delegate_) | |
480 delegate_->set_chunk_callback(this); | |
481 | |
482 // Pushed streams do not send any data, and should always be in STATE_OPEN or | 469 // Pushed streams do not send any data, and should always be in STATE_OPEN or |
483 // STATE_DONE. However, we still want to return IO_PENDING to mimic non-push | 470 // STATE_DONE. However, we still want to return IO_PENDING to mimic non-push |
484 // behavior. | 471 // behavior. |
485 has_upload_data_ = has_upload_data; | 472 has_upload_data_ = has_upload_data; |
486 if (pushed_) { | 473 if (pushed_) { |
487 send_time_ = base::TimeTicks::Now(); | 474 send_time_ = base::TimeTicks::Now(); |
488 DCHECK(!has_upload_data_); | 475 DCHECK(!has_upload_data_); |
489 DCHECK(response_received()); | 476 DCHECK(response_received()); |
490 return ERR_IO_PENDING; | 477 return ERR_IO_PENDING; |
491 } | 478 } |
(...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
695 return OK; | 682 return OK; |
696 } | 683 } |
697 | 684 |
698 io_state_ = STATE_SEND_BODY; | 685 io_state_ = STATE_SEND_BODY; |
699 return OK; | 686 return OK; |
700 } | 687 } |
701 | 688 |
702 // DoSendBody is called to send the optional body for the request. This call | 689 // DoSendBody is called to send the optional body for the request. This call |
703 // will also be called as each write of a chunk of the body completes. | 690 // will also be called as each write of a chunk of the body completes. |
704 int SpdyStream::DoSendBody() { | 691 int SpdyStream::DoSendBody() { |
705 // If we're already in the STATE_SENDING_BODY state, then we've already | 692 // If we're already in the STATE_SEND_BODY state, then we've already |
706 // sent a portion of the body. In that case, we need to first consume | 693 // sent a portion of the body. In that case, we need to first consume |
707 // the bytes written in the body stream. Note that the bytes written is | 694 // the bytes written in the body stream. Note that the bytes written is |
708 // the number of bytes in the frame that were written, only consume the | 695 // the number of bytes in the frame that were written, only consume the |
709 // data portion, of course. | 696 // data portion, of course. |
710 io_state_ = STATE_SEND_BODY_COMPLETE; | 697 io_state_ = STATE_SEND_BODY_COMPLETE; |
711 if (!delegate_) | 698 if (!delegate_) |
712 return ERR_UNEXPECTED; | 699 return ERR_UNEXPECTED; |
713 return delegate_->OnSendBody(); | 700 return delegate_->OnSendBody(); |
714 } | 701 } |
715 | 702 |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
748 UMA_HISTOGRAM_TIMES("Net.SpdyStreamDownloadTime", | 735 UMA_HISTOGRAM_TIMES("Net.SpdyStreamDownloadTime", |
749 recv_last_byte_time_ - recv_first_byte_time_); | 736 recv_last_byte_time_ - recv_first_byte_time_); |
750 UMA_HISTOGRAM_TIMES("Net.SpdyStreamTime", | 737 UMA_HISTOGRAM_TIMES("Net.SpdyStreamTime", |
751 recv_last_byte_time_ - send_time_); | 738 recv_last_byte_time_ - send_time_); |
752 | 739 |
753 UMA_HISTOGRAM_COUNTS("Net.SpdySendBytes", send_bytes_); | 740 UMA_HISTOGRAM_COUNTS("Net.SpdySendBytes", send_bytes_); |
754 UMA_HISTOGRAM_COUNTS("Net.SpdyRecvBytes", recv_bytes_); | 741 UMA_HISTOGRAM_COUNTS("Net.SpdyRecvBytes", recv_bytes_); |
755 } | 742 } |
756 | 743 |
757 } // namespace net | 744 } // namespace net |
OLD | NEW |