Chromium Code Reviews| Index: net/spdy/spdy_http_stream.cc |
| =================================================================== |
| --- net/spdy/spdy_http_stream.cc (revision 144839) |
| +++ net/spdy/spdy_http_stream.cc (working copy) |
| @@ -36,7 +36,8 @@ |
| user_buffer_len_(0), |
| buffered_read_callback_pending_(false), |
| more_read_data_pending_(false), |
| - direct_(direct) { } |
| + direct_(direct), |
| + waiting_for_chunk_(false) { } |
| void SpdyHttpStream::InitializeWithExistingStream(SpdyStream* spdy_stream) { |
| stream_ = spdy_stream; |
| @@ -45,6 +46,8 @@ |
| } |
| SpdyHttpStream::~SpdyHttpStream() { |
| + if (request_body_stream_ != NULL) |
| + request_body_stream_->set_chunk_callback(NULL); |
| if (stream_) |
| stream_->DetachDelegate(); |
| } |
| @@ -182,11 +185,6 @@ |
| return false; |
| } |
| -void SpdyHttpStream::set_chunk_callback(ChunkCallback* callback) { |
| - if (request_body_stream_ != NULL) |
| - request_body_stream_->set_chunk_callback(callback); |
| -} |
| - |
| int SpdyHttpStream::SendRequest(const HttpRequestHeaders& request_headers, |
| scoped_ptr<UploadDataStream> request_body, |
| HttpResponseInfo* response, |
| @@ -213,6 +211,7 @@ |
| if (request_body != NULL) { |
| if (request_body->size() || request_body->is_chunked()) { |
| request_body_stream_.reset(request_body.release()); |
| + request_body_stream_->set_chunk_callback(this); |
| // Use kMaxSpdyFrameChunkSize as the buffer size, since the request |
| // body data is written with this size at a time. |
| raw_request_body_buf_ = new IOBufferWithSize(kMaxSpdyFrameChunkSize); |
| @@ -271,6 +270,33 @@ |
| stream_->Cancel(); |
| } |
| +int SpdyHttpStream::SendData() { |
| + CHECK(request_body_stream_.get()); |
| + CHECK_EQ(0, request_body_buf_->BytesRemaining()); |
| + |
| + // Read the data from the request body stream. |
| + const int bytes_read = request_body_stream_->Read( |
| + raw_request_body_buf_, raw_request_body_buf_->size()); |
| + |
| + if (request_body_stream_->is_chunked() && bytes_read == ERR_IO_PENDING) { |
| + waiting_for_chunk_ = true; |
|
Ryan Sleevi
2012/07/04 00:52:49
Note that this does mean you can get in a weird st
ramant (doing other things)
2012/07/04 21:04:33
Done.
|
| + return ERR_IO_PENDING; |
| + } |
| + |
| + // ERR_IO_PENDING with chunked encoding is the only possible error. |
| + DCHECK_GE(bytes_read, 0); |
| + |
| + request_body_buf_ = new DrainableIOBuffer(raw_request_body_buf_, |
| + bytes_read); |
| + |
| + DCHECK_GE(request_body_buf_->BytesRemaining(), 0); |
|
Ryan Sleevi
2012/07/04 00:52:49
This check is probably overkill, imo. It's not tes
ramant (doing other things)
2012/07/04 21:04:33
Done.
|
| + const bool eof = request_body_stream_->IsEOF(); |
| + return stream_->WriteStreamData( |
| + request_body_buf_, |
| + request_body_buf_->BytesRemaining(), |
| + eof ? DATA_FLAG_FIN : DATA_FLAG_NONE); |
| +} |
| + |
| bool SpdyHttpStream::OnSendHeadersComplete(int status) { |
| if (!callback_.is_null()) |
| DoCallback(status); |
| @@ -279,20 +305,19 @@ |
| int SpdyHttpStream::OnSendBody() { |
| CHECK(request_body_stream_.get()); |
| + const bool eof = request_body_stream_->IsEOF(); |
| + if (request_body_buf_->BytesRemaining() > 0) { |
| + return stream_->WriteStreamData( |
| + request_body_buf_, |
| + request_body_buf_->BytesRemaining(), |
| + eof ? DATA_FLAG_FIN : DATA_FLAG_NONE); |
| + } |
| - // TODO(satorux): Clean up the logic here. This behavior is weird. Reading |
| - // of upload data should happen in OnSendBody(). crbug.com/113107. |
| - // |
| - // Nothing to send. This happens when OnSendBody() is first called. |
| - // A read of the upload data stream is initiated in OnSendBodyComplete(). |
| - if (request_body_buf_->BytesRemaining() == 0) |
| + // The entire body data has been sent. |
| + if (eof) |
| return OK; |
| - const bool eof = request_body_stream_->IsEOF(); |
| - return stream_->WriteStreamData( |
| - request_body_buf_, |
| - request_body_buf_->BytesRemaining(), |
| - eof ? DATA_FLAG_FIN : DATA_FLAG_NONE); |
| + return SendData(); |
| } |
| int SpdyHttpStream::OnSendBodyComplete(int status, bool* eof) { |
| @@ -311,19 +336,6 @@ |
| // Check if the entire body data has been sent. |
| *eof = (request_body_stream_->IsEOF() && |
| !request_body_buf_->BytesRemaining()); |
| - if (*eof) |
| - return OK; |
| - |
| - // Read the data from the request body stream. |
| - const int bytes_read = request_body_stream_->Read( |
| - raw_request_body_buf_, raw_request_body_buf_->size()); |
| - if (request_body_stream_->is_chunked() && bytes_read == ERR_IO_PENDING) |
| - return ERR_IO_PENDING; |
| - // ERR_IO_PENDING with chunked encoding is the only possible error. |
| - DCHECK_GE(bytes_read, 0); |
| - |
| - request_body_buf_ = new DrainableIOBuffer(raw_request_body_buf_, |
| - bytes_read); |
| return OK; |
| } |
| @@ -406,6 +418,8 @@ |
| void SpdyHttpStream::OnClose(int status) { |
| bool invoked_callback = false; |
| + if (request_body_stream_ != NULL) |
| + request_body_stream_->set_chunk_callback(NULL); |
| if (status == net::OK) { |
| // We need to complete any pending buffered read now. |
| invoked_callback = DoBufferedReadCallback(); |
| @@ -414,6 +428,14 @@ |
| DoCallback(status); |
| } |
| +void SpdyHttpStream::OnChunkAvailable() { |
| + if (waiting_for_chunk_) { |
|
Ryan Sleevi
2012/07/04 00:52:49
nit: You can handle this as a short circuit, to re
ramant (doing other things)
2012/07/04 21:04:33
Done.
|
| + DCHECK(request_body_stream_->is_chunked()); |
| + waiting_for_chunk_ = false; |
| + SendData(); |
| + } |
| +} |
| + |
| void SpdyHttpStream::ScheduleBufferedReadCallback() { |
| // If there is already a scheduled DoBufferedReadCallback, don't issue |
| // another one. Mark that we have received more data and return. |