| Index: net/quic/quic_spdy_stream.cc
|
| diff --git a/net/quic/quic_spdy_stream.cc b/net/quic/quic_spdy_stream.cc
|
| index 2e099ca5e76c267121f74cf1f75304cf1bc42efd..c946e0c0c95cc5916f9c16ce328100bed7c05ba5 100644
|
| --- a/net/quic/quic_spdy_stream.cc
|
| +++ b/net/quic/quic_spdy_stream.cc
|
| @@ -183,6 +183,16 @@ void QuicSpdyStream::OnStreamHeadersComplete(bool fin, size_t frame_len) {
|
| }
|
| }
|
|
|
| +void QuicSpdyStream::OnStreamHeaderList(bool fin,
|
| + size_t frame_len,
|
| + const QuicHeaderList& header_list) {
|
| + if (!headers_decompressed_) {
|
| + OnInitialHeadersComplete(fin, frame_len, header_list);
|
| + } else {
|
| + OnTrailingHeadersComplete(fin, frame_len, header_list);
|
| + }
|
| +}
|
| +
|
| void QuicSpdyStream::OnInitialHeadersComplete(bool fin, size_t /*frame_len*/) {
|
| headers_decompressed_ = true;
|
| if (fin) {
|
| @@ -193,6 +203,20 @@ void QuicSpdyStream::OnInitialHeadersComplete(bool fin, size_t /*frame_len*/) {
|
| }
|
| }
|
|
|
| +void QuicSpdyStream::OnInitialHeadersComplete(
|
| + bool fin,
|
| + size_t /*frame_len*/,
|
| + const QuicHeaderList& header_list) {
|
| + headers_decompressed_ = true;
|
| + header_list_ = header_list;
|
| + if (fin) {
|
| + OnStreamFrame(QuicStreamFrame(id(), fin, 0, StringPiece()));
|
| + }
|
| + if (FinishedReadingHeaders()) {
|
| + sequencer()->SetUnblocked();
|
| + }
|
| +}
|
| +
|
| void QuicSpdyStream::OnPromiseHeaders(StringPiece headers_data) {
|
| headers_data.AppendToString(&decompressed_headers_);
|
| }
|
| @@ -208,6 +232,18 @@ void QuicSpdyStream::OnPromiseHeadersComplete(
|
| return;
|
| }
|
|
|
| +void QuicSpdyStream::OnPromiseHeaderList(
|
| + QuicStreamId /* promised_id */,
|
| + size_t /* frame_len */,
|
| + const QuicHeaderList& /*header_list */) {
|
| + // To be overridden in QuicSpdyClientStream. Not supported on
|
| + // server side.
|
| + session()->connection()->CloseConnection(
|
| + QUIC_INVALID_HEADERS_STREAM_DATA, "Promise headers received by server",
|
| + ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
|
| + return;
|
| +}
|
| +
|
| void QuicSpdyStream::OnTrailingHeadersComplete(bool fin, size_t /*frame_len*/) {
|
| DCHECK(!trailers_decompressed_);
|
| if (fin_received()) {
|
| @@ -245,6 +281,39 @@ void QuicSpdyStream::OnTrailingHeadersComplete(bool fin, size_t /*frame_len*/) {
|
| trailers_decompressed_ = true;
|
| }
|
|
|
| +void QuicSpdyStream::OnTrailingHeadersComplete(
|
| + bool fin,
|
| + size_t /*frame_len*/,
|
| + const QuicHeaderList& header_list) {
|
| + DCHECK(!trailers_decompressed_);
|
| + if (fin_received()) {
|
| + DLOG(ERROR) << "Received Trailers after FIN, on stream: " << id();
|
| + session()->connection()->CloseConnection(
|
| + QUIC_INVALID_HEADERS_STREAM_DATA, "Trailers after fin",
|
| + ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
|
| + return;
|
| + }
|
| + if (!fin) {
|
| + DLOG(ERROR) << "Trailers must have FIN set, on stream: " << id();
|
| + session()->connection()->CloseConnection(
|
| + QUIC_INVALID_HEADERS_STREAM_DATA, "Fin missing from trailers",
|
| + ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
|
| + return;
|
| + }
|
| +
|
| + size_t final_byte_offset = 0;
|
| + if (!SpdyUtils::CopyAndValidateTrailers(header_list, &final_byte_offset,
|
| + &received_trailers_)) {
|
| + DLOG(ERROR) << "Trailers are malformed: " << id();
|
| + session()->connection()->CloseConnection(
|
| + QUIC_INVALID_HEADERS_STREAM_DATA, "Trailers are malformed",
|
| + ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
|
| + return;
|
| + }
|
| + OnStreamFrame(QuicStreamFrame(id(), fin, final_byte_offset, StringPiece()));
|
| + trailers_decompressed_ = true;
|
| +}
|
| +
|
| void QuicSpdyStream::OnStreamReset(const QuicRstStreamFrame& frame) {
|
| if (frame.error_code != QUIC_STREAM_NO_ERROR ||
|
| version() <= QUIC_VERSION_28) {
|
| @@ -271,7 +340,8 @@ void QuicSpdyStream::OnClose() {
|
| }
|
|
|
| bool QuicSpdyStream::FinishedReadingHeaders() const {
|
| - return headers_decompressed_ && decompressed_headers_.empty();
|
| + return headers_decompressed_ && decompressed_headers_.empty() &&
|
| + header_list_.empty();
|
| }
|
|
|
| bool QuicSpdyStream::ParseHeaderStatusCode(SpdyHeaderBlock* header,
|
|
|