| Index: net/quic/quic_spdy_stream.cc
|
| diff --git a/net/quic/quic_spdy_stream.cc b/net/quic/quic_spdy_stream.cc
|
| index 8387d7fadefd2e3313ffcafbbf9084408c04f9e7..9b7cf7191ffe5ad6db9d0ffcd46b4d46dd86ad5b 100644
|
| --- a/net/quic/quic_spdy_stream.cc
|
| +++ b/net/quic/quic_spdy_stream.cc
|
| @@ -34,7 +34,8 @@ QuicSpdyStream::QuicSpdyStream(QuicStreamId id, QuicSpdySession* spdy_session)
|
| spdy_session_(spdy_session),
|
| visitor_(nullptr),
|
| headers_decompressed_(false),
|
| - priority_(kDefaultPriority) {
|
| + priority_(kDefaultPriority),
|
| + trailers_decompressed_(false) {
|
| DCHECK_NE(kCryptoStreamId, id);
|
| // Don't receive any callbacks from the sequencer until headers
|
| // are complete.
|
| @@ -96,14 +97,18 @@ void QuicSpdyStream::MarkConsumed(size_t num_bytes) {
|
| }
|
|
|
| bool QuicSpdyStream::IsDoneReading() const {
|
| - if (!headers_decompressed_ || !decompressed_headers_.empty()) {
|
| - return false;
|
| - }
|
| - return sequencer()->IsClosed();
|
| + bool done_reading_headers = FinishedReadingHeaders();
|
| + bool done_reading_body = sequencer()->IsClosed();
|
| + bool done_reading_trailers = FinishedReadingTrailers();
|
| + return done_reading_headers && done_reading_body && done_reading_trailers;
|
| }
|
|
|
| bool QuicSpdyStream::HasBytesToRead() const {
|
| - return !decompressed_headers_.empty() || sequencer()->HasBytesToRead();
|
| + bool headers_to_read = !decompressed_headers_.empty();
|
| + bool body_to_read = sequencer()->HasBytesToRead();
|
| + bool trailers_to_read =
|
| + (FLAGS_quic_supports_trailers && !decompressed_trailers_.empty());
|
| + return headers_to_read || body_to_read || trailers_to_read;
|
| }
|
|
|
| void QuicSpdyStream::MarkHeadersConsumed(size_t bytes_consumed) {
|
| @@ -113,6 +118,10 @@ void QuicSpdyStream::MarkHeadersConsumed(size_t bytes_consumed) {
|
| }
|
| }
|
|
|
| +void QuicSpdyStream::MarkTrailersConsumed(size_t bytes_consumed) {
|
| + decompressed_trailers_.erase(0, bytes_consumed);
|
| +}
|
| +
|
| void QuicSpdyStream::set_priority(SpdyPriority priority) {
|
| DCHECK_EQ(0u, stream_bytes_written());
|
| priority_ = priority;
|
| @@ -123,7 +132,12 @@ SpdyPriority QuicSpdyStream::Priority() const {
|
| }
|
|
|
| void QuicSpdyStream::OnStreamHeaders(StringPiece headers_data) {
|
| - headers_data.AppendToString(&decompressed_headers_);
|
| + if (!FLAGS_quic_supports_trailers || !headers_decompressed_) {
|
| + headers_data.AppendToString(&decompressed_headers_);
|
| + } else {
|
| + DCHECK(!trailers_decompressed_);
|
| + headers_data.AppendToString(&decompressed_trailers_);
|
| + }
|
| }
|
|
|
| void QuicSpdyStream::OnStreamHeadersPriority(SpdyPriority priority) {
|
| @@ -132,6 +146,14 @@ void QuicSpdyStream::OnStreamHeadersPriority(SpdyPriority priority) {
|
| }
|
|
|
| void QuicSpdyStream::OnStreamHeadersComplete(bool fin, size_t frame_len) {
|
| + if (!FLAGS_quic_supports_trailers || !headers_decompressed_) {
|
| + OnInitialHeadersComplete(fin, frame_len);
|
| + } else {
|
| + OnTrailingHeadersComplete(fin, frame_len);
|
| + }
|
| +}
|
| +
|
| +void QuicSpdyStream::OnInitialHeadersComplete(bool fin, size_t /*frame_len*/) {
|
| headers_decompressed_ = true;
|
| if (fin) {
|
| OnStreamFrame(QuicStreamFrame(id(), fin, 0, StringPiece()));
|
| @@ -141,6 +163,21 @@ void QuicSpdyStream::OnStreamHeadersComplete(bool fin, size_t frame_len) {
|
| }
|
| }
|
|
|
| +void QuicSpdyStream::OnTrailingHeadersComplete(bool fin, size_t /*frame_len*/) {
|
| + DCHECK(!trailers_decompressed_);
|
| + if (fin_received()) {
|
| + DLOG(ERROR) << "Received Trailers after FIN, on stream: " << id();
|
| + session()->CloseConnection(QUIC_INVALID_HEADERS_STREAM_DATA);
|
| + return;
|
| + }
|
| + if (!fin) {
|
| + DLOG(ERROR) << "Trailers must have FIN set, on stream: " << id();
|
| + session()->CloseConnection(QUIC_INVALID_HEADERS_STREAM_DATA);
|
| + return;
|
| + }
|
| + trailers_decompressed_ = true;
|
| +}
|
| +
|
| void QuicSpdyStream::OnStreamReset(const QuicRstStreamFrame& frame) {
|
| if (frame.error_code != QUIC_STREAM_NO_ERROR ||
|
| version() <= QUIC_VERSION_28) {
|
| @@ -170,4 +207,11 @@ bool QuicSpdyStream::FinishedReadingHeaders() const {
|
| return headers_decompressed_ && decompressed_headers_.empty();
|
| }
|
|
|
| +bool QuicSpdyStream::FinishedReadingTrailers() const {
|
| + if (!FLAGS_quic_supports_trailers) {
|
| + return true;
|
| + }
|
| + return trailers_decompressed_ && decompressed_trailers_.empty();
|
| +}
|
| +
|
| } // namespace net
|
|
|