Index: net/spdy/spdy_stream.cc |
diff --git a/net/spdy/spdy_stream.cc b/net/spdy/spdy_stream.cc |
index 7ed562c4d1c0d2fac7ccfbd2390acc6993bab82b..ce9ddd306e5cfd22101b3cbec8defb7d9d7307fb 100644 |
--- a/net/spdy/spdy_stream.cc |
+++ b/net/spdy/spdy_stream.cc |
@@ -403,9 +403,8 @@ int SpdyStream::OnInitialResponseHeadersReceived( |
case SPDY_REQUEST_RESPONSE_STREAM: |
// For a request/response stream, we're ready for the response |
- // headers once we've finished sending the request headers and |
- // the request body (if we have one). |
- if (io_state_ != STATE_HALF_CLOSED_LOCAL) { |
+ // headers once we've finished sending the request headers. |
+ if (io_state_ == STATE_IDLE) { |
session_->ResetStream(stream_id_, RST_STREAM_PROTOCOL_ERROR, |
"Response received before request sent"); |
return ERR_SPDY_PROTOCOL_ERROR; |
@@ -485,16 +484,15 @@ void SpdyStream::OnDataReceived(scoped_ptr<SpdyBuffer> buffer) { |
if (!buffer) { |
metrics_.StopStream(); |
- // TODO(jgraettinger): Closing from OPEN preserves current SpdyStream |
- // behavior, but is incorrect HTTP/2 behavior. |io_state_| should be |
- // HALF_CLOSED_REMOTE. To be changed in a subsequent CL. |
- if (io_state_ == STATE_OPEN || io_state_ == STATE_HALF_CLOSED_LOCAL) { |
+ if (io_state_ == STATE_OPEN) { |
+ io_state_ = STATE_HALF_CLOSED_REMOTE; |
+ } else if (io_state_ == STATE_HALF_CLOSED_LOCAL) { |
io_state_ = STATE_CLOSED; |
// Deletes |this|. |
session_->CloseActiveStream(stream_id_, OK); |
- return; |
+ } else { |
+ NOTREACHED() << io_state_; |
} |
- NOTREACHED() << io_state_; |
return; |
} |
@@ -535,18 +533,29 @@ void SpdyStream::OnFrameWriteComplete(SpdyFrameType frame_type, |
} |
if (pending_send_status_ == NO_MORE_DATA_TO_SEND) { |
- // TODO(jgraettinger): Once HALF_CLOSED_REMOTE is added, |
- // we'll need to handle transitions to fully closed here. |
- CHECK_EQ(io_state_, STATE_OPEN); |
- io_state_ = STATE_HALF_CLOSED_LOCAL; |
+ if(io_state_ == STATE_OPEN) { |
+ io_state_ = STATE_HALF_CLOSED_LOCAL; |
+ } else if(io_state_ == STATE_HALF_CLOSED_REMOTE) { |
+ io_state_ = STATE_CLOSED; |
+ } else { |
+ NOTREACHED() << io_state_; |
+ } |
} |
- |
- // Notify delegate of write completion. May destroy |this|. |
+ // Notify delegate of write completion. Must not destroy |this|. |
CHECK(delegate_); |
- if (frame_type == SYN_STREAM) { |
- delegate_->OnRequestHeadersSent(); |
- } else { |
- delegate_->OnDataSent(); |
+ { |
+ base::WeakPtr<SpdyStream> weak_this = GetWeakPtr(); |
+ if (frame_type == SYN_STREAM) { |
+ delegate_->OnRequestHeadersSent(); |
+ } else { |
+ delegate_->OnDataSent(); |
+ } |
+ CHECK(weak_this); |
+ } |
+ |
+ if (io_state_ == STATE_CLOSED) { |
+ // Deletes |this|. |
+ session_->CloseActiveStream(stream_id_, OK); |
} |
} |
@@ -559,7 +568,8 @@ int SpdyStream::OnRequestHeadersSent() { |
} |
int SpdyStream::OnDataSent(size_t frame_size) { |
- CHECK_EQ(io_state_, STATE_OPEN); |
+ CHECK(io_state_ == STATE_OPEN || |
+ io_state_ == STATE_HALF_CLOSED_REMOTE) << io_state_; |
size_t frame_payload_size = frame_size - session_->GetDataFrameMinimumSize(); |
@@ -654,7 +664,8 @@ void SpdyStream::SendData(IOBuffer* data, |
SpdySendStatus send_status) { |
CHECK_NE(type_, SPDY_PUSH_STREAM); |
CHECK_EQ(pending_send_status_, MORE_DATA_TO_SEND); |
- CHECK_EQ(io_state_, STATE_OPEN); |
+ CHECK(io_state_ == STATE_OPEN || |
+ io_state_ == STATE_HALF_CLOSED_REMOTE) << io_state_; |
CHECK(!pending_send_data_.get()); |
pending_send_data_ = new DrainableIOBuffer(data, length); |
pending_send_status_ = send_status; |
@@ -696,7 +707,7 @@ bool SpdyStream::IsLocallyClosed() const { |
io_state_ == STATE_CLOSED; |
} |
-bool SpdyStream::IsIdleTemporaryRename() const { |
+bool SpdyStream::IsIdle() const { |
return io_state_ == STATE_IDLE; |
} |
@@ -762,7 +773,8 @@ void SpdyStream::UpdateHistograms() { |
void SpdyStream::QueueNextDataFrame() { |
// Until the request has been completely sent, we cannot be sure |
// that our stream_id is correct. |
- CHECK_EQ(io_state_, STATE_OPEN); |
+ CHECK(io_state_ == STATE_OPEN || |
+ io_state_ == STATE_HALF_CLOSED_REMOTE) << io_state_; |
CHECK_GT(stream_id_, 0u); |
CHECK(pending_send_data_.get()); |
CHECK_GT(pending_send_data_->BytesRemaining(), 0); |