| Index: net/quic/quic_headers_stream.cc
|
| diff --git a/net/quic/quic_headers_stream.cc b/net/quic/quic_headers_stream.cc
|
| index 7b0f8ec01d9f4134315c09e1053f37ae96e22827..964be3201a4dd72d6bff090482810083eb580a78 100644
|
| --- a/net/quic/quic_headers_stream.cc
|
| +++ b/net/quic/quic_headers_stream.cc
|
| @@ -20,12 +20,6 @@ using std::string;
|
|
|
| namespace net {
|
|
|
| -namespace {
|
| -
|
| -const QuicStreamId kInvalidStreamId = 0;
|
| -
|
| -} // namespace
|
| -
|
| // A SpdyFramer visitor which passed SYN_STREAM and SYN_REPLY frames to
|
| // the QuicSpdyStream, and closes the connection if any unexpected frames
|
| // are received.
|
| @@ -144,7 +138,14 @@ class QuicHeadersStream::SpdyFramerVisitor
|
| void OnPushPromise(SpdyStreamId stream_id,
|
| SpdyStreamId promised_stream_id,
|
| bool end) override {
|
| - CloseConnection("SPDY PUSH_PROMISE frame received.");
|
| + if (!stream_->supports_push_promise()) {
|
| + CloseConnection("PUSH_PROMISE not supported.");
|
| + return;
|
| + }
|
| + if (!stream_->IsConnected()) {
|
| + return;
|
| + }
|
| + stream_->OnPushPromise(stream_id, promised_stream_id, end);
|
| }
|
|
|
| void OnContinuation(SpdyStreamId stream_id, bool end) override {}
|
| @@ -186,10 +187,14 @@ QuicHeadersStream::QuicHeadersStream(QuicSpdySession* session)
|
| : ReliableQuicStream(kHeadersStreamId, session),
|
| spdy_session_(session),
|
| stream_id_(kInvalidStreamId),
|
| + promised_stream_id_(kInvalidStreamId),
|
| fin_(false),
|
| frame_len_(0),
|
| measure_headers_hol_blocking_time_(
|
| FLAGS_quic_measure_headers_hol_blocking_time),
|
| + supports_push_promise_(
|
| + session->perspective() == Perspective::IS_CLIENT &&
|
| + FLAGS_quic_supports_push_promise),
|
| cur_max_timestamp_(QuicTime::Zero()),
|
| prev_max_timestamp_(QuicTime::Zero()),
|
| spdy_framer_(HTTP2),
|
| @@ -296,10 +301,25 @@ void QuicHeadersStream::OnHeaders(SpdyStreamId stream_id,
|
| }
|
| }
|
| DCHECK_EQ(kInvalidStreamId, stream_id_);
|
| + DCHECK_EQ(kInvalidStreamId, promised_stream_id_);
|
| stream_id_ = stream_id;
|
| fin_ = fin;
|
| }
|
|
|
| +void QuicHeadersStream::OnPushPromise(SpdyStreamId stream_id,
|
| + SpdyStreamId promised_stream_id,
|
| + bool end) {
|
| + if (!supports_push_promise_) {
|
| + CloseConnectionWithDetails(QUIC_INVALID_HEADERS_STREAM_DATA,
|
| + "SPDY PUSH_PROMISE not supported.");
|
| + return;
|
| + }
|
| + DCHECK_EQ(kInvalidStreamId, stream_id_);
|
| + DCHECK_EQ(kInvalidStreamId, promised_stream_id_);
|
| + stream_id_ = stream_id;
|
| + promised_stream_id_ = promised_stream_id;
|
| +}
|
| +
|
| void QuicHeadersStream::OnControlFrameHeaderData(SpdyStreamId stream_id,
|
| const char* header_data,
|
| size_t len) {
|
| @@ -322,13 +342,24 @@ void QuicHeadersStream::OnControlFrameHeaderData(SpdyStreamId stream_id,
|
| prev_max_timestamp_ = std::max(prev_max_timestamp_, cur_max_timestamp_);
|
| cur_max_timestamp_ = QuicTime::Zero();
|
| }
|
| - spdy_session_->OnStreamHeadersComplete(stream_id_, fin_, frame_len_);
|
| + if (promised_stream_id_ == kInvalidStreamId) {
|
| + spdy_session_->OnStreamHeadersComplete(stream_id_, fin_, frame_len_);
|
| + } else {
|
| + spdy_session_->OnPromiseHeadersComplete(stream_id_, promised_stream_id_,
|
| + frame_len_);
|
| + }
|
| // Reset state for the next frame.
|
| + promised_stream_id_ = kInvalidStreamId;
|
| stream_id_ = kInvalidStreamId;
|
| fin_ = false;
|
| frame_len_ = 0;
|
| } else {
|
| - spdy_session_->OnStreamHeaders(stream_id_, StringPiece(header_data, len));
|
| + if (promised_stream_id_ == kInvalidStreamId) {
|
| + spdy_session_->OnStreamHeaders(stream_id_, StringPiece(header_data, len));
|
| + } else {
|
| + spdy_session_->OnPromiseHeaders(stream_id_,
|
| + StringPiece(header_data, len));
|
| + }
|
| }
|
| }
|
|
|
|
|