// Copyright 2012 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "net/quic/quic_chromium_client_stream.h"

#include <string>

#include "base/functional/bind.h"
#include "base/functional/callback_helpers.h"
#include "base/memory/ptr_util.h"
#include "base/memory/raw_ptr.h"
#include "base/run_loop.h"
#include "base/strings/string_number_conversions.h"
#include "net/base/io_buffer.h"
#include "net/base/net_errors.h"
#include "net/base/test_completion_callback.h"
#include "net/quic/quic_chromium_client_session.h"
#include "net/quic/quic_context.h"
#include "net/test/gtest_util.h"
#include "net/test/test_with_task_environment.h"
#include "net/third_party/quiche/src/quiche/quic/core/http/quic_spdy_client_session_base.h"
#include "net/third_party/quiche/src/quiche/quic/core/http/quic_spdy_client_stream.h"
#include "net/third_party/quiche/src/quiche/quic/core/http/spdy_utils.h"
#include "net/third_party/quiche/src/quiche/quic/core/quic_utils.h"
#include "net/third_party/quiche/src/quiche/quic/test_tools/crypto_test_utils.h"
#include "net/third_party/quiche/src/quiche/quic/test_tools/quic_config_peer.h"
#include "net/third_party/quiche/src/quiche/quic/test_tools/quic_connection_peer.h"
#include "net/third_party/quiche/src/quiche/quic/test_tools/quic_spdy_session_peer.h"
#include "net/third_party/quiche/src/quiche/quic/test_tools/quic_test_utils.h"
#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
#include "testing/gmock/include/gmock/gmock.h"

using testing::_;
using testing::Return;

namespace net::test {
namespace {

class MockQuicClientSessionBase : public quic::QuicSpdyClientSessionBase {
 public:
  explicit MockQuicClientSessionBase(quic::QuicConnection* connection,
                                     quic::QuicClientPushPromiseIndex* index);

  MockQuicClientSessionBase(const MockQuicClientSessionBase&) = delete;
  MockQuicClientSessionBase& operator=(const MockQuicClientSessionBase&) =
      delete;

  ~MockQuicClientSessionBase() override;

  const quic::QuicCryptoStream* GetCryptoStream() const override {
    return crypto_stream_.get();
  }

  quic::QuicCryptoStream* GetMutableCryptoStream() override {
    return crypto_stream_.get();
  }

  // From quic::QuicSession.
  MOCK_METHOD2(OnConnectionClosed,
               void(const quic::QuicConnectionCloseFrame& frame,
                    quic::ConnectionCloseSource source));
  MOCK_METHOD1(CreateIncomingStream,
               quic::QuicSpdyStream*(quic::QuicStreamId id));
  MOCK_METHOD1(CreateIncomingStream,
               quic::QuicSpdyStream*(quic::PendingStream* pending));
  MOCK_METHOD0(CreateOutgoingBidirectionalStream, QuicChromiumClientStream*());
  MOCK_METHOD0(CreateOutgoingUnidirectionalStream, QuicChromiumClientStream*());
  MOCK_METHOD6(WritevData,
               quic::QuicConsumedData(quic::QuicStreamId id,
                                      size_t write_length,
                                      quic::QuicStreamOffset offset,
                                      quic::StreamSendingState state,
                                      quic::TransmissionType type,
                                      quic::EncryptionLevel level));
  MOCK_METHOD2(WriteControlFrame,
               bool(const quic::QuicFrame&, quic::TransmissionType));
  MOCK_METHOD4(SendRstStream,
               void(quic::QuicStreamId stream_id,
                    quic::QuicRstStreamErrorCode error,
                    quic::QuicStreamOffset bytes_written,
                    bool send_rst_only));

  MOCK_METHOD2(OnStreamHeaders,
               void(quic::QuicStreamId stream_id,
                    absl::string_view headers_data));
  MOCK_METHOD2(OnStreamHeadersPriority,
               void(quic::QuicStreamId stream_id,
                    const spdy::SpdyStreamPrecedence& precedence));
  MOCK_METHOD3(OnStreamHeadersComplete,
               void(quic::QuicStreamId stream_id, bool fin, size_t frame_len));
  MOCK_METHOD2(OnPromiseHeaders,
               void(quic::QuicStreamId stream_id,
                    absl::string_view headers_data));
  MOCK_METHOD3(OnPromiseHeadersComplete,
               void(quic::QuicStreamId stream_id,
                    quic::QuicStreamId promised_stream_id,
                    size_t frame_len));
  MOCK_CONST_METHOD0(OneRttKeysAvailable, bool());
  // Methods taking non-copyable types like spdy::Http2HeaderBlock by value
  // cannot be mocked directly.
  size_t WriteHeadersOnHeadersStream(
      quic::QuicStreamId id,
      spdy::Http2HeaderBlock headers,
      bool fin,
      const spdy::SpdyStreamPrecedence& precedence,
      quiche::QuicheReferenceCountedPointer<quic::QuicAckListenerInterface>
          ack_listener) override {
    return WriteHeadersOnHeadersStreamMock(id, headers, fin, precedence,
                                           std::move(ack_listener));
  }
  MOCK_METHOD5(WriteHeadersOnHeadersStreamMock,
               size_t(quic::QuicStreamId id,
                      const spdy::Http2HeaderBlock& headers,
                      bool fin,
                      const spdy::SpdyStreamPrecedence& precedence,
                      const quiche::QuicheReferenceCountedPointer<
                          quic::QuicAckListenerInterface>& ack_listener));
  MOCK_METHOD1(OnHeadersHeadOfLineBlocking, void(quic::QuicTime::Delta delta));

  using quic::QuicSession::ActivateStream;

  // Returns a quic::QuicConsumedData that indicates all of |write_length| (and
  // |fin| if set) has been consumed.
  static quic::QuicConsumedData ConsumeAllData(
      quic::QuicStreamId id,
      size_t write_length,
      quic::QuicStreamOffset offset,
      bool fin,
      quic::QuicAckListenerInterface* ack_listener);

  void OnProofValid(
      const quic::QuicCryptoClientConfig::CachedState& cached) override {}
  void OnProofVerifyDetailsAvailable(
      const quic::ProofVerifyDetails& verify_details) override {}
  bool IsAuthorized(const std::string& hostname) override { return true; }

 protected:
  MOCK_METHOD1(ShouldCreateIncomingStream, bool(quic::QuicStreamId id));
  MOCK_METHOD0(ShouldCreateOutgoingBidirectionalStream, bool());
  MOCK_METHOD0(ShouldCreateOutgoingUnidirectionalStream, bool());

 private:
  std::unique_ptr<quic::QuicCryptoStream> crypto_stream_;
};

MockQuicClientSessionBase::MockQuicClientSessionBase(
    quic::QuicConnection* connection,
    quic::QuicClientPushPromiseIndex* push_promise_index)
    : quic::QuicSpdyClientSessionBase(connection,
                                      /*visitor=*/nullptr,
                                      push_promise_index,
                                      quic::test::DefaultQuicConfig(),
                                      connection->supported_versions()) {
  crypto_stream_ = std::make_unique<quic::test::MockQuicCryptoStream>(this);
  Initialize();
  ON_CALL(*this, WritevData(_, _, _, _, _, _))
      .WillByDefault(testing::Return(quic::QuicConsumedData(0, false)));
}

MockQuicClientSessionBase::~MockQuicClientSessionBase() = default;

class QuicChromiumClientStreamTest
    : public ::testing::TestWithParam<quic::ParsedQuicVersion>,
      public WithTaskEnvironment {
 public:
  QuicChromiumClientStreamTest()
      : version_(GetParam()),
        crypto_config_(
            quic::test::crypto_test_utils::ProofVerifierForTesting()),
        session_(new quic::test::MockQuicConnection(
                     &helper_,
                     &alarm_factory_,
                     quic::Perspective::IS_CLIENT,
                     quic::test::SupportedVersions(version_)),
                 &push_promise_index_) {
    quic::test::QuicConfigPeer::SetReceivedInitialSessionFlowControlWindow(
        session_.config(), quic::kMinimumFlowControlSendWindow);
    quic::test::QuicConfigPeer::
        SetReceivedInitialMaxStreamDataBytesOutgoingBidirectional(
            session_.config(), quic::kMinimumFlowControlSendWindow);
    quic::test::QuicConfigPeer::SetReceivedMaxUnidirectionalStreams(
        session_.config(), 10);
    session_.OnConfigNegotiated();
    stream_ = new QuicChromiumClientStream(
        quic::test::GetNthClientInitiatedBidirectionalStreamId(
            version_.transport_version, 0),
        &session_, quic::BIDIRECTIONAL, NetLogWithSource(),
        TRAFFIC_ANNOTATION_FOR_TESTS);
    session_.ActivateStream(base::WrapUnique(stream_.get()));
    handle_ = stream_->CreateHandle();
    helper_.AdvanceTime(quic::QuicTime::Delta::FromSeconds(1));
    session_.connection()->SetEncrypter(
        quic::ENCRYPTION_FORWARD_SECURE,
        std::make_unique<quic::test::TaggingEncrypter>(
            quic::ENCRYPTION_FORWARD_SECURE));
  }

  void InitializeHeaders() {
    headers_[":host"] = "www.google.com";
    headers_[":path"] = "/index.hml";
    headers_[":scheme"] = "https";
    headers_[":status"] = "200";
    headers_["cookie"] =
        "__utma=208381060.1228362404.1372200928.1372200928.1372200928.1; "
        "__utmc=160408618; "
        "GX=DQAAAOEAAACWJYdewdE9rIrW6qw3PtVi2-d729qaa-74KqOsM1NVQblK4VhX"
        "hoALMsy6HOdDad2Sz0flUByv7etmo3mLMidGrBoljqO9hSVA40SLqpG_iuKKSHX"
        "RW3Np4bq0F0SDGDNsW0DSmTS9ufMRrlpARJDS7qAI6M3bghqJp4eABKZiRqebHT"
        "pMU-RXvTI5D5oCF1vYxYofH_l1Kviuiy3oQ1kS1enqWgbhJ2t61_SNdv-1XJIS0"
        "O3YeHLmVCs62O6zp89QwakfAWK9d3IDQvVSJzCQsvxvNIvaZFa567MawWlXg0Rh"
        "1zFMi5vzcns38-8_Sns; "
        "GA=v*2%2Fmem*57968640*47239936%2Fmem*57968640*47114716%2Fno-nm-"
        "yj*15%2Fno-cc-yj*5%2Fpc-ch*133685%2Fpc-s-cr*133947%2Fpc-s-t*1339"
        "47%2Fno-nm-yj*4%2Fno-cc-yj*1%2Fceft-as*1%2Fceft-nqas*0%2Fad-ra-c"
        "v_p%2Fad-nr-cv_p-f*1%2Fad-v-cv_p*859%2Fad-ns-cv_p-f*1%2Ffn-v-ad%"
        "2Fpc-t*250%2Fpc-cm*461%2Fpc-s-cr*722%2Fpc-s-t*722%2Fau_p*4"
        "SICAID=AJKiYcHdKgxum7KMXG0ei2t1-W4OD1uW-ecNsCqC0wDuAXiDGIcT_HA2o1"
        "3Rs1UKCuBAF9g8rWNOFbxt8PSNSHFuIhOo2t6bJAVpCsMU5Laa6lewuTMYI8MzdQP"
        "ARHKyW-koxuhMZHUnGBJAM1gJODe0cATO_KGoX4pbbFxxJ5IicRxOrWK_5rU3cdy6"
        "edlR9FsEdH6iujMcHkbE5l18ehJDwTWmBKBzVD87naobhMMrF6VvnDGxQVGp9Ir_b"
        "Rgj3RWUoPumQVCxtSOBdX0GlJOEcDTNCzQIm9BSfetog_eP_TfYubKudt5eMsXmN6"
        "QnyXHeGeK2UINUzJ-D30AFcpqYgH9_1BvYSpi7fc7_ydBU8TaD8ZRxvtnzXqj0RfG"
        "tuHghmv3aD-uzSYJ75XDdzKdizZ86IG6Fbn1XFhYZM-fbHhm3mVEXnyRW4ZuNOLFk"
        "Fas6LMcVC6Q8QLlHYbXBpdNFuGbuZGUnav5C-2I_-46lL0NGg3GewxGKGHvHEfoyn"
        "EFFlEYHsBQ98rXImL8ySDycdLEFvBPdtctPmWCfTxwmoSMLHU2SCVDhbqMWU5b0yr"
        "JBCScs_ejbKaqBDoB7ZGxTvqlrB__2ZmnHHjCr8RgMRtKNtIeuZAo ";
  }

  spdy::Http2HeaderBlock CreateResponseHeaders(const std::string& status_code) {
    spdy::Http2HeaderBlock headers;
    headers[":status"] = status_code;
    return headers;
  }

  void ReadData(absl::string_view expected_data) {
    scoped_refptr<IOBuffer> buffer =
        base::MakeRefCounted<IOBuffer>(expected_data.length() + 1);
    EXPECT_EQ(static_cast<int>(expected_data.length()),
              stream_->Read(buffer.get(), expected_data.length() + 1));
    EXPECT_EQ(expected_data,
              absl::string_view(buffer->data(), expected_data.length()));
  }

  quic::QuicHeaderList ProcessHeaders(const spdy::Http2HeaderBlock& headers) {
    quic::QuicHeaderList h = quic::test::AsHeaderList(headers);
    stream_->OnStreamHeaderList(false, h.uncompressed_header_bytes(), h);
    return h;
  }

  quic::QuicHeaderList ProcessTrailers(const spdy::Http2HeaderBlock& headers) {
    quic::QuicHeaderList h = quic::test::AsHeaderList(headers);
    stream_->OnStreamHeaderList(true, h.uncompressed_header_bytes(), h);
    return h;
  }

  quic::QuicHeaderList ProcessHeadersFull(
      const spdy::Http2HeaderBlock& headers) {
    quic::QuicHeaderList h = ProcessHeaders(headers);
    TestCompletionCallback callback;
    EXPECT_EQ(static_cast<int>(h.uncompressed_header_bytes()),
              handle_->ReadInitialHeaders(&headers_, callback.callback()));
    EXPECT_EQ(headers, headers_);
    EXPECT_TRUE(stream_->header_list().empty());
    return h;
  }

  quic::QuicStreamId GetNthClientInitiatedBidirectionalStreamId(int n) {
    return quic::test::GetNthClientInitiatedBidirectionalStreamId(
        session_.connection()->transport_version(), n);
  }

  quic::QuicStreamId GetNthServerInitiatedUnidirectionalStreamId(int n) {
    return quic::test::GetNthServerInitiatedUnidirectionalStreamId(
        session_.connection()->transport_version(), n);
  }

  void ResetStreamCallback(QuicChromiumClientStream* stream, int /*rv*/) {
    stream->Reset(quic::QUIC_STREAM_CANCELLED);
  }

  std::string ConstructDataHeader(size_t body_len) {
    quiche::QuicheBuffer buffer = quic::HttpEncoder::SerializeDataFrameHeader(
        body_len, quiche::SimpleBufferAllocator::Get());
    return std::string(buffer.data(), buffer.size());
  }

  const quic::ParsedQuicVersion version_;
  quic::QuicCryptoClientConfig crypto_config_;
  std::unique_ptr<QuicChromiumClientStream::Handle> handle_;
  std::unique_ptr<QuicChromiumClientStream::Handle> handle2_;
  quic::test::MockQuicConnectionHelper helper_;
  quic::test::MockAlarmFactory alarm_factory_;
  MockQuicClientSessionBase session_;
  raw_ptr<QuicChromiumClientStream> stream_;
  spdy::Http2HeaderBlock headers_;
  spdy::Http2HeaderBlock trailers_;
  quic::QuicClientPushPromiseIndex push_promise_index_;
};

INSTANTIATE_TEST_SUITE_P(Version,
                         QuicChromiumClientStreamTest,
                         ::testing::ValuesIn(AllSupportedQuicVersions()),
                         ::testing::PrintToStringParamName());

TEST_P(QuicChromiumClientStreamTest, Handle) {
  testing::InSequence seq;
  EXPECT_TRUE(handle_->IsOpen());
  EXPECT_EQ(quic::test::GetNthClientInitiatedBidirectionalStreamId(
                version_.transport_version, 0),
            handle_->id());
  EXPECT_EQ(quic::QUIC_NO_ERROR, handle_->connection_error());
  EXPECT_EQ(quic::QUIC_STREAM_NO_ERROR, handle_->stream_error());
  EXPECT_TRUE(handle_->IsFirstStream());
  EXPECT_FALSE(handle_->IsDoneReading());
  EXPECT_FALSE(handle_->fin_sent());
  EXPECT_FALSE(handle_->fin_received());
  EXPECT_EQ(0u, handle_->stream_bytes_read());
  EXPECT_EQ(0u, handle_->stream_bytes_written());
  EXPECT_EQ(0u, handle_->NumBytesConsumed());

  InitializeHeaders();
  quic::QuicStreamOffset offset = 0;
  ProcessHeadersFull(headers_);
  quic::QuicStreamFrame frame2(
      quic::test::GetNthClientInitiatedBidirectionalStreamId(
          version_.transport_version, 0),
      true, offset, absl::string_view());
  stream_->OnStreamFrame(frame2);
  EXPECT_TRUE(handle_->fin_received());
  handle_->OnFinRead();

  const char kData1[] = "hello world";
  const size_t kDataLen = std::size(kData1);

  // All data written.
  std::string header = ConstructDataHeader(kDataLen);
  EXPECT_CALL(session_,
              WritevData(stream_->id(), _, _, _, quic::NOT_RETRANSMISSION, _))
      .WillOnce(Return(quic::QuicConsumedData(header.length(), false)));
  EXPECT_CALL(session_,
              WritevData(stream_->id(), _, _, _, quic::NOT_RETRANSMISSION, _))
      .WillOnce(Return(quic::QuicConsumedData(kDataLen, true)));
  TestCompletionCallback callback;
  EXPECT_EQ(OK, handle_->WriteStreamData(base::StringPiece(kData1, kDataLen),
                                         true, callback.callback()));

  EXPECT_FALSE(handle_->IsOpen());
  EXPECT_EQ(quic::test::GetNthClientInitiatedBidirectionalStreamId(
                version_.transport_version, 0),
            handle_->id());
  EXPECT_EQ(quic::QUIC_NO_ERROR, handle_->connection_error());
  EXPECT_EQ(quic::QUIC_STREAM_NO_ERROR, handle_->stream_error());
  EXPECT_TRUE(handle_->IsFirstStream());
  EXPECT_TRUE(handle_->IsDoneReading());
  EXPECT_TRUE(handle_->fin_sent());
  EXPECT_TRUE(handle_->fin_received());
  EXPECT_EQ(0u, handle_->stream_bytes_read());
  EXPECT_EQ(header.length() + kDataLen, handle_->stream_bytes_written());
  EXPECT_EQ(0u, handle_->NumBytesConsumed());

  EXPECT_EQ(ERR_CONNECTION_CLOSED,
            handle_->WriteStreamData(base::StringPiece(kData1, kDataLen), true,
                                     callback.callback()));

  std::vector<scoped_refptr<IOBuffer>> buffers = {
      base::MakeRefCounted<IOBuffer>(10)};
  std::vector<int> lengths = {10};
  EXPECT_EQ(
      ERR_CONNECTION_CLOSED,
      handle_->WritevStreamData(buffers, lengths, true, callback.callback()));

  spdy::Http2HeaderBlock headers;
  EXPECT_EQ(0, handle_->WriteHeaders(std::move(headers), true, nullptr));
}

TEST_P(QuicChromiumClientStreamTest, HandleAfterConnectionClose) {
  quic::test::QuicConnectionPeer::TearDownLocalConnectionState(
      session_.connection());
  stream_->OnConnectionClosed(quic::QUIC_INVALID_FRAME_DATA,
                              quic::ConnectionCloseSource::FROM_PEER);

  EXPECT_FALSE(handle_->IsOpen());
  EXPECT_EQ(quic::QUIC_INVALID_FRAME_DATA, handle_->connection_error());
}

TEST_P(QuicChromiumClientStreamTest, HandleAfterStreamReset) {
  // Make a STOP_SENDING frame and pass it to QUIC. We need both a REST_STREAM
  // and a STOP_SENDING to effect a closed stream.
  quic::QuicStopSendingFrame stop_sending_frame(
      quic::kInvalidControlFrameId,
      quic::test::GetNthClientInitiatedBidirectionalStreamId(
          version_.transport_version, 0),
      quic::QUIC_STREAM_CANCELLED);
  session_.OnStopSendingFrame(stop_sending_frame);

  // Verify that the Handle still behaves correctly after the stream is reset.
  quic::QuicRstStreamFrame rst(
      quic::kInvalidControlFrameId,
      quic::test::GetNthClientInitiatedBidirectionalStreamId(
          version_.transport_version, 0),
      quic::QUIC_STREAM_CANCELLED, 0);

  stream_->OnStreamReset(rst);
  EXPECT_FALSE(handle_->IsOpen());
  EXPECT_EQ(quic::QUIC_STREAM_CANCELLED, handle_->stream_error());
}

TEST_P(QuicChromiumClientStreamTest, OnFinRead) {
  InitializeHeaders();
  quic::QuicStreamOffset offset = 0;
  ProcessHeadersFull(headers_);
  quic::QuicStreamFrame frame2(
      quic::test::GetNthClientInitiatedBidirectionalStreamId(
          version_.transport_version, 0),
      true, offset, absl::string_view());
  stream_->OnStreamFrame(frame2);
}

TEST_P(QuicChromiumClientStreamTest, OnDataAvailable) {
  InitializeHeaders();
  ProcessHeadersFull(headers_);

  const char data[] = "hello world!";
  int data_len = strlen(data);
  size_t offset = 0;
  std::string header = ConstructDataHeader(data_len);
  stream_->OnStreamFrame(quic::QuicStreamFrame(
      quic::test::GetNthClientInitiatedBidirectionalStreamId(
          version_.transport_version, 0),
      /*fin=*/false,
      /*offset=*/offset, header));
  offset += header.length();
  stream_->OnStreamFrame(quic::QuicStreamFrame(
      quic::test::GetNthClientInitiatedBidirectionalStreamId(
          version_.transport_version, 0),
      /*fin=*/false,
      /*offset=*/offset, data));

  // Read the body and verify that it arrives correctly.
  TestCompletionCallback callback;
  scoped_refptr<IOBuffer> buffer = base::MakeRefCounted<IOBuffer>(2 * data_len);
  EXPECT_EQ(data_len,
            handle_->ReadBody(buffer.get(), 2 * data_len, callback.callback()));
  EXPECT_EQ(absl::string_view(data),
            absl::string_view(buffer->data(), data_len));
}

TEST_P(QuicChromiumClientStreamTest, OnDataAvailableAfterReadBody) {
  InitializeHeaders();
  ProcessHeadersFull(headers_);

  const char data[] = "hello world!";
  int data_len = strlen(data);

  // Start to read the body.
  TestCompletionCallback callback;
  scoped_refptr<IOBuffer> buffer = base::MakeRefCounted<IOBuffer>(2 * data_len);
  EXPECT_EQ(ERR_IO_PENDING,
            handle_->ReadBody(buffer.get(), 2 * data_len, callback.callback()));

  size_t offset = 0;
  std::string header = ConstructDataHeader(data_len);
  stream_->OnStreamFrame(quic::QuicStreamFrame(
      quic::test::GetNthClientInitiatedBidirectionalStreamId(
          version_.transport_version, 0),
      /*fin=*/false,
      /*offset=*/offset, header));
  offset += header.length();

  stream_->OnStreamFrame(quic::QuicStreamFrame(
      quic::test::GetNthClientInitiatedBidirectionalStreamId(
          version_.transport_version, 0),
      /*fin=*/false,
      /*offset=*/offset, data));

  EXPECT_EQ(data_len, callback.WaitForResult());
  EXPECT_EQ(absl::string_view(data),
            absl::string_view(buffer->data(), data_len));
  base::RunLoop().RunUntilIdle();
}

TEST_P(QuicChromiumClientStreamTest, ProcessHeadersWithError) {
  spdy::Http2HeaderBlock bad_headers;
  bad_headers["NAME"] = "...";

  EXPECT_CALL(
      *static_cast<quic::test::MockQuicConnection*>(session_.connection()),
      OnStreamReset(quic::test::GetNthClientInitiatedBidirectionalStreamId(
                        version_.transport_version, 0),
                    quic::QUIC_BAD_APPLICATION_PAYLOAD));

  auto headers = quic::test::AsHeaderList(bad_headers);
  stream_->OnStreamHeaderList(false, headers.uncompressed_header_bytes(),
                              headers);

  base::RunLoop().RunUntilIdle();
}

TEST_P(QuicChromiumClientStreamTest, OnDataAvailableWithError) {
  InitializeHeaders();
  auto headers = quic::test::AsHeaderList(headers_);
  ProcessHeadersFull(headers_);

  const char data[] = "hello world!";
  int data_len = strlen(data);

  // Start to read the body.
  TestCompletionCallback callback;
  scoped_refptr<IOBuffer> buffer = base::MakeRefCounted<IOBuffer>(2 * data_len);
  EXPECT_EQ(
      ERR_IO_PENDING,
      handle_->ReadBody(
          buffer.get(), 2 * data_len,
          base::BindOnce(&QuicChromiumClientStreamTest::ResetStreamCallback,
                         base::Unretained(this), stream_)));

  EXPECT_CALL(
      *static_cast<quic::test::MockQuicConnection*>(session_.connection()),
      OnStreamReset(quic::test::GetNthClientInitiatedBidirectionalStreamId(
                        version_.transport_version, 0),
                    quic::QUIC_STREAM_CANCELLED));

  // Receive the data and close the stream during the callback.
  size_t offset = 0;
  std::string header = ConstructDataHeader(data_len);
  stream_->OnStreamFrame(quic::QuicStreamFrame(
      quic::test::GetNthClientInitiatedBidirectionalStreamId(
          version_.transport_version, 0),
      /*fin=*/false,
      /*offset=*/offset, header));
  offset += header.length();
  stream_->OnStreamFrame(quic::QuicStreamFrame(
      quic::test::GetNthClientInitiatedBidirectionalStreamId(
          version_.transport_version, 0),
      /*fin=*/false,
      /*offset=*/0, data));

  base::RunLoop().RunUntilIdle();
}

TEST_P(QuicChromiumClientStreamTest, OnError) {
  //  EXPECT_CALL(delegate_, OnError(ERR_INTERNET_DISCONNECTED)).Times(1);

  stream_->OnError(ERR_INTERNET_DISCONNECTED);
  stream_->OnError(ERR_INTERNET_DISCONNECTED);
}

TEST_P(QuicChromiumClientStreamTest, OnTrailers) {
  InitializeHeaders();
  ProcessHeadersFull(headers_);

  const char data[] = "hello world!";
  int data_len = strlen(data);
  size_t offset = 0;
  std::string header = ConstructDataHeader(data_len);
  stream_->OnStreamFrame(quic::QuicStreamFrame(
      quic::test::GetNthClientInitiatedBidirectionalStreamId(
          version_.transport_version, 0),
      /*fin=*/false,
      /*offset=*/offset, header));
  offset += header.length();
  stream_->OnStreamFrame(quic::QuicStreamFrame(
      quic::test::GetNthClientInitiatedBidirectionalStreamId(
          version_.transport_version, 0),
      /*fin=*/false,
      /*offset=*/offset, data));

  // Read the body and verify that it arrives correctly.
  TestCompletionCallback callback;
  scoped_refptr<IOBuffer> buffer = base::MakeRefCounted<IOBuffer>(2 * data_len);
  EXPECT_EQ(data_len,
            handle_->ReadBody(buffer.get(), 2 * data_len, callback.callback()));
  EXPECT_EQ(absl::string_view(data),
            absl::string_view(buffer->data(), data_len));

  spdy::Http2HeaderBlock trailers;
  trailers["bar"] = "foo";

  auto t = ProcessTrailers(trailers);

  TestCompletionCallback trailers_callback;
  EXPECT_EQ(
      static_cast<int>(t.uncompressed_header_bytes()),
      handle_->ReadTrailingHeaders(&trailers_, trailers_callback.callback()));

  // Read the body and verify that it arrives correctly.
  EXPECT_EQ(0,
            handle_->ReadBody(buffer.get(), 2 * data_len, callback.callback()));

  EXPECT_EQ(trailers, trailers_);
  base::RunLoop().RunUntilIdle();
}

// Tests that trailers are marked as consumed only before delegate is to be
// immediately notified about trailers.
TEST_P(QuicChromiumClientStreamTest, MarkTrailersConsumedWhenNotifyDelegate) {
  InitializeHeaders();
  ProcessHeadersFull(headers_);

  const char data[] = "hello world!";
  int data_len = strlen(data);
  size_t offset = 0;
  std::string header = ConstructDataHeader(data_len);
  stream_->OnStreamFrame(quic::QuicStreamFrame(
      quic::test::GetNthClientInitiatedBidirectionalStreamId(
          version_.transport_version, 0),
      /*fin=*/false,
      /*offset=*/offset, header));
  offset += header.length();
  stream_->OnStreamFrame(quic::QuicStreamFrame(
      quic::test::GetNthClientInitiatedBidirectionalStreamId(
          version_.transport_version, 0),
      /*fin=*/false,
      /*offset=*/offset, data));

  // Read the body and verify that it arrives correctly.
  TestCompletionCallback callback;
  scoped_refptr<IOBuffer> buffer = base::MakeRefCounted<IOBuffer>(2 * data_len);
  EXPECT_EQ(data_len,
            handle_->ReadBody(buffer.get(), 2 * data_len, callback.callback()));
  EXPECT_EQ(absl::string_view(data),
            absl::string_view(buffer->data(), data_len));

  // Read again, and it will be pending.
  EXPECT_THAT(
      handle_->ReadBody(buffer.get(), 2 * data_len, callback.callback()),
      IsError(ERR_IO_PENDING));

  spdy::Http2HeaderBlock trailers;
  trailers["bar"] = "foo";
  quic::QuicHeaderList t = ProcessTrailers(trailers);
  EXPECT_FALSE(stream_->IsDoneReading());

  EXPECT_EQ(static_cast<int>(t.uncompressed_header_bytes()),
            handle_->ReadTrailingHeaders(&trailers_, callback.callback()));

  // Read the body and verify that it arrives correctly.
  EXPECT_EQ(0, callback.WaitForResult());

  // Make sure the stream is properly closed since trailers and data are all
  // consumed.
  EXPECT_TRUE(stream_->IsDoneReading());
  EXPECT_EQ(trailers, trailers_);

  base::RunLoop().RunUntilIdle();
}

// Test that if Read() is called after response body is read and after trailers
// are received but not yet delivered, Read() will return ERR_IO_PENDING instead
// of 0 (EOF).
TEST_P(QuicChromiumClientStreamTest, ReadAfterTrailersReceivedButNotDelivered) {
  InitializeHeaders();
  ProcessHeadersFull(headers_);

  const char data[] = "hello world!";
  int data_len = strlen(data);
  size_t offset = 0;
  std::string header = ConstructDataHeader(data_len);
  stream_->OnStreamFrame(quic::QuicStreamFrame(
      quic::test::GetNthClientInitiatedBidirectionalStreamId(
          version_.transport_version, 0),
      /*fin=*/false,
      /*offset=*/offset, header));
  offset += header.length();
  stream_->OnStreamFrame(quic::QuicStreamFrame(
      quic::test::GetNthClientInitiatedBidirectionalStreamId(
          version_.transport_version, 0),
      /*fin=*/false,
      /*offset=*/offset, data));

  // Read the body and verify that it arrives correctly.
  TestCompletionCallback callback;
  scoped_refptr<IOBuffer> buffer = base::MakeRefCounted<IOBuffer>(2 * data_len);
  EXPECT_EQ(data_len,
            handle_->ReadBody(buffer.get(), 2 * data_len, callback.callback()));
  EXPECT_EQ(absl::string_view(data),
            absl::string_view(buffer->data(), data_len));

  // Deliver trailers. Delegate notification is posted asynchronously.
  spdy::Http2HeaderBlock trailers;
  trailers["bar"] = "foo";

  quic::QuicHeaderList t = ProcessTrailers(trailers);

  EXPECT_FALSE(stream_->IsDoneReading());
  // Read again, it return ERR_IO_PENDING.
  EXPECT_THAT(
      handle_->ReadBody(buffer.get(), 2 * data_len, callback.callback()),
      IsError(ERR_IO_PENDING));

  // Trailers are not delivered
  EXPECT_FALSE(stream_->IsDoneReading());

  TestCompletionCallback callback2;
  EXPECT_EQ(static_cast<int>(t.uncompressed_header_bytes()),
            handle_->ReadTrailingHeaders(&trailers_, callback2.callback()));

  // Read the body and verify that it arrives correctly.
  // OnDataAvailable() should follow right after and Read() will return 0.
  EXPECT_EQ(0, callback.WaitForResult());

  // Make sure the stream is properly closed since trailers and data are all
  // consumed.
  EXPECT_TRUE(stream_->IsDoneReading());

  EXPECT_EQ(trailers, trailers_);

  base::RunLoop().RunUntilIdle();
}

TEST_P(QuicChromiumClientStreamTest, WriteStreamData) {
  testing::InSequence seq;
  const char kData1[] = "hello world";
  const size_t kDataLen = std::size(kData1);

  // All data written.
  std::string header = ConstructDataHeader(kDataLen);
  EXPECT_CALL(session_,
              WritevData(stream_->id(), _, _, _, quic::NOT_RETRANSMISSION, _))
      .WillOnce(Return(quic::QuicConsumedData(header.length(), false)));
  EXPECT_CALL(session_,
              WritevData(stream_->id(), _, _, _, quic::NOT_RETRANSMISSION, _))
      .WillOnce(Return(quic::QuicConsumedData(kDataLen, true)));
  TestCompletionCallback callback;
  EXPECT_EQ(OK, handle_->WriteStreamData(base::StringPiece(kData1, kDataLen),
                                         true, callback.callback()));
}

TEST_P(QuicChromiumClientStreamTest, WriteStreamDataAsync) {
  testing::InSequence seq;
  const char kData1[] = "hello world";
  const size_t kDataLen = std::size(kData1);

  // No data written.
  EXPECT_CALL(session_,
              WritevData(stream_->id(), _, _, _, quic::NOT_RETRANSMISSION, _))
      .WillOnce(Return(quic::QuicConsumedData(0, false)));
  TestCompletionCallback callback;
  EXPECT_EQ(ERR_IO_PENDING,
            handle_->WriteStreamData(base::StringPiece(kData1, kDataLen), true,
                                     callback.callback()));
  ASSERT_FALSE(callback.have_result());

  // All data written.
  std::string header = ConstructDataHeader(kDataLen);
  EXPECT_CALL(session_,
              WritevData(stream_->id(), _, _, _, quic::NOT_RETRANSMISSION, _))
      .WillOnce(Return(quic::QuicConsumedData(header.length(), false)));
  EXPECT_CALL(session_,
              WritevData(stream_->id(), _, _, _, quic::NOT_RETRANSMISSION, _))
      .WillOnce(Return(quic::QuicConsumedData(kDataLen, true)));
  stream_->OnCanWrite();
  // Do 2 writes in version 99.
  stream_->OnCanWrite();
  ASSERT_TRUE(callback.have_result());
  EXPECT_THAT(callback.WaitForResult(), IsOk());
}

TEST_P(QuicChromiumClientStreamTest, WritevStreamData) {
  testing::InSequence seq;
  scoped_refptr<StringIOBuffer> buf1 =
      base::MakeRefCounted<StringIOBuffer>("hello world!");
  scoped_refptr<StringIOBuffer> buf2 =
      base::MakeRefCounted<StringIOBuffer>("Just a small payload");

  // All data written.
  std::string header = ConstructDataHeader(buf1->size());
  EXPECT_CALL(session_,
              WritevData(stream_->id(), _, _, _, quic::NOT_RETRANSMISSION, _))
      .WillOnce(Return(quic::QuicConsumedData(header.length(), false)));
  EXPECT_CALL(session_,
              WritevData(stream_->id(), _, _, _, quic::NOT_RETRANSMISSION, _))
      .WillOnce(Return(quic::QuicConsumedData(buf1->size(), false)));
  header = ConstructDataHeader(buf2->size());
  EXPECT_CALL(session_,
              WritevData(stream_->id(), _, _, _, quic::NOT_RETRANSMISSION, _))
      .WillOnce(Return(quic::QuicConsumedData(header.length(), false)));
  EXPECT_CALL(session_,
              WritevData(stream_->id(), _, _, _, quic::NOT_RETRANSMISSION, _))
      .WillOnce(Return(quic::QuicConsumedData(buf2->size(), true)));
  TestCompletionCallback callback;
  EXPECT_EQ(
      OK, handle_->WritevStreamData({buf1, buf2}, {buf1->size(), buf2->size()},
                                    true, callback.callback()));
}

TEST_P(QuicChromiumClientStreamTest, WritevStreamDataAsync) {
  testing::InSequence seq;
  scoped_refptr<StringIOBuffer> buf1 =
      base::MakeRefCounted<StringIOBuffer>("hello world!");
  scoped_refptr<StringIOBuffer> buf2 =
      base::MakeRefCounted<StringIOBuffer>("Just a small payload");

  // Only a part of the data is written.
  std::string header = ConstructDataHeader(buf1->size());
  EXPECT_CALL(session_,
              WritevData(stream_->id(), _, _, _, quic::NOT_RETRANSMISSION, _))
      .WillOnce(Return(quic::QuicConsumedData(header.length(), false)));
  EXPECT_CALL(session_,
              WritevData(stream_->id(), _, _, _, quic::NOT_RETRANSMISSION, _))
      // First piece of data is written.
      .WillOnce(Return(quic::QuicConsumedData(buf1->size(), false)));
  // Second piece of data is queued.
  EXPECT_CALL(session_,
              WritevData(stream_->id(), _, _, _, quic::NOT_RETRANSMISSION, _))
      .WillOnce(Return(quic::QuicConsumedData(0, false)));
  TestCompletionCallback callback;
  EXPECT_EQ(ERR_IO_PENDING,
            handle_->WritevStreamData({buf1.get(), buf2.get()},
                                      {buf1->size(), buf2->size()}, true,
                                      callback.callback()));
  ASSERT_FALSE(callback.have_result());

  // The second piece of data is written.
  header = ConstructDataHeader(buf2->size());
  EXPECT_CALL(session_,
              WritevData(stream_->id(), _, _, _, quic::NOT_RETRANSMISSION, _))
      .WillOnce(Return(quic::QuicConsumedData(header.length(), false)));
  EXPECT_CALL(session_,
              WritevData(stream_->id(), _, _, _, quic::NOT_RETRANSMISSION, _))
      .WillOnce(Return(quic::QuicConsumedData(buf2->size(), true)));
  stream_->OnCanWrite();
  stream_->OnCanWrite();
  ASSERT_TRUE(callback.have_result());
  EXPECT_THAT(callback.WaitForResult(), IsOk());
}

TEST_P(QuicChromiumClientStreamTest, HeadersBeforeHandle) {
  // We don't use stream_ because we want an incoming server push
  // stream.
  quic::QuicStreamId stream_id = GetNthServerInitiatedUnidirectionalStreamId(0);
  QuicChromiumClientStream* stream2 = new QuicChromiumClientStream(
      stream_id, &session_, quic::READ_UNIDIRECTIONAL, NetLogWithSource(),
      TRAFFIC_ANNOTATION_FOR_TESTS);
  session_.ActivateStream(base::WrapUnique(stream2));

  InitializeHeaders();

  // Receive the headers before the delegate is set.
  quic::QuicHeaderList header_list = quic::test::AsHeaderList(headers_);
  stream2->OnStreamHeaderList(true, header_list.uncompressed_header_bytes(),
                              header_list);

  // Now set the delegate and verify that the headers are delivered.
  handle2_ = stream2->CreateHandle();
  TestCompletionCallback callback;
  EXPECT_EQ(static_cast<int>(header_list.uncompressed_header_bytes()),
            handle2_->ReadInitialHeaders(&headers_, callback.callback()));
  EXPECT_EQ(headers_, headers_);
}

TEST_P(QuicChromiumClientStreamTest, HeadersAndDataBeforeHandle) {
  // We don't use stream_ because we want an incoming server push
  // stream.
  quic::QuicStreamId stream_id = GetNthServerInitiatedUnidirectionalStreamId(0);
  QuicChromiumClientStream* stream2 = new QuicChromiumClientStream(
      stream_id, &session_, quic::READ_UNIDIRECTIONAL, NetLogWithSource(),
      TRAFFIC_ANNOTATION_FOR_TESTS);
  session_.ActivateStream(base::WrapUnique(stream2));

  InitializeHeaders();

  // Receive the headers and data before the delegate is set.
  quic::QuicHeaderList header_list = quic::test::AsHeaderList(headers_);
  stream2->OnStreamHeaderList(false, header_list.uncompressed_header_bytes(),
                              header_list);
  const char data[] = "hello world!";

  size_t offset = 0;
  std::string header = ConstructDataHeader(strlen(data));
  stream2->OnStreamFrame(quic::QuicStreamFrame(stream_id,
                                               /*fin=*/false,
                                               /*offset=*/offset, header));
  offset += header.length();
  stream2->OnStreamFrame(quic::QuicStreamFrame(stream_id, /*fin=*/false,
                                               /*offset=*/offset, data));

  // Now set the delegate and verify that the headers are delivered, but
  // not the data, which needs to be read explicitly.
  handle2_ = stream2->CreateHandle();
  TestCompletionCallback callback;
  EXPECT_EQ(static_cast<int>(header_list.uncompressed_header_bytes()),
            handle2_->ReadInitialHeaders(&headers_, callback.callback()));
  EXPECT_EQ(headers_, headers_);
  base::RunLoop().RunUntilIdle();

  // Now explicitly read the data.
  int data_len = std::size(data) - 1;
  scoped_refptr<IOBuffer> buffer = base::MakeRefCounted<IOBuffer>(data_len + 1);
  ASSERT_EQ(data_len, stream2->Read(buffer.get(), data_len + 1));
  EXPECT_EQ(absl::string_view(data),
            absl::string_view(buffer->data(), data_len));
}

// Regression test for https://crbug.com/1043531.
TEST_P(QuicChromiumClientStreamTest, ResetOnEmptyResponseHeaders) {
  const spdy::Http2HeaderBlock empty_response_headers;
  ProcessHeaders(empty_response_headers);

  // Empty headers are allowed by QuicSpdyStream,
  // but an error is generated by QuicChromiumClientStream.
  int rv = handle_->ReadInitialHeaders(&headers_, CompletionOnceCallback());
  EXPECT_THAT(rv, IsError(net::ERR_QUIC_PROTOCOL_ERROR));
}

// Tests that the stream resets when it receives an invalid ":status"
// pseudo-header value.
TEST_P(QuicChromiumClientStreamTest, InvalidStatus) {
  spdy::Http2HeaderBlock headers = CreateResponseHeaders("xxx");

  EXPECT_CALL(
      *static_cast<quic::test::MockQuicConnection*>(session_.connection()),
      OnStreamReset(quic::test::GetNthClientInitiatedBidirectionalStreamId(
                        version_.transport_version, 0),
                    quic::QUIC_BAD_APPLICATION_PAYLOAD));

  ProcessHeaders(headers);
  EXPECT_FALSE(handle_->IsOpen());
  EXPECT_EQ(quic::QUIC_BAD_APPLICATION_PAYLOAD, handle_->stream_error());
}

// Tests that the stream resets when it receives 101 Switching Protocols.
TEST_P(QuicChromiumClientStreamTest, SwitchingProtocolsResponse) {
  spdy::Http2HeaderBlock informational_headers = CreateResponseHeaders("101");

  EXPECT_CALL(
      *static_cast<quic::test::MockQuicConnection*>(session_.connection()),
      OnStreamReset(quic::test::GetNthClientInitiatedBidirectionalStreamId(
                        version_.transport_version, 0),
                    quic::QUIC_BAD_APPLICATION_PAYLOAD));

  ProcessHeaders(informational_headers);
  EXPECT_FALSE(handle_->IsOpen());
  EXPECT_EQ(quic::QUIC_BAD_APPLICATION_PAYLOAD, handle_->stream_error());
}

// Tests that the stream ignores 100 Continue response.
TEST_P(QuicChromiumClientStreamTest, ContinueResponse) {
  spdy::Http2HeaderBlock informational_headers = CreateResponseHeaders("100");

  // This informational headers should be ignored.
  ProcessHeaders(informational_headers);

  // Pass the initial headers.
  InitializeHeaders();
  quic::QuicHeaderList header_list = ProcessHeaders(headers_);

  // Read the initial headers.
  spdy::Http2HeaderBlock response_headers;
  // Pass DoNothing because the initial headers is already available and the
  // callback won't be called.
  EXPECT_EQ(static_cast<int>(header_list.uncompressed_header_bytes()),
            handle_->ReadInitialHeaders(&response_headers, base::DoNothing()));
  base::RunLoop().RunUntilIdle();

  EXPECT_EQ(response_headers, headers_);
}

// Tests that the stream handles 103 Early Hints responses.
TEST_P(QuicChromiumClientStreamTest, EarlyHintsResponses) {
  // Pass Two Early Hints responses to the stream.
  spdy::Http2HeaderBlock hints1_headers = CreateResponseHeaders("103");
  hints1_headers["x-header1"] = "foo";
  quic::QuicHeaderList header_list = ProcessHeaders(hints1_headers);
  const size_t hints1_bytes = header_list.uncompressed_header_bytes();

  spdy::Http2HeaderBlock hints2_headers = CreateResponseHeaders("103");
  hints2_headers["x-header2"] = "foobarbaz";
  header_list = ProcessHeaders(hints2_headers);
  const size_t hints2_bytes = header_list.uncompressed_header_bytes();

  // Pass the initial headers to the stream.
  InitializeHeaders();
  header_list = ProcessHeaders(headers_);
  const size_t initial_headers_bytes = header_list.uncompressed_header_bytes();

  spdy::Http2HeaderBlock headers;

  // Read headers. The first two reads should return Early Hints.
  EXPECT_EQ(static_cast<int>(hints1_bytes),
            handle_->ReadInitialHeaders(&headers, base::DoNothing()));
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(headers, hints1_headers);
  base::TimeTicks first_early_hints_time = handle_->first_early_hints_time();
  EXPECT_FALSE(first_early_hints_time.is_null());

  EXPECT_EQ(static_cast<int>(hints2_bytes),
            handle_->ReadInitialHeaders(&headers, base::DoNothing()));
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(headers, hints2_headers);
  EXPECT_EQ(first_early_hints_time, handle_->first_early_hints_time());

  // The third read should return the initial headers.
  EXPECT_EQ(static_cast<int>(initial_headers_bytes),
            handle_->ReadInitialHeaders(&headers, base::DoNothing()));
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(headers, headers_);
}

// Tests that pending reads for Early Hints work.
TEST_P(QuicChromiumClientStreamTest, EarlyHintsAsync) {
  spdy::Http2HeaderBlock headers;
  TestCompletionCallback hints_callback;

  // Try to read headers. The read should be blocked.
  EXPECT_EQ(ERR_IO_PENDING,
            handle_->ReadInitialHeaders(&headers, hints_callback.callback()));

  // Pass an Early Hints and the initial headers.
  spdy::Http2HeaderBlock hints_headers = CreateResponseHeaders("103");
  hints_headers["x-header1"] = "foo";
  quic::QuicHeaderList header_list = ProcessHeaders(hints_headers);
  const size_t hints_bytes = header_list.uncompressed_header_bytes();
  InitializeHeaders();
  header_list = ProcessHeaders(headers_);
  const size_t initial_headers_bytes = header_list.uncompressed_header_bytes();

  // Wait for the pending headers read. The result should be the Early Hints.
  const int hints_result = hints_callback.WaitForResult();
  EXPECT_EQ(hints_result, static_cast<int>(hints_bytes));
  EXPECT_EQ(headers, hints_headers);

  // Second read should return the initial headers.
  EXPECT_EQ(static_cast<int>(initial_headers_bytes),
            handle_->ReadInitialHeaders(&headers, base::DoNothing()));
  EXPECT_EQ(headers, headers_);
}

// Tests that Early Hints after the initial headers is treated as an error.
TEST_P(QuicChromiumClientStreamTest, EarlyHintsAfterInitialHeaders) {
  InitializeHeaders();
  ProcessHeadersFull(headers_);

  // Early Hints after the initial headers are treated as trailers, and it
  // should result in an error because trailers must not contain pseudo-headers
  // like ":status".
  EXPECT_CALL(
      *static_cast<quic::test::MockQuicConnection*>(session_.connection()),
      CloseConnection(
          quic::QUIC_INVALID_HEADERS_STREAM_DATA, _,
          quic::ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET));

  spdy::Http2HeaderBlock hints_headers;
  hints_headers[":status"] = "103";
  ProcessHeaders(hints_headers);
  base::RunLoop().RunUntilIdle();
}

// Similar to the above test but don't read the initial headers.
TEST_P(QuicChromiumClientStreamTest, EarlyHintsAfterInitialHeadersWithoutRead) {
  InitializeHeaders();
  ProcessHeaders(headers_);

  // Early Hints after the initial headers are treated as trailers, and it
  // should result in an error because trailers must not contain pseudo-headers
  // like ":status".
  EXPECT_CALL(
      *static_cast<quic::test::MockQuicConnection*>(session_.connection()),
      CloseConnection(
          quic::QUIC_INVALID_HEADERS_STREAM_DATA, _,
          quic::ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET));

  spdy::Http2HeaderBlock hints_headers;
  hints_headers[":status"] = "103";
  ProcessHeaders(hints_headers);
  base::RunLoop().RunUntilIdle();
}

// Regression test for https://crbug.com/1248970. Write an Early Hints headers,
// an initial response headers and trailers in succession without reading in
// the middle of writings.
TEST_P(QuicChromiumClientStreamTest, TrailersAfterEarlyHintsWithoutRead) {
  // Process an Early Hints response headers on the stream.
  spdy::Http2HeaderBlock hints_headers = CreateResponseHeaders("103");
  quic::QuicHeaderList hints_header_list = ProcessHeaders(hints_headers);

  // Process an initial response headers on the stream.
  InitializeHeaders();
  quic::QuicHeaderList header_list = ProcessHeaders(headers_);

  // Process a trailer headers on the stream. This should not hit any DCHECK.
  spdy::Http2HeaderBlock trailers;
  trailers["bar"] = "foo";
  quic::QuicHeaderList trailer_header_list = ProcessTrailers(trailers);
  base::RunLoop().RunUntilIdle();

  // Read the Early Hints response from the handle.
  {
    spdy::Http2HeaderBlock headers;
    TestCompletionCallback callback;
    EXPECT_EQ(static_cast<int>(hints_header_list.uncompressed_header_bytes()),
              handle_->ReadInitialHeaders(&headers, callback.callback()));
    EXPECT_EQ(headers, hints_headers);
  }

  // Read the initial headers from the handle.
  {
    spdy::Http2HeaderBlock headers;
    TestCompletionCallback callback;
    EXPECT_EQ(static_cast<int>(header_list.uncompressed_header_bytes()),
              handle_->ReadInitialHeaders(&headers, callback.callback()));
    EXPECT_EQ(headers, headers_);
  }

  // Read trailers from the handle.
  {
    spdy::Http2HeaderBlock headers;
    TestCompletionCallback callback;
    EXPECT_EQ(static_cast<int>(trailer_header_list.uncompressed_header_bytes()),
              handle_->ReadTrailingHeaders(&headers, callback.callback()));
    EXPECT_EQ(headers, trailers);
  }
}

}  // namespace
}  // namespace net::test
