Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(720)

Unified Diff: net/spdy/spdy_stream.cc

Issue 3020032: Implement server push protocol 2. (Closed)
Patch Set: nits. Created 10 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « net/spdy/spdy_stream.h ('k') | net/spdy/spdy_test_util.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: net/spdy/spdy_stream.cc
diff --git a/net/spdy/spdy_stream.cc b/net/spdy/spdy_stream.cc
index b79cb9936abeb5633cdcaca88c883f2b972ed6e6..5fd5f14690cec30e28c6b91b0ec00562110047f1 100644
--- a/net/spdy/spdy_stream.cc
+++ b/net/spdy/spdy_stream.cc
@@ -13,7 +13,8 @@ namespace net {
SpdyStream::SpdyStream(
SpdySession* session, spdy::SpdyStreamId stream_id, bool pushed)
- : stream_id_(stream_id),
+ : continue_buffering_data_(true),
+ stream_id_(stream_id),
priority_(0),
send_window_size_(spdy::kInitialWindowSize),
pushed_(pushed),
@@ -39,16 +40,32 @@ void SpdyStream::SetDelegate(Delegate* delegate) {
CHECK(delegate);
delegate_ = delegate;
- if (!response_->empty()) {
- // The stream already got response.
- delegate_->OnResponseReceived(*response_, response_time_, OK);
+ if (pushed_) {
+ CHECK(!response_->empty());
+ MessageLoop::current()->PostTask(
+ FROM_HERE, NewRunnableMethod(this,
+ &SpdyStream::PushedStreamReplayData));
+ } else {
+ continue_buffering_data_ = false;
}
+}
+void SpdyStream::PushedStreamReplayData() {
+ if (cancelled_ || delegate_ == NULL)
+ return;
+
+ delegate_->OnResponseReceived(*response_, response_time_, OK);
+
+ continue_buffering_data_ = false;
std::vector<scoped_refptr<IOBufferWithSize> > buffers;
buffers.swap(pending_buffers_);
for (size_t i = 0; i < buffers.size(); ++i) {
- if (delegate_)
- delegate_->OnDataReceived(buffers[i]->data(), buffers[i]->size());
+ if (delegate_){
+ if (buffers[i])
+ delegate_->OnDataReceived(buffers[i]->data(), buffers[i]->size());
+ else
+ delegate_->OnDataReceived(NULL, 0);
+ }
}
}
@@ -131,13 +148,7 @@ int SpdyStream::OnResponseReceived(const spdy::SpdyHeaderBlock& response) {
CHECK(pushed_);
io_state_ = STATE_READ_HEADERS;
} else if (io_state_ == STATE_READ_HEADERS_COMPLETE) {
- // This SpdyStream could be in this state in both true and false pushed_
- // conditions.
- // The false pushed_ condition (client request) will always go through
- // this state.
- // The true pushed_condition (server push) can be in this state when the
- // client requests an X-Associated-Content piece of content prior
- // to when the server push happens.
+ CHECK(!pushed_);
} else {
// We're not expecting a response while in this state. Error!
rv = ERR_SPDY_PROTOCOL_ERROR;
@@ -146,8 +157,8 @@ int SpdyStream::OnResponseReceived(const spdy::SpdyHeaderBlock& response) {
rv = DoLoop(rv);
if (delegate_)
rv = delegate_->OnResponseReceived(*response_, response_time_, rv);
- // if delegate_ is not yet attached, we'll return response when delegate
- // gets attached to the stream.
+ // If delegate_ is not yet attached, we'll call OnResponseReceived after the
+ // delegate gets attached to the stream.
return rv;
}
@@ -157,7 +168,20 @@ void SpdyStream::OnDataReceived(const char* data, int length) {
LOG(INFO) << "SpdyStream: Data (" << length << " bytes) received for "
<< stream_id_;
- CHECK(!response_complete_);
+ if (!delegate_ || continue_buffering_data_) {
+ // It should be valid for this to happen in the server push case.
+ // We'll return received data when delegate gets attached to the stream.
+ if (length > 0) {
+ IOBufferWithSize* buf = new IOBufferWithSize(length);
+ memcpy(buf->data(), data, length);
+ pending_buffers_.push_back(buf);
+ }
+ else
+ pending_buffers_.push_back(NULL);
+ return;
+ }
+
+ CHECK(!response_complete_);
// If we don't have a response, then the SYN_REPLY did not come through.
// We cannot pass data up to the caller unless the reply headers have been
@@ -248,16 +272,11 @@ int SpdyStream::DoSendRequest(bool has_upload_data) {
DCHECK_EQ(io_state_, STATE_NONE);
io_state_ = STATE_SEND_HEADERS;
} else {
+ // Pushed stream should not have upload data.
DCHECK(!has_upload_data);
- if (!response_->empty()) {
- // We already have response headers, so we don't need to read the header.
- // Pushed stream should not have upload data.
- // We don't need to call DoLoop() in this state.
- DCHECK_EQ(io_state_, STATE_OPEN);
- return OK;
- } else {
- io_state_ = STATE_READ_HEADERS;
- }
+ DCHECK(!response_->empty());
+ DCHECK_EQ(io_state_, STATE_OPEN);
+ return ERR_IO_PENDING;
}
return DoLoop(result);
}
« no previous file with comments | « net/spdy/spdy_stream.h ('k') | net/spdy/spdy_test_util.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698