summaryrefslogtreecommitdiffstats
path: root/net/quic/quic_headers_stream.cc
diff options
context:
space:
mode:
Diffstat (limited to 'net/quic/quic_headers_stream.cc')
-rw-r--r--net/quic/quic_headers_stream.cc51
1 files changed, 41 insertions, 10 deletions
diff --git a/net/quic/quic_headers_stream.cc b/net/quic/quic_headers_stream.cc
index 0676b54..abcaa71 100644
--- a/net/quic/quic_headers_stream.cc
+++ b/net/quic/quic_headers_stream.cc
@@ -7,6 +7,7 @@
#include "base/macros.h"
#include "base/metrics/histogram_macros.h"
#include "base/strings/stringprintf.h"
+#include "net/quic/quic_bug_tracker.h"
#include "net/quic/quic_flags.h"
#include "net/quic/quic_headers_stream.h"
#include "net/quic/quic_spdy_session.h"
@@ -19,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.
@@ -143,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 {}
@@ -185,10 +187,13 @@ 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),
@@ -226,7 +231,7 @@ size_t QuicHeadersStream::WritePushPromise(
const SpdyHeaderBlock& headers,
QuicAckListenerInterface* ack_listener) {
if (session()->perspective() == Perspective::IS_CLIENT) {
- LOG(DFATAL) << "Client shouldn't send PUSH_PROMISE";
+ QUIC_BUG << "Client shouldn't send PUSH_PROMISE";
return 0;
}
@@ -295,10 +300,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) {
@@ -321,13 +341,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));
+ }
}
}