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

Unified Diff: net/spdy/spdy_stream.cc

Issue 10448083: Fix out of order SYN_STEAM frames. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebase Created 8 years, 6 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_stream_spdy2_unittest.cc » ('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 9d0f552efbca70d5917a69e5754df024e7c9dae8..47311681c45ffbe5b02b890d8182749e3d81ea78 100644
--- a/net/spdy/spdy_stream.cc
+++ b/net/spdy/spdy_stream.cc
@@ -50,11 +50,10 @@ bool ContainsUpperAscii(const std::string& str) {
} // namespace
SpdyStream::SpdyStream(SpdySession* session,
- SpdyStreamId stream_id,
bool pushed,
const BoundNetLog& net_log)
: continue_buffering_data_(true),
- stream_id_(stream_id),
+ stream_id_(0),
priority_(HIGHEST),
slot_(0),
stalled_by_flow_control_(false),
@@ -77,8 +76,77 @@ SpdyStream::SpdyStream(SpdySession* session,
domain_bound_cert_type_(CLIENT_CERT_INVALID_TYPE) {
}
+class SpdyStream::SpdyStreamIOBufferProducer
+ : public SpdySession::SpdyIOBufferProducer {
+ public:
+ SpdyStreamIOBufferProducer(SpdyStream* stream) : stream_(stream) {}
+
+ // SpdyFrameProducer
+ virtual RequestPriority GetPriority() const OVERRIDE {
+ return stream_->priority();
+ }
+
+ virtual SpdyIOBuffer* ProduceNextBuffer(SpdySession* session) OVERRIDE {
+ if (stream_->stream_id() == 0)
+ SpdySession::SpdyIOBufferProducer::ActivateStream(session, stream_);
+ SpdyFrame* frame = stream_->ProduceNextFrame();
+ return frame == NULL ? NULL :
+ SpdySession::SpdyIOBufferProducer::CreateIOBuffer(
+ frame, GetPriority(), stream_);
+ }
+
+ private:
+ scoped_refptr<SpdyStream> stream_;
+
+};
+
+SpdySession::SpdyIOBufferProducer* SpdyStream::CreateProducer() {
willchan no longer on Chromium 2012/06/26 17:07:27 I don't feel strongly. I don't really know why I f
Ryan Hamilton 2012/06/26 17:55:24 Done. Heh, fair enough. Both approaches work for
+ return new SpdyStreamIOBufferProducer(this);
+}
+
+SpdyFrame* SpdyStream::ProduceNextFrame() {
+ if (io_state_ == STATE_SEND_DOMAIN_BOUND_CERT_COMPLETE) {
+ CHECK(request_.get());
+ CHECK_GT(stream_id_, 0u);
+
+ std::string origin = GetUrl().GetOrigin().spec();
+ origin.erase(origin.length() - 1); // trim trailing slash
+ SpdyCredentialControlFrame* frame = session_->CreateCredentialFrame(
+ origin, domain_bound_cert_type_, domain_bound_private_key_,
+ domain_bound_cert_, priority_);
+ return frame;
+ } else if (io_state_ == STATE_SEND_HEADERS_COMPLETE) {
+ CHECK(request_.get());
+ CHECK_GT(stream_id_, 0u);
+
+ SpdyControlFlags flags =
+ has_upload_data_ ? CONTROL_FLAG_NONE : CONTROL_FLAG_FIN;
+ SpdySynStreamControlFrame* frame = session_->CreateSynStream(
+ stream_id_, priority_, slot_, flags, request_);
+ set_stream_id(frame->stream_id());
+ send_time_ = base::TimeTicks::Now();
+ return frame;
+ } else {
+ CHECK(!cancelled());
+ // We must need to write stream data.
+ // Until the headers have been completely sent, we can not be sure
+ // that our stream_id is correct.
+ DCHECK_GT(io_state_, STATE_SEND_HEADERS_COMPLETE);
+ DCHECK_GT(stream_id_, 0u);
+ DCHECK(!pending_data_frames_.empty());
+ SpdyFrame* frame = pending_data_frames_.front();
+ pending_data_frames_.pop_front();
+ return frame;
+ }
+}
+
SpdyStream::~SpdyStream() {
UpdateHistograms();
+ while (!pending_data_frames_.empty()) {
+ SpdyFrame* frame = pending_data_frames_.back();
+ pending_data_frames_.pop_back();
+ delete frame;
+ }
}
void SpdyStream::SetDelegate(Delegate* delegate) {
@@ -472,7 +540,10 @@ void SpdyStream::Cancel() {
}
void SpdyStream::Close() {
- session_->CloseStream(stream_id_, net::OK);
+ if (stream_id_ != 0)
+ session_->CloseStream(stream_id_, net::OK);
+ else
+ session_->CloseCreatedStream(this, OK);
}
int SpdyStream::SendRequest(bool has_upload_data) {
@@ -499,7 +570,13 @@ int SpdyStream::WriteStreamData(IOBuffer* data, int length,
// Until the headers have been completely sent, we can not be sure
// that our stream_id is correct.
DCHECK_GT(io_state_, STATE_SEND_HEADERS_COMPLETE);
- return session_->WriteStreamData(stream_id_, data, length, flags);
+ CHECK_GT(stream_id_, 0u);
+
+ pending_data_frames_.push_back(
+ session_->CreateDataFrame(stream_id_, data, length, flags));
+
+ session_->SetStreamHasWriteAvailable(this);
+ return ERR_IO_PENDING;
}
bool SpdyStream::GetSSLInfo(SSLInfo* ssl_info,
@@ -643,14 +720,8 @@ int SpdyStream::DoGetDomainBoundCertComplete(int result) {
int SpdyStream::DoSendDomainBoundCert() {
io_state_ = STATE_SEND_DOMAIN_BOUND_CERT_COMPLETE;
CHECK(request_.get());
- std::string origin = GetUrl().GetOrigin().spec();
- origin.erase(origin.length() - 1); // trim trailing slash
- int rv = session_->WriteCredentialFrame(
- origin, domain_bound_cert_type_, domain_bound_private_key_,
- domain_bound_cert_, priority_);
- if (rv != ERR_IO_PENDING)
- return rv;
- return OK;
+ session_->SetStreamHasWriteAvailable(this);
+ return ERR_IO_PENDING;
}
int SpdyStream::DoSendDomainBoundCertComplete(int result) {
@@ -664,18 +735,7 @@ int SpdyStream::DoSendDomainBoundCertComplete(int result) {
int SpdyStream::DoSendHeaders() {
CHECK(!cancelled_);
- SpdyControlFlags flags = CONTROL_FLAG_NONE;
- if (!has_upload_data_)
- flags = CONTROL_FLAG_FIN;
-
- CHECK(request_.get());
- int result = session_->WriteSynStream(
- stream_id_, priority_, slot_, flags,
- request_);
- if (result != ERR_IO_PENDING)
- return result;
-
- send_time_ = base::TimeTicks::Now();
+ session_->SetStreamHasWriteAvailable(this);
io_state_ = STATE_SEND_HEADERS_COMPLETE;
return ERR_IO_PENDING;
}
« no previous file with comments | « net/spdy/spdy_stream.h ('k') | net/spdy/spdy_stream_spdy2_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698