Index: net/spdy/spdy_stream.cc |
diff --git a/net/spdy/spdy_stream.cc b/net/spdy/spdy_stream.cc |
index 9d0f552efbca70d5917a69e5754df024e7c9dae8..e4a90941607e4b5120e860b1d318918edefd02bd 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,78 @@ 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_; |
+ |
ramant (doing other things)
2012/06/26 23:30:25
overly nit: extra blank line.
Ryan Hamilton
2012/06/27 16:58:28
Done.
|
+}; |
+ |
+void SpdyStream::SetHasWriteAvailable() { |
+ session_->SetStreamHasWriteAvailable(this, |
+ 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( |
ramant (doing other things)
2012/06/26 23:30:25
nit: should we DCHECK that "origin" ends with slas
Ryan Hamilton
2012/06/27 16:58:28
Done.
|
+ 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()); |
ramant (doing other things)
2012/06/26 23:30:25
nit: why call set_stream_id again? stream_id_ is n
Ryan Hamilton
2012/06/27 16:58:28
I *swear* I removed that line of code earlier, but
|
+ 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 +541,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 +571,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)); |
+ |
+ SetHasWriteAvailable(); |
+ return ERR_IO_PENDING; |
} |
bool SpdyStream::GetSSLInfo(SSLInfo* ssl_info, |
@@ -643,14 +721,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; |
+ SetHasWriteAvailable(); |
+ return ERR_IO_PENDING; |
} |
int SpdyStream::DoSendDomainBoundCertComplete(int result) { |
@@ -664,18 +736,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(); |
+ SetHasWriteAvailable(); |
io_state_ = STATE_SEND_HEADERS_COMPLETE; |
return ERR_IO_PENDING; |
} |