diff --git a/quic/core/http/end_to_end_test.cc b/quic/core/http/end_to_end_test.cc
new file mode 100644
index 0000000..c26ffa6
--- /dev/null
+++ b/quic/core/http/end_to_end_test.cc
@@ -0,0 +1,3847 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <cstddef>
+#include <cstdint>
+#include <list>
+#include <memory>
+#include <ostream>
+#include <utility>
+#include <vector>
+
+#include "net/third_party/quiche/src/quic/core/crypto/null_encrypter.h"
+#include "net/third_party/quiche/src/quic/core/http/quic_spdy_client_stream.h"
+#include "net/third_party/quiche/src/quic/core/quic_epoll_connection_helper.h"
+#include "net/third_party/quiche/src/quic/core/quic_error_codes.h"
+#include "net/third_party/quiche/src/quic/core/quic_framer.h"
+#include "net/third_party/quiche/src/quic/core/quic_packet_creator.h"
+#include "net/third_party/quiche/src/quic/core/quic_packet_writer_wrapper.h"
+#include "net/third_party/quiche/src/quic/core/quic_packets.h"
+#include "net/third_party/quiche/src/quic/core/quic_session.h"
+#include "net/third_party/quiche/src/quic/core/quic_utils.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_epoll.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_error_code_wrappers.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_expect_bug.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_flags.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_logging.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_port_utils.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_ptr_util.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_sleep.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_socket_address.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_str_cat.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_string.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_string_piece.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_test.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_test_loopback.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_text_utils.h"
+#include "net/quic/platform/impl/quic_socket_utils.h"
+#include "net/third_party/quiche/src/quic/test_tools/bad_packet_writer.h"
+#include "net/third_party/quiche/src/quic/test_tools/crypto_test_utils.h"
+#include "net/third_party/quiche/src/quic/test_tools/packet_dropping_test_writer.h"
+#include "net/third_party/quiche/src/quic/test_tools/packet_reordering_writer.h"
+#include "net/third_party/quiche/src/quic/test_tools/quic_client_peer.h"
+#include "net/third_party/quiche/src/quic/test_tools/quic_config_peer.h"
+#include "net/third_party/quiche/src/quic/test_tools/quic_connection_peer.h"
+#include "net/third_party/quiche/src/quic/test_tools/quic_dispatcher_peer.h"
+#include "net/third_party/quiche/src/quic/test_tools/quic_flow_controller_peer.h"
+#include "net/third_party/quiche/src/quic/test_tools/quic_sent_packet_manager_peer.h"
+#include "net/third_party/quiche/src/quic/test_tools/quic_server_peer.h"
+#include "net/third_party/quiche/src/quic/test_tools/quic_session_peer.h"
+#include "net/third_party/quiche/src/quic/test_tools/quic_spdy_session_peer.h"
+#include "net/third_party/quiche/src/quic/test_tools/quic_stream_id_manager_peer.h"
+#include "net/third_party/quiche/src/quic/test_tools/quic_stream_peer.h"
+#include "net/third_party/quiche/src/quic/test_tools/quic_stream_sequencer_peer.h"
+#include "net/third_party/quiche/src/quic/test_tools/quic_test_client.h"
+#include "net/third_party/quiche/src/quic/test_tools/quic_test_server.h"
+#include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h"
+#include "net/third_party/quiche/src/quic/test_tools/server_thread.h"
+#include "net/third_party/quiche/src/quic/tools/quic_backend_response.h"
+#include "net/third_party/quiche/src/quic/tools/quic_client.h"
+#include "net/third_party/quiche/src/quic/tools/quic_memory_cache_backend.h"
+#include "net/third_party/quiche/src/quic/tools/quic_server.h"
+#include "net/third_party/quiche/src/quic/tools/quic_simple_client_stream.h"
+#include "net/third_party/quiche/src/quic/tools/quic_simple_server_stream.h"
+
+using spdy::kV3LowestPriority;
+using spdy::SETTINGS_MAX_HEADER_LIST_SIZE;
+using spdy::SpdyFramer;
+using spdy::SpdyHeaderBlock;
+using spdy::SpdySerializedFrame;
+using spdy::SpdySettingsIR;
+
+namespace quic {
+namespace test {
+namespace {
+
+const char kFooResponseBody[] = "Artichoke hearts make me happy.";
+const char kBarResponseBody[] = "Palm hearts are pretty delicious, also.";
+const float kSessionToStreamRatio = 1.5;
+
+// Run all tests with the cross products of all versions.
+struct TestParams {
+  TestParams(const ParsedQuicVersionVector& client_supported_versions,
+             const ParsedQuicVersionVector& server_supported_versions,
+             ParsedQuicVersion negotiated_version,
+             bool client_supports_stateless_rejects,
+             bool server_uses_stateless_rejects_if_peer_supported,
+             QuicTag congestion_control_tag,
+             bool use_cheap_stateless_reject)
+      : client_supported_versions(client_supported_versions),
+        server_supported_versions(server_supported_versions),
+        negotiated_version(negotiated_version),
+        client_supports_stateless_rejects(client_supports_stateless_rejects),
+        server_uses_stateless_rejects_if_peer_supported(
+            server_uses_stateless_rejects_if_peer_supported),
+        congestion_control_tag(congestion_control_tag),
+        use_cheap_stateless_reject(use_cheap_stateless_reject) {}
+
+  friend std::ostream& operator<<(std::ostream& os, const TestParams& p) {
+    os << "{ server_supported_versions: "
+       << ParsedQuicVersionVectorToString(p.server_supported_versions);
+    os << " client_supported_versions: "
+       << ParsedQuicVersionVectorToString(p.client_supported_versions);
+    os << " negotiated_version: "
+       << ParsedQuicVersionToString(p.negotiated_version);
+    os << " client_supports_stateless_rejects: "
+       << p.client_supports_stateless_rejects;
+    os << " server_uses_stateless_rejects_if_peer_supported: "
+       << p.server_uses_stateless_rejects_if_peer_supported;
+    os << " congestion_control_tag: "
+       << QuicTagToString(p.congestion_control_tag);
+    os << " use_cheap_stateless_reject: " << p.use_cheap_stateless_reject
+       << " }";
+    return os;
+  }
+
+  ParsedQuicVersionVector client_supported_versions;
+  ParsedQuicVersionVector server_supported_versions;
+  ParsedQuicVersion negotiated_version;
+  bool client_supports_stateless_rejects;
+  bool server_uses_stateless_rejects_if_peer_supported;
+  QuicTag congestion_control_tag;
+  bool use_cheap_stateless_reject;
+};
+
+// Constructs various test permutations.
+std::vector<TestParams> GetTestParams(bool use_tls_handshake,
+                                      bool test_stateless_rejects) {
+  QuicFlagSaver flags;
+  // Divide the versions into buckets in which the intra-frame format
+  // is compatible. When clients encounter QUIC version negotiation
+  // they simply retransmit all packets using the new version's
+  // QUIC framing. However, they are unable to change the intra-frame
+  // layout (for example to change HTTP/2 headers to SPDY/3, or a change in the
+  // handshake protocol). So these tests need to ensure that clients are never
+  // attempting to do 0-RTT across incompatible versions. Chromium only
+  // supports a single version at a time anyway. :)
+  FLAGS_quic_supports_tls_handshake = use_tls_handshake;
+  ParsedQuicVersionVector all_supported_versions =
+      FilterSupportedVersions(AllSupportedVersions());
+
+  // Buckets are separated by versions: versions prior to QUIC_VERSION_47 use
+  // STREAM frames for the handshake, and only have QUIC crypto as the handshake
+  // protocol. Version 47 and greater use CRYPTO frames for the handshake, and
+  // must also be split based on the handshake protocol. If the handshake
+  // protocol (QUIC crypto or TLS) changes, the ClientHello/CHLO must be
+  // reconstructed for the correct protocol.
+  ParsedQuicVersionVector version_buckets[3];
+
+  for (const ParsedQuicVersion& version : all_supported_versions) {
+    if (version.transport_version < QUIC_VERSION_47) {
+      version_buckets[0].push_back(version);
+    } else if (version.handshake_protocol == PROTOCOL_QUIC_CRYPTO) {
+      version_buckets[1].push_back(version);
+    } else {
+      version_buckets[2].push_back(version);
+    }
+  }
+
+  // This must be kept in sync with the number of nested for-loops below as it
+  // is used to prune the number of tests that are run.
+  const int kMaxEnabledOptions = 4;
+  int max_enabled_options = 0;
+  std::vector<TestParams> params;
+  for (const QuicTag congestion_control_tag : {kRENO, kTBBR, kQBIC, kTPCC}) {
+    for (bool server_uses_stateless_rejects_if_peer_supported : {true, false}) {
+      for (bool client_supports_stateless_rejects : {true, false}) {
+        for (bool use_cheap_stateless_reject : {true, false}) {
+          int enabled_options = 0;
+          if (congestion_control_tag != kQBIC) {
+            ++enabled_options;
+          }
+          if (client_supports_stateless_rejects) {
+            ++enabled_options;
+          }
+          if (server_uses_stateless_rejects_if_peer_supported) {
+            ++enabled_options;
+          }
+          if (use_cheap_stateless_reject) {
+            ++enabled_options;
+          }
+          CHECK_GE(kMaxEnabledOptions, enabled_options);
+          if (enabled_options > max_enabled_options) {
+            max_enabled_options = enabled_options;
+          }
+
+          // Run tests with no options, a single option, or all the
+          // options enabled to avoid a combinatorial explosion.
+          if (enabled_options > 1 && enabled_options < kMaxEnabledOptions) {
+            continue;
+          }
+
+          // There are many stateless reject combinations, so don't test them
+          // unless requested.
+          if ((server_uses_stateless_rejects_if_peer_supported ||
+               client_supports_stateless_rejects ||
+               use_cheap_stateless_reject) &&
+              !test_stateless_rejects) {
+            continue;
+          }
+
+          for (const ParsedQuicVersionVector& client_versions :
+               version_buckets) {
+            if (FilterSupportedVersions(client_versions).empty()) {
+              continue;
+            }
+            // Add an entry for server and client supporting all
+            // versions.
+            params.push_back(TestParams(
+                client_versions, all_supported_versions,
+                client_versions.front(), client_supports_stateless_rejects,
+                server_uses_stateless_rejects_if_peer_supported,
+                congestion_control_tag, use_cheap_stateless_reject));
+
+            // Run version negotiation tests tests with no options, or
+            // all the options enabled to avoid a combinatorial
+            // explosion.
+            if (enabled_options > 1 && enabled_options < kMaxEnabledOptions) {
+              continue;
+            }
+
+            // Test client supporting all versions and server supporting
+            // 1 version. Simulate an old server and exercise version
+            // downgrade in the client. Protocol negotiation should
+            // occur.  Skip the i = 0 case because it is essentially the
+            // same as the default case.
+            for (size_t i = 1; i < client_versions.size(); ++i) {
+              ParsedQuicVersionVector server_supported_versions;
+              server_supported_versions.push_back(client_versions[i]);
+              if (FilterSupportedVersions(server_supported_versions).empty()) {
+                continue;
+              }
+              params.push_back(TestParams(
+                  client_versions, server_supported_versions,
+                  server_supported_versions.front(),
+                  client_supports_stateless_rejects,
+                  server_uses_stateless_rejects_if_peer_supported,
+                  congestion_control_tag, use_cheap_stateless_reject));
+            }  // End of inner version loop.
+          }    // End of outer version loop.
+        }      // End of use_cheap_stateless_reject loop.
+      }        // End of client_supports_stateless_rejects loop.
+    }          // End of server_uses_stateless_rejects_if_peer_supported loop.
+  }            // End of congestion_control_tag loop.
+  CHECK_EQ(kMaxEnabledOptions, max_enabled_options);
+  return params;
+}
+
+class ServerDelegate : public PacketDroppingTestWriter::Delegate {
+ public:
+  explicit ServerDelegate(QuicDispatcher* dispatcher)
+      : dispatcher_(dispatcher) {}
+  ~ServerDelegate() override = default;
+  void OnCanWrite() override { dispatcher_->OnCanWrite(); }
+
+ private:
+  QuicDispatcher* dispatcher_;
+};
+
+class ClientDelegate : public PacketDroppingTestWriter::Delegate {
+ public:
+  explicit ClientDelegate(QuicClient* client) : client_(client) {}
+  ~ClientDelegate() override = default;
+  void OnCanWrite() override {
+    QuicEpollEvent event(EPOLLOUT);
+    client_->epoll_network_helper()->OnEvent(client_->GetLatestFD(), &event);
+  }
+
+ private:
+  QuicClient* client_;
+};
+
+class EndToEndTest : public QuicTestWithParam<TestParams> {
+ protected:
+  EndToEndTest()
+      : initialized_(false),
+        connect_to_server_on_initialize_(true),
+        server_address_(
+            QuicSocketAddress(TestLoopback(), QuicPickUnusedPortOrDie())),
+        server_hostname_("test.example.com"),
+        client_writer_(nullptr),
+        server_writer_(nullptr),
+        negotiated_version_(UnsupportedQuicVersion()),
+        chlo_multiplier_(0),
+        stream_factory_(nullptr),
+        support_server_push_(false),
+        override_connection_id_(nullptr) {
+    FLAGS_quic_supports_tls_handshake = true;
+    SetQuicRestartFlag(quic_no_server_conn_ver_negotiation2, true);
+    SetQuicReloadableFlag(quic_no_client_conn_ver_negotiation, true);
+    client_supported_versions_ = GetParam().client_supported_versions;
+    server_supported_versions_ = GetParam().server_supported_versions;
+    negotiated_version_ = GetParam().negotiated_version;
+
+    QUIC_LOG(INFO) << "Using Configuration: " << GetParam();
+
+    // Use different flow control windows for client/server.
+    client_config_.SetInitialStreamFlowControlWindowToSend(
+        2 * kInitialStreamFlowControlWindowForTest);
+    client_config_.SetInitialSessionFlowControlWindowToSend(
+        2 * kInitialSessionFlowControlWindowForTest);
+    server_config_.SetInitialStreamFlowControlWindowToSend(
+        3 * kInitialStreamFlowControlWindowForTest);
+    server_config_.SetInitialSessionFlowControlWindowToSend(
+        3 * kInitialSessionFlowControlWindowForTest);
+
+    // The default idle timeouts can be too strict when running on a busy
+    // machine.
+    const QuicTime::Delta timeout = QuicTime::Delta::FromSeconds(30);
+    client_config_.set_max_time_before_crypto_handshake(timeout);
+    client_config_.set_max_idle_time_before_crypto_handshake(timeout);
+    server_config_.set_max_time_before_crypto_handshake(timeout);
+    server_config_.set_max_idle_time_before_crypto_handshake(timeout);
+
+    AddToCache("/foo", 200, kFooResponseBody);
+    AddToCache("/bar", 200, kBarResponseBody);
+  }
+
+  ~EndToEndTest() override { QuicRecyclePort(server_address_.port()); }
+
+  virtual void CreateClientWithWriter() {
+    client_.reset(CreateQuicClient(client_writer_));
+  }
+
+  QuicTestClient* CreateQuicClient(QuicPacketWriterWrapper* writer) {
+    QuicTestClient* client =
+        new QuicTestClient(server_address_, server_hostname_, client_config_,
+                           client_supported_versions_,
+                           crypto_test_utils::ProofVerifierForTesting());
+    client->UseWriter(writer);
+    if (!pre_shared_key_client_.empty()) {
+      client->client()->SetPreSharedKey(pre_shared_key_client_);
+    }
+    if (override_connection_id_ != nullptr) {
+      client->UseConnectionId(*override_connection_id_);
+    }
+    client->Connect();
+    return client;
+  }
+
+  void set_smaller_flow_control_receive_window() {
+    const uint32_t kClientIFCW = 64 * 1024;
+    const uint32_t kServerIFCW = 1024 * 1024;
+    set_client_initial_stream_flow_control_receive_window(kClientIFCW);
+    set_client_initial_session_flow_control_receive_window(
+        kSessionToStreamRatio * kClientIFCW);
+    set_server_initial_stream_flow_control_receive_window(kServerIFCW);
+    set_server_initial_session_flow_control_receive_window(
+        kSessionToStreamRatio * kServerIFCW);
+  }
+
+  void set_client_initial_stream_flow_control_receive_window(uint32_t window) {
+    CHECK(client_ == nullptr);
+    QUIC_DLOG(INFO) << "Setting client initial stream flow control window: "
+                    << window;
+    client_config_.SetInitialStreamFlowControlWindowToSend(window);
+  }
+
+  void set_client_initial_session_flow_control_receive_window(uint32_t window) {
+    CHECK(client_ == nullptr);
+    QUIC_DLOG(INFO) << "Setting client initial session flow control window: "
+                    << window;
+    client_config_.SetInitialSessionFlowControlWindowToSend(window);
+  }
+
+  void set_server_initial_stream_flow_control_receive_window(uint32_t window) {
+    CHECK(server_thread_ == nullptr);
+    QUIC_DLOG(INFO) << "Setting server initial stream flow control window: "
+                    << window;
+    server_config_.SetInitialStreamFlowControlWindowToSend(window);
+  }
+
+  void set_server_initial_session_flow_control_receive_window(uint32_t window) {
+    CHECK(server_thread_ == nullptr);
+    QUIC_DLOG(INFO) << "Setting server initial session flow control window: "
+                    << window;
+    server_config_.SetInitialSessionFlowControlWindowToSend(window);
+  }
+
+  const QuicSentPacketManager* GetSentPacketManagerFromFirstServerSession() {
+    return &GetServerConnection()->sent_packet_manager();
+  }
+
+  QuicConnection* GetServerConnection() {
+    return GetServerSession()->connection();
+  }
+
+  QuicSession* GetServerSession() {
+    QuicDispatcher* dispatcher =
+        QuicServerPeer::GetDispatcher(server_thread_->server());
+    EXPECT_EQ(1u, dispatcher->session_map().size());
+    return dispatcher->session_map().begin()->second.get();
+  }
+
+  bool Initialize() {
+    QuicTagVector copt;
+    server_config_.SetConnectionOptionsToSend(copt);
+    copt = client_extra_copts_;
+
+    // TODO(nimia): Consider setting the congestion control algorithm for the
+    // client as well according to the test parameter.
+    copt.push_back(GetParam().congestion_control_tag);
+    if (GetParam().congestion_control_tag == kTPCC &&
+        GetQuicReloadableFlag(quic_enable_pcc3)) {
+      copt.push_back(kTPCC);
+    }
+
+    if (GetParam().client_supports_stateless_rejects) {
+      copt.push_back(kSREJ);
+    }
+    client_config_.SetConnectionOptionsToSend(copt);
+
+    // Start the server first, because CreateQuicClient() attempts
+    // to connect to the server.
+    StartServer();
+
+    if (!connect_to_server_on_initialize_) {
+      initialized_ = true;
+      return true;
+    }
+
+    CreateClientWithWriter();
+    static QuicEpollEvent event(EPOLLOUT);
+    if (client_writer_ != nullptr) {
+      client_writer_->Initialize(
+          QuicConnectionPeer::GetHelper(
+              client_->client()->client_session()->connection()),
+          QuicConnectionPeer::GetAlarmFactory(
+              client_->client()->client_session()->connection()),
+          QuicMakeUnique<ClientDelegate>(client_->client()));
+    }
+    initialized_ = true;
+    return client_->client()->connected();
+  }
+
+  void SetUp() override {
+    // The ownership of these gets transferred to the QuicPacketWriterWrapper
+    // when Initialize() is executed.
+    client_writer_ = new PacketDroppingTestWriter();
+    server_writer_ = new PacketDroppingTestWriter();
+  }
+
+  void TearDown() override {
+    ASSERT_TRUE(initialized_) << "You must call Initialize() in every test "
+                              << "case. Otherwise, your test will leak memory.";
+    StopServer();
+  }
+
+  void StartServer() {
+    SetQuicReloadableFlag(quic_use_cheap_stateless_rejects,
+                          GetParam().use_cheap_stateless_reject);
+
+    uint8_t connection_id_length = override_connection_id_ != nullptr
+                                       ? override_connection_id_->length()
+                                       : kQuicDefaultConnectionIdLength;
+    auto* test_server =
+        new QuicTestServer(crypto_test_utils::ProofSourceForTesting(),
+                           server_config_, server_supported_versions_,
+                           &memory_cache_backend_, connection_id_length);
+    server_thread_ = QuicMakeUnique<ServerThread>(test_server, server_address_);
+    if (chlo_multiplier_ != 0) {
+      server_thread_->server()->SetChloMultiplier(chlo_multiplier_);
+    }
+    if (!pre_shared_key_server_.empty()) {
+      server_thread_->server()->SetPreSharedKey(pre_shared_key_server_);
+    }
+    server_thread_->Initialize();
+    QuicDispatcher* dispatcher =
+        QuicServerPeer::GetDispatcher(server_thread_->server());
+    QuicDispatcherPeer::UseWriter(dispatcher, server_writer_);
+
+    SetQuicReloadableFlag(
+        enable_quic_stateless_reject_support,
+        GetParam().server_uses_stateless_rejects_if_peer_supported);
+
+    server_writer_->Initialize(QuicDispatcherPeer::GetHelper(dispatcher),
+                               QuicDispatcherPeer::GetAlarmFactory(dispatcher),
+                               QuicMakeUnique<ServerDelegate>(dispatcher));
+    if (stream_factory_ != nullptr) {
+      static_cast<QuicTestServer*>(server_thread_->server())
+          ->SetSpdyStreamFactory(stream_factory_);
+    }
+
+    server_thread_->Start();
+  }
+
+  void StopServer() {
+    if (server_thread_) {
+      server_thread_->Quit();
+      server_thread_->Join();
+    }
+  }
+
+  void AddToCache(QuicStringPiece path,
+                  int response_code,
+                  QuicStringPiece body) {
+    memory_cache_backend_.AddSimpleResponse(server_hostname_, path,
+                                            response_code, body);
+  }
+
+  void SetPacketLossPercentage(int32_t loss) {
+    client_writer_->set_fake_packet_loss_percentage(loss);
+    server_writer_->set_fake_packet_loss_percentage(loss);
+  }
+
+  void SetPacketSendDelay(QuicTime::Delta delay) {
+    client_writer_->set_fake_packet_delay(delay);
+    server_writer_->set_fake_packet_delay(delay);
+  }
+
+  void SetReorderPercentage(int32_t reorder) {
+    client_writer_->set_fake_reorder_percentage(reorder);
+    server_writer_->set_fake_reorder_percentage(reorder);
+  }
+
+  // Verifies that the client and server connections were both free of packets
+  // being discarded, based on connection stats.
+  // Calls server_thread_ Pause() and Resume(), which may only be called once
+  // per test.
+  void VerifyCleanConnection(bool had_packet_loss) {
+    QuicConnectionStats client_stats =
+        client_->client()->client_session()->connection()->GetStats();
+    // TODO(ianswett): Determine why this becomes even more flaky with BBR
+    // enabled.  b/62141144
+    if (!had_packet_loss && !GetQuicReloadableFlag(quic_default_to_bbr)) {
+      EXPECT_EQ(0u, client_stats.packets_lost);
+    }
+    EXPECT_EQ(0u, client_stats.packets_discarded);
+    // When doing 0-RTT with stateless rejects, the encrypted requests cause
+    // a retranmission of the SREJ packets which are dropped by the client.
+    // When client starts with an unsupported version, the version negotiation
+    // packet sent by server for the old connection (respond for the connection
+    // close packet) will be dropped by the client.
+    if (!BothSidesSupportStatelessRejects() &&
+        !ServerSendsVersionNegotiation()) {
+      EXPECT_EQ(0u, client_stats.packets_dropped);
+    }
+    if (!ClientSupportsIetfQuicNotSupportedByServer()) {
+      // In this case, if client sends 0-RTT POST with v99, receives IETF
+      // version negotiation packet and speaks a GQUIC version. Server processes
+      // this connection in time wait list and keeps sending IETF version
+      // negotiation packet for incoming packets. But these version negotiation
+      // packets cannot be processed by the client speaking GQUIC.
+      EXPECT_EQ(client_stats.packets_received, client_stats.packets_processed);
+    }
+
+    const int num_expected_stateless_rejects =
+        (BothSidesSupportStatelessRejects() &&
+         client_->client()->client_session()->GetNumSentClientHellos() > 0)
+            ? 1
+            : 0;
+    EXPECT_EQ(num_expected_stateless_rejects,
+              client_->client()->num_stateless_rejects_received());
+
+    server_thread_->Pause();
+    QuicConnectionStats server_stats = GetServerConnection()->GetStats();
+    if (!had_packet_loss) {
+      EXPECT_EQ(0u, server_stats.packets_lost);
+    }
+    EXPECT_EQ(0u, server_stats.packets_discarded);
+    // TODO(ianswett): Restore the check for packets_dropped equals 0.
+    // The expect for packets received is equal to packets processed fails
+    // due to version negotiation packets.
+    server_thread_->Resume();
+  }
+
+  bool BothSidesSupportStatelessRejects() {
+    return (GetParam().server_uses_stateless_rejects_if_peer_supported &&
+            GetParam().client_supports_stateless_rejects);
+  }
+
+  // Client supports IETF QUIC, while it is not supported by server.
+  bool ClientSupportsIetfQuicNotSupportedByServer() {
+    return GetParam().client_supported_versions[0].transport_version >
+               QUIC_VERSION_43 &&
+           FilterSupportedVersions(GetParam().server_supported_versions)[0]
+                   .transport_version <= QUIC_VERSION_43;
+  }
+
+  // Returns true when client starts with an unsupported version, and client
+  // closes connection when version negotiation is received.
+  bool ServerSendsVersionNegotiation() {
+    return GetQuicReloadableFlag(quic_no_client_conn_ver_negotiation) &&
+           GetParam().client_supported_versions[0] !=
+               GetParam().negotiated_version;
+  }
+
+  bool SupportsIetfQuicWithTls(ParsedQuicVersion version) {
+    return version.transport_version > QUIC_VERSION_43 &&
+           version.handshake_protocol == PROTOCOL_TLS1_3;
+  }
+
+  void ExpectFlowControlsSynced(QuicFlowController* client,
+                                QuicFlowController* server) {
+    EXPECT_EQ(QuicFlowControllerPeer::SendWindowSize(client),
+              QuicFlowControllerPeer::ReceiveWindowSize(server));
+    EXPECT_EQ(QuicFlowControllerPeer::ReceiveWindowSize(client),
+              QuicFlowControllerPeer::SendWindowSize(server));
+  }
+
+  // Must be called before Initialize to have effect.
+  void SetSpdyStreamFactory(QuicTestServer::StreamFactory* factory) {
+    stream_factory_ = factory;
+  }
+
+  QuicStreamId GetNthClientInitiatedBidirectionalId(int n) {
+    return GetNthClientInitiatedBidirectionalStreamId(
+        client_->client()->client_session()->connection()->transport_version(),
+        n);
+  }
+
+  QuicStreamId GetNthServerInitiatedBidirectionalId(int n) {
+    return GetNthServerInitiatedBidirectionalStreamId(
+        client_->client()->client_session()->connection()->transport_version(),
+        n);
+  }
+
+  ScopedEnvironmentForThreads environment_;
+  bool initialized_;
+  // If true, the Initialize() function will create |client_| and starts to
+  // connect to the server.
+  // Default is true.
+  bool connect_to_server_on_initialize_;
+  QuicSocketAddress server_address_;
+  QuicString server_hostname_;
+  QuicMemoryCacheBackend memory_cache_backend_;
+  std::unique_ptr<ServerThread> server_thread_;
+  std::unique_ptr<QuicTestClient> client_;
+  PacketDroppingTestWriter* client_writer_;
+  PacketDroppingTestWriter* server_writer_;
+  QuicConfig client_config_;
+  QuicConfig server_config_;
+  ParsedQuicVersionVector client_supported_versions_;
+  ParsedQuicVersionVector server_supported_versions_;
+  QuicTagVector client_extra_copts_;
+  ParsedQuicVersion negotiated_version_;
+  size_t chlo_multiplier_;
+  QuicTestServer::StreamFactory* stream_factory_;
+  bool support_server_push_;
+  QuicString pre_shared_key_client_;
+  QuicString pre_shared_key_server_;
+  QuicConnectionId* override_connection_id_;
+};
+
+// Run all end to end tests with all supported versions.
+INSTANTIATE_TEST_SUITE_P(EndToEndTests,
+                         EndToEndTest,
+                         ::testing::ValuesIn(GetTestParams(false, false)));
+
+class EndToEndTestWithTls : public EndToEndTest {};
+
+INSTANTIATE_TEST_SUITE_P(EndToEndTestsWithTls,
+                         EndToEndTestWithTls,
+                         ::testing::ValuesIn(GetTestParams(true, false)));
+
+class EndToEndTestWithStatelessReject : public EndToEndTest {};
+
+INSTANTIATE_TEST_SUITE_P(WithStatelessReject,
+                         EndToEndTestWithStatelessReject,
+                         ::testing::ValuesIn(GetTestParams(false, true)));
+
+TEST_P(EndToEndTestWithTls, HandshakeSuccessful) {
+  ASSERT_TRUE(Initialize());
+  EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
+  server_thread_->WaitForCryptoHandshakeConfirmed();
+  // There have been occasions where it seemed that negotiated_version_ and the
+  // version in the connection are not in sync. If it is happening, it has not
+  // been recreatable; this assert is here just to check and raise a flag if it
+  // happens.
+  ASSERT_EQ(
+      client_->client()->client_session()->connection()->transport_version(),
+      negotiated_version_.transport_version);
+
+  QuicCryptoStream* crypto_stream = QuicSessionPeer::GetMutableCryptoStream(
+      client_->client()->client_session());
+  QuicStreamSequencer* sequencer = QuicStreamPeer::sequencer(crypto_stream);
+  EXPECT_FALSE(QuicStreamSequencerPeer::IsUnderlyingBufferAllocated(sequencer));
+  server_thread_->Pause();
+  crypto_stream = QuicSessionPeer::GetMutableCryptoStream(GetServerSession());
+  sequencer = QuicStreamPeer::sequencer(crypto_stream);
+  EXPECT_FALSE(QuicStreamSequencerPeer::IsUnderlyingBufferAllocated(sequencer));
+}
+
+TEST_P(EndToEndTestWithStatelessReject, SimpleRequestResponseStatless) {
+  ASSERT_TRUE(Initialize());
+
+  EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
+  EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
+  int expected_num_client_hellos = 2;
+  if (ServerSendsVersionNegotiation()) {
+    ++expected_num_client_hellos;
+    if (BothSidesSupportStatelessRejects()) {
+      ++expected_num_client_hellos;
+    }
+  }
+  EXPECT_EQ(expected_num_client_hellos,
+            client_->client()->GetNumSentClientHellos());
+}
+
+TEST_P(EndToEndTest, SimpleRequestResponse) {
+  ASSERT_TRUE(Initialize());
+
+  EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
+  EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
+  int expected_num_client_hellos = 2;
+  if (ServerSendsVersionNegotiation()) {
+    ++expected_num_client_hellos;
+    if (BothSidesSupportStatelessRejects()) {
+      ++expected_num_client_hellos;
+    }
+  }
+  EXPECT_EQ(expected_num_client_hellos,
+            client_->client()->GetNumSentClientHellos());
+}
+
+TEST_P(EndToEndTest, SimpleRequestResponseZeroConnectionID) {
+  QuicConnectionId connection_id = QuicUtils::CreateZeroConnectionId(
+      GetParam().negotiated_version.transport_version);
+  override_connection_id_ = &connection_id;
+  ASSERT_TRUE(Initialize());
+
+  EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
+  EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
+  int expected_num_client_hellos = 2;
+  if (ServerSendsVersionNegotiation()) {
+    ++expected_num_client_hellos;
+    if (BothSidesSupportStatelessRejects()) {
+      ++expected_num_client_hellos;
+    }
+  }
+  EXPECT_EQ(expected_num_client_hellos,
+            client_->client()->GetNumSentClientHellos());
+  EXPECT_EQ(client_->client()->client_session()->connection()->connection_id(),
+            QuicUtils::CreateZeroConnectionId(
+                GetParam().negotiated_version.transport_version));
+}
+
+TEST_P(EndToEndTest, SimpleRequestResponseWithLargeReject) {
+  chlo_multiplier_ = 1;
+  ASSERT_TRUE(Initialize());
+
+  EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
+  EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
+  if (ServerSendsVersionNegotiation()) {
+    EXPECT_EQ(4, client_->client()->GetNumSentClientHellos());
+  } else {
+    EXPECT_EQ(3, client_->client()->GetNumSentClientHellos());
+  }
+}
+
+TEST_P(EndToEndTestWithTls, SimpleRequestResponsev6) {
+  server_address_ =
+      QuicSocketAddress(QuicIpAddress::Loopback6(), server_address_.port());
+  ASSERT_TRUE(Initialize());
+
+  EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
+  EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
+}
+
+TEST_P(EndToEndTestWithTls, SeparateFinPacket) {
+  ASSERT_TRUE(Initialize());
+
+  // Send a request in two parts: the request and then an empty packet with FIN.
+  SpdyHeaderBlock headers;
+  headers[":method"] = "POST";
+  headers[":path"] = "/foo";
+  headers[":scheme"] = "https";
+  headers[":authority"] = server_hostname_;
+  client_->SendMessage(headers, "", /*fin=*/false);
+  client_->SendData("", true);
+  client_->WaitForResponse();
+  EXPECT_EQ(kFooResponseBody, client_->response_body());
+  EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
+
+  // Now do the same thing but with a content length.
+  headers["content-length"] = "3";
+  client_->SendMessage(headers, "", /*fin=*/false);
+  client_->SendData("foo", true);
+  client_->WaitForResponse();
+  EXPECT_EQ(kFooResponseBody, client_->response_body());
+  EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
+}
+
+TEST_P(EndToEndTestWithTls, MultipleRequestResponse) {
+  ASSERT_TRUE(Initialize());
+
+  EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
+  EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
+  EXPECT_EQ(kBarResponseBody, client_->SendSynchronousRequest("/bar"));
+  EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
+}
+
+TEST_P(EndToEndTest, MultipleRequestResponseZeroConnectionID) {
+  QuicConnectionId connection_id = QuicUtils::CreateZeroConnectionId(
+      GetParam().negotiated_version.transport_version);
+  override_connection_id_ = &connection_id;
+  ASSERT_TRUE(Initialize());
+
+  EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
+  EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
+  EXPECT_EQ(kBarResponseBody, client_->SendSynchronousRequest("/bar"));
+  EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
+}
+
+TEST_P(EndToEndTestWithTls, MultipleStreams) {
+  // Verifies quic_test_client can track responses of all active streams.
+  ASSERT_TRUE(Initialize());
+
+  const int kNumRequests = 10;
+
+  SpdyHeaderBlock headers;
+  headers[":method"] = "POST";
+  headers[":path"] = "/foo";
+  headers[":scheme"] = "https";
+  headers[":authority"] = server_hostname_;
+  headers["content-length"] = "3";
+
+  for (int i = 0; i < kNumRequests; ++i) {
+    client_->SendMessage(headers, "bar", /*fin=*/true);
+  }
+
+  while (kNumRequests > client_->num_responses()) {
+    client_->ClearPerRequestState();
+    client_->WaitForResponse();
+    EXPECT_EQ(kFooResponseBody, client_->response_body());
+    EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
+  }
+}
+
+TEST_P(EndToEndTestWithTls, MultipleClients) {
+  ASSERT_TRUE(Initialize());
+  std::unique_ptr<QuicTestClient> client2(CreateQuicClient(nullptr));
+
+  SpdyHeaderBlock headers;
+  headers[":method"] = "POST";
+  headers[":path"] = "/foo";
+  headers[":scheme"] = "https";
+  headers[":authority"] = server_hostname_;
+  headers["content-length"] = "3";
+
+  client_->SendMessage(headers, "", /*fin=*/false);
+  client2->SendMessage(headers, "", /*fin=*/false);
+
+  client_->SendData("bar", true);
+  client_->WaitForResponse();
+  EXPECT_EQ(kFooResponseBody, client_->response_body());
+  EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
+
+  client2->SendData("eep", true);
+  client2->WaitForResponse();
+  EXPECT_EQ(kFooResponseBody, client2->response_body());
+  EXPECT_EQ("200", client2->response_headers()->find(":status")->second);
+}
+
+TEST_P(EndToEndTestWithTls, RequestOverMultiplePackets) {
+  // Send a large enough request to guarantee fragmentation.
+  QuicString huge_request =
+      "/some/path?query=" + QuicString(kMaxPacketSize, '.');
+  AddToCache(huge_request, 200, kBarResponseBody);
+
+  ASSERT_TRUE(Initialize());
+
+  EXPECT_EQ(kBarResponseBody, client_->SendSynchronousRequest(huge_request));
+  EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
+}
+
+TEST_P(EndToEndTestWithTls, MultiplePacketsRandomOrder) {
+  // Send a large enough request to guarantee fragmentation.
+  QuicString huge_request =
+      "/some/path?query=" + QuicString(kMaxPacketSize, '.');
+  AddToCache(huge_request, 200, kBarResponseBody);
+
+  ASSERT_TRUE(Initialize());
+  SetPacketSendDelay(QuicTime::Delta::FromMilliseconds(2));
+  SetReorderPercentage(50);
+
+  EXPECT_EQ(kBarResponseBody, client_->SendSynchronousRequest(huge_request));
+  EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
+}
+
+TEST_P(EndToEndTestWithTls, PostMissingBytes) {
+  ASSERT_TRUE(Initialize());
+
+  // Add a content length header with no body.
+  SpdyHeaderBlock headers;
+  headers[":method"] = "POST";
+  headers[":path"] = "/foo";
+  headers[":scheme"] = "https";
+  headers[":authority"] = server_hostname_;
+  headers["content-length"] = "3";
+
+  // This should be detected as stream fin without complete request,
+  // triggering an error response.
+  client_->SendCustomSynchronousRequest(headers, "");
+  EXPECT_EQ(QuicSimpleServerStream::kErrorResponseBody,
+            client_->response_body());
+  EXPECT_EQ("500", client_->response_headers()->find(":status")->second);
+}
+
+TEST_P(EndToEndTest, LargePostNoPacketLoss) {
+  ASSERT_TRUE(Initialize());
+
+  EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
+
+  // 1 MB body.
+  QuicString body(1024 * 1024, 'a');
+  SpdyHeaderBlock headers;
+  headers[":method"] = "POST";
+  headers[":path"] = "/foo";
+  headers[":scheme"] = "https";
+  headers[":authority"] = server_hostname_;
+
+  EXPECT_EQ(kFooResponseBody,
+            client_->SendCustomSynchronousRequest(headers, body));
+  // TODO(ianswett): There should not be packet loss in this test, but on some
+  // platforms the receive buffer overflows.
+  VerifyCleanConnection(true);
+}
+
+TEST_P(EndToEndTest, LargePostNoPacketLoss1sRTT) {
+  ASSERT_TRUE(Initialize());
+  SetPacketSendDelay(QuicTime::Delta::FromMilliseconds(1000));
+
+  EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
+
+  // 100 KB body.
+  QuicString body(100 * 1024, 'a');
+  SpdyHeaderBlock headers;
+  headers[":method"] = "POST";
+  headers[":path"] = "/foo";
+  headers[":scheme"] = "https";
+  headers[":authority"] = server_hostname_;
+
+  EXPECT_EQ(kFooResponseBody,
+            client_->SendCustomSynchronousRequest(headers, body));
+  VerifyCleanConnection(false);
+}
+
+TEST_P(EndToEndTest, LargePostWithPacketLoss) {
+  if (!BothSidesSupportStatelessRejects()) {
+    // Connect with lower fake packet loss than we'd like to test.
+    // Until b/10126687 is fixed, losing handshake packets is pretty
+    // brutal.
+    // TODO(jokulik): Until we support redundant SREJ packets, don't
+    // drop handshake packets for stateless rejects.
+    SetPacketLossPercentage(5);
+  }
+  ASSERT_TRUE(Initialize());
+
+  // Wait for the server SHLO before upping the packet loss.
+  EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
+  SetPacketLossPercentage(30);
+
+  // 10 KB body.
+  QuicString body(1024 * 10, 'a');
+  SpdyHeaderBlock headers;
+  headers[":method"] = "POST";
+  headers[":path"] = "/foo";
+  headers[":scheme"] = "https";
+  headers[":authority"] = server_hostname_;
+
+  EXPECT_EQ(kFooResponseBody,
+            client_->SendCustomSynchronousRequest(headers, body));
+  VerifyCleanConnection(true);
+}
+
+// Regression test for b/80090281.
+TEST_P(EndToEndTest, LargePostWithPacketLossAndAlwaysBundleWindowUpdates) {
+  ASSERT_TRUE(Initialize());
+
+  // Wait for the server SHLO before upping the packet loss.
+  EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
+  server_thread_->WaitForCryptoHandshakeConfirmed();
+
+  // Normally server only bundles a retransmittable frame once every other
+  // kMaxConsecutiveNonRetransmittablePackets ack-only packets. Setting the max
+  // to 0 to reliably reproduce b/80090281.
+  server_thread_->Schedule([this]() {
+    QuicConnectionPeer::SetMaxConsecutiveNumPacketsWithNoRetransmittableFrames(
+        GetServerConnection(), 0);
+  });
+
+  SetPacketLossPercentage(30);
+
+  // 10 KB body.
+  QuicString body(1024 * 10, 'a');
+  SpdyHeaderBlock headers;
+  headers[":method"] = "POST";
+  headers[":path"] = "/foo";
+  headers[":scheme"] = "https";
+  headers[":authority"] = server_hostname_;
+
+  EXPECT_EQ(kFooResponseBody,
+            client_->SendCustomSynchronousRequest(headers, body));
+  VerifyCleanConnection(true);
+}
+
+TEST_P(EndToEndTest, LargePostWithPacketLossAndBlockedSocket) {
+  if (!BothSidesSupportStatelessRejects()) {
+    // Connect with lower fake packet loss than we'd like to test.  Until
+    // b/10126687 is fixed, losing handshake packets is pretty brutal.
+    // TODO(jokulik): Until we support redundant SREJ packets, don't
+    // drop handshake packets for stateless rejects.
+    SetPacketLossPercentage(5);
+  }
+  ASSERT_TRUE(Initialize());
+
+  // Wait for the server SHLO before upping the packet loss.
+  EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
+  SetPacketLossPercentage(10);
+  client_writer_->set_fake_blocked_socket_percentage(10);
+
+  // 10 KB body.
+  QuicString body(1024 * 10, 'a');
+  SpdyHeaderBlock headers;
+  headers[":method"] = "POST";
+  headers[":path"] = "/foo";
+  headers[":scheme"] = "https";
+  headers[":authority"] = server_hostname_;
+
+  EXPECT_EQ(kFooResponseBody,
+            client_->SendCustomSynchronousRequest(headers, body));
+}
+
+TEST_P(EndToEndTest, LargePostNoPacketLossWithDelayAndReordering) {
+  ASSERT_TRUE(Initialize());
+
+  EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
+  // Both of these must be called when the writer is not actively used.
+  SetPacketSendDelay(QuicTime::Delta::FromMilliseconds(2));
+  SetReorderPercentage(30);
+
+  // 1 MB body.
+  QuicString body(1024 * 1024, 'a');
+  SpdyHeaderBlock headers;
+  headers[":method"] = "POST";
+  headers[":path"] = "/foo";
+  headers[":scheme"] = "https";
+  headers[":authority"] = server_hostname_;
+
+  EXPECT_EQ(kFooResponseBody,
+            client_->SendCustomSynchronousRequest(headers, body));
+}
+
+TEST_P(EndToEndTest, LargePostZeroRTTFailure) {
+  // Send a request and then disconnect. This prepares the client to attempt
+  // a 0-RTT handshake for the next request.
+  ASSERT_TRUE(Initialize());
+
+  QuicString body(20480, 'a');
+  SpdyHeaderBlock headers;
+  headers[":method"] = "POST";
+  headers[":path"] = "/foo";
+  headers[":scheme"] = "https";
+  headers[":authority"] = server_hostname_;
+
+  EXPECT_EQ(kFooResponseBody,
+            client_->SendCustomSynchronousRequest(headers, body));
+  // In the non-stateless case, the same session is used for both
+  // hellos, so the number of hellos sent on that session is 2.  In
+  // the stateless case, the first client session will be completely
+  // torn down after the reject.  The number of hellos on the latest
+  // session is 1.
+  const int expected_num_hellos_latest_session =
+      (BothSidesSupportStatelessRejects() && !ServerSendsVersionNegotiation())
+          ? 1
+          : 2;
+  EXPECT_EQ(expected_num_hellos_latest_session,
+            client_->client()->client_session()->GetNumSentClientHellos());
+  if (ServerSendsVersionNegotiation()) {
+    EXPECT_EQ(3, client_->client()->GetNumSentClientHellos());
+  } else {
+    EXPECT_EQ(2, client_->client()->GetNumSentClientHellos());
+  }
+
+  client_->Disconnect();
+
+  // The 0-RTT handshake should succeed.
+  client_->Connect();
+  EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
+  ASSERT_TRUE(client_->client()->connected());
+  EXPECT_EQ(kFooResponseBody,
+            client_->SendCustomSynchronousRequest(headers, body));
+
+  EXPECT_EQ(1, client_->client()->client_session()->GetNumSentClientHellos());
+  if (ServerSendsVersionNegotiation()) {
+    EXPECT_EQ(2, client_->client()->GetNumSentClientHellos());
+  } else {
+    EXPECT_EQ(1, client_->client()->GetNumSentClientHellos());
+  }
+
+  client_->Disconnect();
+
+  // Restart the server so that the 0-RTT handshake will take 1 RTT.
+  StopServer();
+  server_writer_ = new PacketDroppingTestWriter();
+  StartServer();
+
+  client_->Connect();
+  EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
+  ASSERT_TRUE(client_->client()->connected());
+  EXPECT_EQ(kFooResponseBody,
+            client_->SendCustomSynchronousRequest(headers, body));
+  // In the non-stateless case, the same session is used for both
+  // hellos, so the number of hellos sent on that session is 2.  In
+  // the stateless case, the first client session will be completely
+  // torn down after the reject.  The number of hellos sent on the
+  // latest session is 1.
+  EXPECT_EQ(expected_num_hellos_latest_session,
+            client_->client()->client_session()->GetNumSentClientHellos());
+  if (ServerSendsVersionNegotiation()) {
+    EXPECT_EQ(3, client_->client()->GetNumSentClientHellos());
+  } else {
+    EXPECT_EQ(2, client_->client()->GetNumSentClientHellos());
+  }
+
+  VerifyCleanConnection(false);
+}
+
+TEST_P(EndToEndTest, SynchronousRequestZeroRTTFailure) {
+  // Send a request and then disconnect. This prepares the client to attempt
+  // a 0-RTT handshake for the next request.
+  ASSERT_TRUE(Initialize());
+
+  EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
+  // In the non-stateless case, the same session is used for both
+  // hellos, so the number of hellos sent on that session is 2.  In
+  // the stateless case, the first client session will be completely
+  // torn down after the reject.  The number of hellos on that second
+  // latest session is 1.
+  const int expected_num_hellos_latest_session =
+      (BothSidesSupportStatelessRejects() && !ServerSendsVersionNegotiation())
+          ? 1
+          : 2;
+  EXPECT_EQ(expected_num_hellos_latest_session,
+            client_->client()->client_session()->GetNumSentClientHellos());
+  if (ServerSendsVersionNegotiation()) {
+    EXPECT_EQ(3, client_->client()->GetNumSentClientHellos());
+  } else {
+    EXPECT_EQ(2, client_->client()->GetNumSentClientHellos());
+  }
+
+  client_->Disconnect();
+
+  // The 0-RTT handshake should succeed.
+  client_->Connect();
+  EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
+  ASSERT_TRUE(client_->client()->connected());
+  EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
+
+  EXPECT_EQ(1, client_->client()->client_session()->GetNumSentClientHellos());
+  if (ServerSendsVersionNegotiation()) {
+    EXPECT_EQ(2, client_->client()->GetNumSentClientHellos());
+  } else {
+    EXPECT_EQ(1, client_->client()->GetNumSentClientHellos());
+  }
+
+  client_->Disconnect();
+
+  // Restart the server so that the 0-RTT handshake will take 1 RTT.
+  StopServer();
+  server_writer_ = new PacketDroppingTestWriter();
+  StartServer();
+
+  client_->Connect();
+  EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
+  ASSERT_TRUE(client_->client()->connected());
+  EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
+  // In the non-stateless case, the same session is used for both
+  // hellos, so the number of hellos sent on that session is 2.  In
+  // the stateless case, the first client session will be completely
+  // torn down after the reject.  The number of hellos sent on the
+  // latest session is 1.
+  EXPECT_EQ(expected_num_hellos_latest_session,
+            client_->client()->client_session()->GetNumSentClientHellos());
+  if (ServerSendsVersionNegotiation()) {
+    EXPECT_EQ(3, client_->client()->GetNumSentClientHellos());
+  } else {
+    EXPECT_EQ(2, client_->client()->GetNumSentClientHellos());
+  }
+
+  VerifyCleanConnection(false);
+}
+
+TEST_P(EndToEndTest, LargePostSynchronousRequest) {
+  // Send a request and then disconnect. This prepares the client to attempt
+  // a 0-RTT handshake for the next request.
+  ASSERT_TRUE(Initialize());
+
+  QuicString body(20480, 'a');
+  SpdyHeaderBlock headers;
+  headers[":method"] = "POST";
+  headers[":path"] = "/foo";
+  headers[":scheme"] = "https";
+  headers[":authority"] = server_hostname_;
+
+  EXPECT_EQ(kFooResponseBody,
+            client_->SendCustomSynchronousRequest(headers, body));
+  // In the non-stateless case, the same session is used for both
+  // hellos, so the number of hellos sent on that session is 2.  In
+  // the stateless case, the first client session will be completely
+  // torn down after the reject.  The number of hellos on the latest
+  // session is 1.
+  const int expected_num_hellos_latest_session =
+      (BothSidesSupportStatelessRejects() && !ServerSendsVersionNegotiation())
+          ? 1
+          : 2;
+  EXPECT_EQ(expected_num_hellos_latest_session,
+            client_->client()->client_session()->GetNumSentClientHellos());
+  if (ServerSendsVersionNegotiation()) {
+    EXPECT_EQ(3, client_->client()->GetNumSentClientHellos());
+  } else {
+    EXPECT_EQ(2, client_->client()->GetNumSentClientHellos());
+  }
+
+  client_->Disconnect();
+
+  // The 0-RTT handshake should succeed.
+  client_->Connect();
+  EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
+  ASSERT_TRUE(client_->client()->connected());
+  EXPECT_EQ(kFooResponseBody,
+            client_->SendCustomSynchronousRequest(headers, body));
+
+  EXPECT_EQ(1, client_->client()->client_session()->GetNumSentClientHellos());
+  if (ServerSendsVersionNegotiation()) {
+    EXPECT_EQ(2, client_->client()->GetNumSentClientHellos());
+  } else {
+    EXPECT_EQ(1, client_->client()->GetNumSentClientHellos());
+  }
+
+  client_->Disconnect();
+
+  // Restart the server so that the 0-RTT handshake will take 1 RTT.
+  StopServer();
+  server_writer_ = new PacketDroppingTestWriter();
+  StartServer();
+
+  client_->Connect();
+  EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
+  ASSERT_TRUE(client_->client()->connected());
+  EXPECT_EQ(kFooResponseBody,
+            client_->SendCustomSynchronousRequest(headers, body));
+  // In the non-stateless case, the same session is used for both
+  // hellos, so the number of hellos sent on that session is 2.  In
+  // the stateless case, the first client session will be completely
+  // torn down after the reject.  The number of hellos sent on the
+  // latest session is 1.
+  EXPECT_EQ(expected_num_hellos_latest_session,
+            client_->client()->client_session()->GetNumSentClientHellos());
+  if (ServerSendsVersionNegotiation()) {
+    EXPECT_EQ(3, client_->client()->GetNumSentClientHellos());
+  } else {
+    EXPECT_EQ(2, client_->client()->GetNumSentClientHellos());
+  }
+
+  VerifyCleanConnection(false);
+}
+
+TEST_P(EndToEndTest, StatelessRejectWithPacketLoss) {
+  // In this test, we intentionally drop the first packet from the
+  // server, which corresponds with the initial REJ/SREJ response from
+  // the server.
+  server_writer_->set_fake_drop_first_n_packets(1);
+  ASSERT_TRUE(Initialize());
+}
+
+TEST_P(EndToEndTest, SetInitialReceivedConnectionOptions) {
+  QuicTagVector initial_received_options;
+  initial_received_options.push_back(kTBBR);
+  initial_received_options.push_back(kIW10);
+  initial_received_options.push_back(kPRST);
+  EXPECT_TRUE(server_config_.SetInitialReceivedConnectionOptions(
+      initial_received_options));
+
+  ASSERT_TRUE(Initialize());
+  EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
+  server_thread_->WaitForCryptoHandshakeConfirmed();
+
+  EXPECT_FALSE(server_config_.SetInitialReceivedConnectionOptions(
+      initial_received_options));
+
+  // Verify that server's configuration is correct.
+  server_thread_->Pause();
+  EXPECT_TRUE(server_config_.HasReceivedConnectionOptions());
+  EXPECT_TRUE(
+      ContainsQuicTag(server_config_.ReceivedConnectionOptions(), kTBBR));
+  EXPECT_TRUE(
+      ContainsQuicTag(server_config_.ReceivedConnectionOptions(), kIW10));
+  EXPECT_TRUE(
+      ContainsQuicTag(server_config_.ReceivedConnectionOptions(), kPRST));
+}
+
+TEST_P(EndToEndTest, LargePostSmallBandwidthLargeBuffer) {
+  ASSERT_TRUE(Initialize());
+  SetPacketSendDelay(QuicTime::Delta::FromMicroseconds(1));
+  // 256KB per second with a 256KB buffer from server to client.  Wireless
+  // clients commonly have larger buffers, but our max CWND is 200.
+  server_writer_->set_max_bandwidth_and_buffer_size(
+      QuicBandwidth::FromBytesPerSecond(256 * 1024), 256 * 1024);
+
+  EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
+
+  // 1 MB body.
+  QuicString body(1024 * 1024, 'a');
+  SpdyHeaderBlock headers;
+  headers[":method"] = "POST";
+  headers[":path"] = "/foo";
+  headers[":scheme"] = "https";
+  headers[":authority"] = server_hostname_;
+
+  EXPECT_EQ(kFooResponseBody,
+            client_->SendCustomSynchronousRequest(headers, body));
+  // This connection may drop packets, because the buffer is smaller than the
+  // max CWND.
+  VerifyCleanConnection(true);
+}
+
+TEST_P(EndToEndTestWithTls, DoNotSetSendAlarmIfConnectionFlowControlBlocked) {
+  // Regression test for b/14677858.
+  // Test that the resume write alarm is not set in QuicConnection::OnCanWrite
+  // if currently connection level flow control blocked. If set, this results in
+  // an infinite loop in the EpollServer, as the alarm fires and is immediately
+  // rescheduled.
+  ASSERT_TRUE(Initialize());
+  EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
+
+  // Ensure both stream and connection level are flow control blocked by setting
+  // the send window offset to 0.
+  const uint64_t flow_control_window =
+      server_config_.GetInitialStreamFlowControlWindowToSend();
+  QuicSpdyClientStream* stream = client_->GetOrCreateStream();
+  QuicSession* session = client_->client()->client_session();
+  QuicFlowControllerPeer::SetSendWindowOffset(stream->flow_controller(), 0);
+  QuicFlowControllerPeer::SetSendWindowOffset(session->flow_controller(), 0);
+  EXPECT_TRUE(stream->flow_controller()->IsBlocked());
+  EXPECT_TRUE(session->flow_controller()->IsBlocked());
+
+  // Make sure that the stream has data pending so that it will be marked as
+  // write blocked when it receives a stream level WINDOW_UPDATE.
+  stream->WriteOrBufferBody("hello", false);
+
+  // The stream now attempts to write, fails because it is still connection
+  // level flow control blocked, and is added to the write blocked list.
+  QuicWindowUpdateFrame window_update(kInvalidControlFrameId, stream->id(),
+                                      2 * flow_control_window);
+  stream->OnWindowUpdateFrame(window_update);
+
+  // Prior to fixing b/14677858 this call would result in an infinite loop in
+  // Chromium. As a proxy for detecting this, we now check whether the
+  // send alarm is set after OnCanWrite. It should not be, as the
+  // connection is still flow control blocked.
+  session->connection()->OnCanWrite();
+
+  QuicAlarm* send_alarm =
+      QuicConnectionPeer::GetSendAlarm(session->connection());
+  EXPECT_FALSE(send_alarm->IsSet());
+}
+
+// TODO(nharper): Needs to get turned back to EndToEndTestWithTls
+// when we figure out why the test doesn't work on chrome.
+TEST_P(EndToEndTest, InvalidStream) {
+  ASSERT_TRUE(Initialize());
+  EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
+
+  QuicString body(kMaxPacketSize, 'a');
+  SpdyHeaderBlock headers;
+  headers[":method"] = "POST";
+  headers[":path"] = "/foo";
+  headers[":scheme"] = "https";
+  headers[":authority"] = server_hostname_;
+
+  // Force the client to write with a stream ID belonging to a nonexistent
+  // server-side stream.
+  QuicSpdySession* session = client_->client()->client_session();
+  QuicSessionPeer::SetNextOutgoingBidirectionalStreamId(
+      session, GetNthServerInitiatedBidirectionalId(0));
+
+  client_->SendCustomSynchronousRequest(headers, body);
+  EXPECT_EQ(QUIC_STREAM_CONNECTION_ERROR, client_->stream_error());
+  EXPECT_EQ(QUIC_INVALID_STREAM_ID, client_->connection_error());
+}
+
+// Test that if the server will close the connection if the client attempts
+// to send a request with overly large headers.
+TEST_P(EndToEndTest, LargeHeaders) {
+  ASSERT_TRUE(Initialize());
+  EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
+
+  QuicString body(kMaxPacketSize, 'a');
+  SpdyHeaderBlock headers;
+  headers[":method"] = "POST";
+  headers[":path"] = "/foo";
+  headers[":scheme"] = "https";
+  headers[":authority"] = server_hostname_;
+  headers["key1"] = QuicString(15 * 1024, 'a');
+  headers["key2"] = QuicString(15 * 1024, 'a');
+  headers["key3"] = QuicString(15 * 1024, 'a');
+
+  client_->SendCustomSynchronousRequest(headers, body);
+  EXPECT_EQ(QUIC_HEADERS_TOO_LARGE, client_->stream_error());
+  EXPECT_EQ(QUIC_NO_ERROR, client_->connection_error());
+}
+
+TEST_P(EndToEndTest, EarlyResponseWithQuicStreamNoError) {
+  ASSERT_TRUE(Initialize());
+  EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
+
+  QuicString large_body(1024 * 1024, 'a');
+  SpdyHeaderBlock headers;
+  headers[":method"] = "POST";
+  headers[":path"] = "/foo";
+  headers[":scheme"] = "https";
+  headers[":authority"] = server_hostname_;
+  // Insert an invalid content_length field in request to trigger an early
+  // response from server.
+  headers["content-length"] = "-3";
+
+  client_->SendCustomSynchronousRequest(headers, large_body);
+  EXPECT_EQ("bad", client_->response_body());
+  EXPECT_EQ("500", client_->response_headers()->find(":status")->second);
+  EXPECT_EQ(QUIC_STREAM_NO_ERROR, client_->stream_error());
+  EXPECT_EQ(QUIC_NO_ERROR, client_->connection_error());
+}
+
+// TODO(rch): this test seems to cause net_unittests timeouts :|
+TEST_P(EndToEndTestWithTls, QUIC_TEST_DISABLED_IN_CHROME(MultipleTermination)) {
+  ASSERT_TRUE(Initialize());
+
+  // Set the offset so we won't frame.  Otherwise when we pick up termination
+  // before HTTP framing is complete, we send an error and close the stream,
+  // and the second write is picked up as writing on a closed stream.
+  QuicSpdyClientStream* stream = client_->GetOrCreateStream();
+  ASSERT_TRUE(stream != nullptr);
+  QuicStreamPeer::SetStreamBytesWritten(3, stream);
+
+  client_->SendData("bar", true);
+  client_->WaitForWriteToFlush();
+
+  // By default the stream protects itself from writes after terminte is set.
+  // Override this to test the server handling buggy clients.
+  QuicStreamPeer::SetWriteSideClosed(false, client_->GetOrCreateStream());
+
+  EXPECT_QUIC_BUG(client_->SendData("eep", true), "Fin already buffered");
+}
+
+// TODO(nharper): Needs to get turned back to EndToEndTestWithTls
+// when we figure out why the test doesn't work on chrome.
+TEST_P(EndToEndTest, Timeout) {
+  client_config_.SetIdleNetworkTimeout(QuicTime::Delta::FromMicroseconds(500),
+                                       QuicTime::Delta::FromMicroseconds(500));
+  // Note: we do NOT ASSERT_TRUE: we may time out during initial handshake:
+  // that's enough to validate timeout in this case.
+  Initialize();
+  while (client_->client()->connected()) {
+    client_->client()->WaitForEvents();
+  }
+}
+
+TEST_P(EndToEndTestWithTls, MaxIncomingDynamicStreamsLimitRespected) {
+  // Set a limit on maximum number of incoming dynamic streams.
+  // Make sure the limit is respected.
+  const uint32_t kServerMaxIncomingDynamicStreams = 1;
+  server_config_.SetMaxIncomingDynamicStreamsToSend(
+      kServerMaxIncomingDynamicStreams);
+  ASSERT_TRUE(Initialize());
+  EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
+  QuicConnection* client_connection =
+      client_->client()->client_session()->connection();
+
+  // Make the client misbehave after negotiation.
+  const int kServerMaxStreams = kMaxStreamsMinimumIncrement + 1;
+  QuicSessionPeer::SetMaxOpenOutgoingStreams(
+      client_->client()->client_session(), kServerMaxStreams + 1);
+
+  SpdyHeaderBlock headers;
+  headers[":method"] = "POST";
+  headers[":path"] = "/foo";
+  headers[":scheme"] = "https";
+  headers[":authority"] = server_hostname_;
+  headers["content-length"] = "3";
+
+  // The server supports a small number of additional streams beyond the
+  // negotiated limit. Open enough streams to go beyond that limit.
+  for (int i = 0; i < kServerMaxStreams + 1; ++i) {
+    client_->SendMessage(headers, "", /*fin=*/false);
+  }
+  client_->WaitForResponse();
+  if (client_connection->transport_version() != QUIC_VERSION_99) {
+    EXPECT_TRUE(client_->connected());
+    EXPECT_EQ(QUIC_REFUSED_STREAM, client_->stream_error());
+    EXPECT_EQ(QUIC_NO_ERROR, client_->connection_error());
+  } else {
+    // Version 99 disconnects the connection if we exceed the stream limit.
+    EXPECT_FALSE(client_->connected());
+    EXPECT_EQ(QUIC_STREAM_CONNECTION_ERROR, client_->stream_error());
+    EXPECT_EQ(QUIC_INVALID_STREAM_ID, client_->connection_error());
+  }
+}
+
+TEST_P(EndToEndTest, SetIndependentMaxIncomingDynamicStreamsLimits) {
+  // Each endpoint can set max incoming dynamic streams independently.
+  const uint32_t kClientMaxIncomingDynamicStreams = 2;
+  const uint32_t kServerMaxIncomingDynamicStreams = 1;
+  client_config_.SetMaxIncomingDynamicStreamsToSend(
+      kClientMaxIncomingDynamicStreams);
+  server_config_.SetMaxIncomingDynamicStreamsToSend(
+      kServerMaxIncomingDynamicStreams);
+  ASSERT_TRUE(Initialize());
+  EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
+
+  // The client has received the server's limit and vice versa.
+  QuicSpdyClientSession* client_session = client_->client()->client_session();
+  size_t client_max_open_outgoing_bidirectional_streams =
+      client_session->connection()->transport_version() == QUIC_VERSION_99
+          ? QuicSessionPeer::v99_streamid_manager(client_session)
+                ->max_allowed_outgoing_bidirectional_streams()
+          : QuicSessionPeer::GetStreamIdManager(client_session)
+                ->max_open_outgoing_streams();
+  size_t client_max_open_outgoing_unidirectional_streams =
+      client_session->connection()->transport_version() == QUIC_VERSION_99
+          ? QuicSessionPeer::v99_streamid_manager(client_session)
+                ->max_allowed_outgoing_unidirectional_streams()
+          : QuicSessionPeer::GetStreamIdManager(client_session)
+                ->max_open_outgoing_streams();
+  EXPECT_EQ(kServerMaxIncomingDynamicStreams,
+            client_max_open_outgoing_bidirectional_streams);
+  EXPECT_EQ(kServerMaxIncomingDynamicStreams,
+            client_max_open_outgoing_unidirectional_streams);
+  server_thread_->Pause();
+  QuicSession* server_session = GetServerSession();
+  size_t server_max_open_outgoing_bidirectional_streams =
+      server_session->connection()->transport_version() == QUIC_VERSION_99
+          ? QuicSessionPeer::v99_streamid_manager(server_session)
+                ->max_allowed_outgoing_bidirectional_streams()
+          : QuicSessionPeer::GetStreamIdManager(server_session)
+                ->max_open_outgoing_streams();
+  size_t server_max_open_outgoing_unidirectional_streams =
+      server_session->connection()->transport_version() == QUIC_VERSION_99
+          ? QuicSessionPeer::v99_streamid_manager(server_session)
+                ->max_allowed_outgoing_unidirectional_streams()
+          : QuicSessionPeer::GetStreamIdManager(server_session)
+                ->max_open_outgoing_streams();
+  EXPECT_EQ(kClientMaxIncomingDynamicStreams,
+            server_max_open_outgoing_bidirectional_streams);
+  EXPECT_EQ(kClientMaxIncomingDynamicStreams,
+            server_max_open_outgoing_unidirectional_streams);
+  server_thread_->Resume();
+}
+
+TEST_P(EndToEndTest, NegotiateCongestionControl) {
+  ASSERT_TRUE(Initialize());
+
+  // For PCC, the underlying implementation may be a stub with a
+  // different name-tag.  Skip the rest of this test.
+  if (GetParam().congestion_control_tag == kTPCC) {
+    return;
+  }
+
+  EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
+
+  CongestionControlType expected_congestion_control_type = kRenoBytes;
+  switch (GetParam().congestion_control_tag) {
+    case kRENO:
+      expected_congestion_control_type = kRenoBytes;
+      break;
+    case kTBBR:
+      expected_congestion_control_type = kBBR;
+      break;
+    case kQBIC:
+      expected_congestion_control_type = kCubicBytes;
+      break;
+    default:
+      QUIC_DLOG(FATAL) << "Unexpected congestion control tag";
+  }
+
+  server_thread_->Pause();
+  EXPECT_EQ(expected_congestion_control_type,
+            QuicSentPacketManagerPeer::GetSendAlgorithm(
+                *GetSentPacketManagerFromFirstServerSession())
+                ->GetCongestionControlType());
+  server_thread_->Resume();
+}
+
+TEST_P(EndToEndTest, ClientSuggestsRTT) {
+  // Client suggests initial RTT, verify it is used.
+  const QuicTime::Delta kInitialRTT = QuicTime::Delta::FromMicroseconds(20000);
+  client_config_.SetInitialRoundTripTimeUsToSend(kInitialRTT.ToMicroseconds());
+
+  ASSERT_TRUE(Initialize());
+  EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
+  server_thread_->WaitForCryptoHandshakeConfirmed();
+
+  // Pause the server so we can access the server's internals without races.
+  server_thread_->Pause();
+  QuicDispatcher* dispatcher =
+      QuicServerPeer::GetDispatcher(server_thread_->server());
+  ASSERT_EQ(1u, dispatcher->session_map().size());
+  const QuicSentPacketManager& client_sent_packet_manager =
+      client_->client()->client_session()->connection()->sent_packet_manager();
+  const QuicSentPacketManager* server_sent_packet_manager =
+      GetSentPacketManagerFromFirstServerSession();
+
+  EXPECT_EQ(kInitialRTT,
+            client_sent_packet_manager.GetRttStats()->initial_rtt());
+  EXPECT_EQ(kInitialRTT,
+            server_sent_packet_manager->GetRttStats()->initial_rtt());
+  server_thread_->Resume();
+}
+
+TEST_P(EndToEndTest, ClientSuggestsIgnoredRTT) {
+  // Client suggests initial RTT, but also specifies NRTT, so it's not used.
+  const QuicTime::Delta kInitialRTT = QuicTime::Delta::FromMicroseconds(20000);
+  client_config_.SetInitialRoundTripTimeUsToSend(kInitialRTT.ToMicroseconds());
+  QuicTagVector options;
+  options.push_back(kNRTT);
+  client_config_.SetConnectionOptionsToSend(options);
+
+  ASSERT_TRUE(Initialize());
+  EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
+  server_thread_->WaitForCryptoHandshakeConfirmed();
+
+  // Pause the server so we can access the server's internals without races.
+  server_thread_->Pause();
+  QuicDispatcher* dispatcher =
+      QuicServerPeer::GetDispatcher(server_thread_->server());
+  ASSERT_EQ(1u, dispatcher->session_map().size());
+  const QuicSentPacketManager& client_sent_packet_manager =
+      client_->client()->client_session()->connection()->sent_packet_manager();
+  const QuicSentPacketManager* server_sent_packet_manager =
+      GetSentPacketManagerFromFirstServerSession();
+
+  EXPECT_EQ(kInitialRTT,
+            client_sent_packet_manager.GetRttStats()->initial_rtt());
+  EXPECT_EQ(kInitialRTT,
+            server_sent_packet_manager->GetRttStats()->initial_rtt());
+  server_thread_->Resume();
+}
+
+TEST_P(EndToEndTest, MaxInitialRTT) {
+  // Client tries to suggest twice the server's max initial rtt and the server
+  // uses the max.
+  client_config_.SetInitialRoundTripTimeUsToSend(2 *
+                                                 kMaxInitialRoundTripTimeUs);
+
+  ASSERT_TRUE(Initialize());
+  EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
+  server_thread_->WaitForCryptoHandshakeConfirmed();
+
+  // Pause the server so we can access the server's internals without races.
+  server_thread_->Pause();
+  const QuicSentPacketManager& client_sent_packet_manager =
+      client_->client()->client_session()->connection()->sent_packet_manager();
+
+  // Now that acks have been exchanged, the RTT estimate has decreased on the
+  // server and is not infinite on the client.
+  EXPECT_FALSE(
+      client_sent_packet_manager.GetRttStats()->smoothed_rtt().IsInfinite());
+  const RttStats& server_rtt_stats =
+      *GetServerConnection()->sent_packet_manager().GetRttStats();
+  EXPECT_EQ(static_cast<int64_t>(kMaxInitialRoundTripTimeUs),
+            server_rtt_stats.initial_rtt().ToMicroseconds());
+  EXPECT_GE(static_cast<int64_t>(kMaxInitialRoundTripTimeUs),
+            server_rtt_stats.smoothed_rtt().ToMicroseconds());
+  server_thread_->Resume();
+}
+
+TEST_P(EndToEndTest, MinInitialRTT) {
+  // Client tries to suggest 0 and the server uses the default.
+  client_config_.SetInitialRoundTripTimeUsToSend(0);
+
+  ASSERT_TRUE(Initialize());
+  EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
+  server_thread_->WaitForCryptoHandshakeConfirmed();
+
+  // Pause the server so we can access the server's internals without races.
+  server_thread_->Pause();
+  const QuicSentPacketManager& client_sent_packet_manager =
+      client_->client()->client_session()->connection()->sent_packet_manager();
+  const QuicSentPacketManager& server_sent_packet_manager =
+      GetServerConnection()->sent_packet_manager();
+
+  // Now that acks have been exchanged, the RTT estimate has decreased on the
+  // server and is not infinite on the client.
+  EXPECT_FALSE(
+      client_sent_packet_manager.GetRttStats()->smoothed_rtt().IsInfinite());
+  // Expect the default rtt of 100ms.
+  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(100),
+            server_sent_packet_manager.GetRttStats()->initial_rtt());
+  // Ensure the bandwidth is valid.
+  client_sent_packet_manager.BandwidthEstimate();
+  server_sent_packet_manager.BandwidthEstimate();
+  server_thread_->Resume();
+}
+
+TEST_P(EndToEndTest, 0ByteConnectionId) {
+  client_config_.SetBytesForConnectionIdToSend(0);
+  ASSERT_TRUE(Initialize());
+
+  EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
+  EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
+  QuicConnection* client_connection =
+      client_->client()->client_session()->connection();
+  QuicPacketHeader* header =
+      QuicConnectionPeer::GetLastHeader(client_connection);
+  EXPECT_EQ(CONNECTION_ID_ABSENT, header->destination_connection_id_included);
+}
+
+TEST_P(EndToEndTestWithTls, 8ByteConnectionId) {
+  client_config_.SetBytesForConnectionIdToSend(8);
+  ASSERT_TRUE(Initialize());
+
+  EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
+  EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
+  QuicConnection* client_connection =
+      client_->client()->client_session()->connection();
+  QuicPacketHeader* header =
+      QuicConnectionPeer::GetLastHeader(client_connection);
+  if (client_connection->transport_version() > QUIC_VERSION_43) {
+    EXPECT_EQ(CONNECTION_ID_ABSENT, header->destination_connection_id_included);
+  } else {
+    EXPECT_EQ(CONNECTION_ID_PRESENT,
+              header->destination_connection_id_included);
+  }
+}
+
+TEST_P(EndToEndTestWithTls, 15ByteConnectionId) {
+  client_config_.SetBytesForConnectionIdToSend(15);
+  ASSERT_TRUE(Initialize());
+
+  // Our server is permissive and allows for out of bounds values.
+  EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
+  EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
+  QuicConnection* client_connection =
+      client_->client()->client_session()->connection();
+  QuicPacketHeader* header =
+      QuicConnectionPeer::GetLastHeader(client_connection);
+  if (client_connection->transport_version() > QUIC_VERSION_43) {
+    EXPECT_EQ(CONNECTION_ID_ABSENT, header->destination_connection_id_included);
+  } else {
+    EXPECT_EQ(CONNECTION_ID_PRESENT,
+              header->destination_connection_id_included);
+  }
+}
+
+TEST_P(EndToEndTestWithTls, ResetConnection) {
+  ASSERT_TRUE(Initialize());
+
+  EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
+  EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
+  client_->ResetConnection();
+  EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
+  EXPECT_EQ(kBarResponseBody, client_->SendSynchronousRequest("/bar"));
+  EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
+}
+
+// TODO(nharper): Needs to get turned back to EndToEndTestWithTls
+// when we figure out why the test doesn't work on chrome.
+TEST_P(EndToEndTest, MaxStreamsUberTest) {
+  if (!BothSidesSupportStatelessRejects()) {
+    // Connect with lower fake packet loss than we'd like to test.  Until
+    // b/10126687 is fixed, losing handshake packets is pretty brutal.
+    // TODO(jokulik): Until we support redundant SREJ packets, don't
+    // drop handshake packets for stateless rejects.
+    SetPacketLossPercentage(1);
+  }
+  ASSERT_TRUE(Initialize());
+  QuicString large_body(10240, 'a');
+  int max_streams = 100;
+
+  AddToCache("/large_response", 200, large_body);
+
+  EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
+  SetPacketLossPercentage(10);
+
+  for (int i = 0; i < max_streams; ++i) {
+    EXPECT_LT(0, client_->SendRequest("/large_response"));
+  }
+
+  // WaitForEvents waits 50ms and returns true if there are outstanding
+  // requests.
+  while (client_->client()->WaitForEvents() == true) {
+  }
+}
+
+TEST_P(EndToEndTestWithTls, StreamCancelErrorTest) {
+  ASSERT_TRUE(Initialize());
+  QuicString small_body(256, 'a');
+
+  AddToCache("/small_response", 200, small_body);
+
+  EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
+
+  QuicSession* session = client_->client()->client_session();
+  // Lose the request.
+  SetPacketLossPercentage(100);
+  EXPECT_LT(0, client_->SendRequest("/small_response"));
+  client_->client()->WaitForEvents();
+  // Transmit the cancel, and ensure the connection is torn down properly.
+  SetPacketLossPercentage(0);
+  QuicStreamId stream_id = GetNthClientInitiatedBidirectionalId(0);
+  session->SendRstStream(stream_id, QUIC_STREAM_CANCELLED, 0);
+
+  // WaitForEvents waits 50ms and returns true if there are outstanding
+  // requests.
+  while (client_->client()->WaitForEvents() == true) {
+  }
+  // It should be completely fine to RST a stream before any data has been
+  // received for that stream.
+  EXPECT_EQ(QUIC_NO_ERROR, client_->connection_error());
+}
+
+TEST_P(EndToEndTest, ConnectionMigrationClientIPChanged) {
+  ASSERT_TRUE(Initialize());
+  EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
+  EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
+
+  // Store the client IP address which was used to send the first request.
+  QuicIpAddress old_host =
+      client_->client()->network_helper()->GetLatestClientAddress().host();
+
+  // Migrate socket to the new IP address.
+  QuicIpAddress new_host = TestLoopback(2);
+  EXPECT_NE(old_host, new_host);
+  ASSERT_TRUE(client_->client()->MigrateSocket(new_host));
+
+  // Send a request using the new socket.
+  EXPECT_EQ(kBarResponseBody, client_->SendSynchronousRequest("/bar"));
+  EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
+}
+
+TEST_P(EndToEndTest, ConnectionMigrationClientPortChanged) {
+  // Tests that the client's port can change during an established QUIC
+  // connection, and that doing so does not result in the connection being
+  // closed by the server.
+  ASSERT_TRUE(Initialize());
+
+  EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
+  EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
+
+  // Store the client address which was used to send the first request.
+  QuicSocketAddress old_address =
+      client_->client()->network_helper()->GetLatestClientAddress();
+  int old_fd = client_->client()->GetLatestFD();
+
+  // Create a new socket before closing the old one, which will result in a new
+  // ephemeral port.
+  QuicClientPeer::CreateUDPSocketAndBind(client_->client());
+
+  // Stop listening and close the old FD.
+  QuicClientPeer::CleanUpUDPSocket(client_->client(), old_fd);
+
+  // The packet writer needs to be updated to use the new FD.
+  client_->client()->network_helper()->CreateQuicPacketWriter();
+
+  // Change the internal state of the client and connection to use the new port,
+  // this is done because in a real NAT rebinding the client wouldn't see any
+  // port change, and so expects no change to incoming port.
+  // This is kind of ugly, but needed as we are simply swapping out the client
+  // FD rather than any more complex NAT rebinding simulation.
+  int new_port =
+      client_->client()->network_helper()->GetLatestClientAddress().port();
+  QuicClientPeer::SetClientPort(client_->client(), new_port);
+  QuicConnectionPeer::SetSelfAddress(
+      client_->client()->client_session()->connection(),
+      QuicSocketAddress(client_->client()
+                            ->client_session()
+                            ->connection()
+                            ->self_address()
+                            .host(),
+                        new_port));
+
+  // Register the new FD for epoll events.
+  int new_fd = client_->client()->GetLatestFD();
+  QuicEpollServer* eps = client_->epoll_server();
+  eps->RegisterFD(new_fd, client_->client()->epoll_network_helper(),
+                  EPOLLIN | EPOLLOUT | EPOLLET);
+
+  // Send a second request, using the new FD.
+  EXPECT_EQ(kBarResponseBody, client_->SendSynchronousRequest("/bar"));
+  EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
+
+  // Verify that the client's ephemeral port is different.
+  QuicSocketAddress new_address =
+      client_->client()->network_helper()->GetLatestClientAddress();
+  EXPECT_EQ(old_address.host(), new_address.host());
+  EXPECT_NE(old_address.port(), new_address.port());
+}
+
+TEST_P(EndToEndTest, NegotiatedInitialCongestionWindow) {
+  SetQuicReloadableFlag(quic_unified_iw_options, true);
+  client_extra_copts_.push_back(kIW03);
+
+  ASSERT_TRUE(Initialize());
+
+  // Values are exchanged during crypto handshake, so wait for that to finish.
+  EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
+  server_thread_->WaitForCryptoHandshakeConfirmed();
+  server_thread_->Pause();
+
+  QuicPacketCount cwnd =
+      GetServerConnection()->sent_packet_manager().initial_congestion_window();
+  EXPECT_EQ(3u, cwnd);
+}
+
+TEST_P(EndToEndTest, DifferentFlowControlWindows) {
+  // Client and server can set different initial flow control receive windows.
+  // These are sent in CHLO/SHLO. Tests that these values are exchanged properly
+  // in the crypto handshake.
+  const uint32_t kClientStreamIFCW = 123456;
+  const uint32_t kClientSessionIFCW = 234567;
+  set_client_initial_stream_flow_control_receive_window(kClientStreamIFCW);
+  set_client_initial_session_flow_control_receive_window(kClientSessionIFCW);
+
+  uint32_t kServerStreamIFCW = 32 * 1024;
+  uint32_t kServerSessionIFCW = 48 * 1024;
+  set_server_initial_stream_flow_control_receive_window(kServerStreamIFCW);
+  set_server_initial_session_flow_control_receive_window(kServerSessionIFCW);
+
+  ASSERT_TRUE(Initialize());
+
+  // Values are exchanged during crypto handshake, so wait for that to finish.
+  EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
+  server_thread_->WaitForCryptoHandshakeConfirmed();
+
+  // Open a data stream to make sure the stream level flow control is updated.
+  QuicSpdyClientStream* stream = client_->GetOrCreateStream();
+  stream->WriteOrBufferBody("hello", false);
+
+  // Client should have the right values for server's receive window.
+  EXPECT_EQ(kServerStreamIFCW,
+            client_->client()
+                ->client_session()
+                ->config()
+                ->ReceivedInitialStreamFlowControlWindowBytes());
+  EXPECT_EQ(kServerSessionIFCW,
+            client_->client()
+                ->client_session()
+                ->config()
+                ->ReceivedInitialSessionFlowControlWindowBytes());
+  EXPECT_EQ(kServerStreamIFCW, QuicFlowControllerPeer::SendWindowOffset(
+                                   stream->flow_controller()));
+  EXPECT_EQ(kServerSessionIFCW,
+            QuicFlowControllerPeer::SendWindowOffset(
+                client_->client()->client_session()->flow_controller()));
+
+  // Server should have the right values for client's receive window.
+  server_thread_->Pause();
+  QuicSession* session = GetServerSession();
+  EXPECT_EQ(kClientStreamIFCW,
+            session->config()->ReceivedInitialStreamFlowControlWindowBytes());
+  EXPECT_EQ(kClientSessionIFCW,
+            session->config()->ReceivedInitialSessionFlowControlWindowBytes());
+  EXPECT_EQ(kClientSessionIFCW, QuicFlowControllerPeer::SendWindowOffset(
+                                    session->flow_controller()));
+  server_thread_->Resume();
+}
+
+// Test negotiation of IFWA connection option.
+TEST_P(EndToEndTest, NegotiatedServerInitialFlowControlWindow) {
+  const uint32_t kClientStreamIFCW = 123456;
+  const uint32_t kClientSessionIFCW = 234567;
+  set_client_initial_stream_flow_control_receive_window(kClientStreamIFCW);
+  set_client_initial_session_flow_control_receive_window(kClientSessionIFCW);
+
+  uint32_t kServerStreamIFCW = 32 * 1024;
+  uint32_t kServerSessionIFCW = 48 * 1024;
+  set_server_initial_stream_flow_control_receive_window(kServerStreamIFCW);
+  set_server_initial_session_flow_control_receive_window(kServerSessionIFCW);
+
+  // Bump the window.
+  const uint32_t kExpectedStreamIFCW = 1024 * 1024;
+  const uint32_t kExpectedSessionIFCW = 1.5 * 1024 * 1024;
+  client_extra_copts_.push_back(kIFWA);
+
+  ASSERT_TRUE(Initialize());
+
+  // Values are exchanged during crypto handshake, so wait for that to finish.
+  EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
+  server_thread_->WaitForCryptoHandshakeConfirmed();
+
+  // Open a data stream to make sure the stream level flow control is updated.
+  QuicSpdyClientStream* stream = client_->GetOrCreateStream();
+  stream->WriteOrBufferBody("hello", false);
+
+  // Client should have the right values for server's receive window.
+  EXPECT_EQ(kExpectedStreamIFCW,
+            client_->client()
+                ->client_session()
+                ->config()
+                ->ReceivedInitialStreamFlowControlWindowBytes());
+  EXPECT_EQ(kExpectedSessionIFCW,
+            client_->client()
+                ->client_session()
+                ->config()
+                ->ReceivedInitialSessionFlowControlWindowBytes());
+  EXPECT_EQ(kExpectedStreamIFCW, QuicFlowControllerPeer::SendWindowOffset(
+                                     stream->flow_controller()));
+  EXPECT_EQ(kExpectedSessionIFCW,
+            QuicFlowControllerPeer::SendWindowOffset(
+                client_->client()->client_session()->flow_controller()));
+}
+
+TEST_P(EndToEndTest, HeadersAndCryptoStreamsNoConnectionFlowControl) {
+  // The special headers and crypto streams should be subject to per-stream flow
+  // control limits, but should not be subject to connection level flow control
+  const uint32_t kStreamIFCW = 32 * 1024;
+  const uint32_t kSessionIFCW = 48 * 1024;
+  set_client_initial_stream_flow_control_receive_window(kStreamIFCW);
+  set_client_initial_session_flow_control_receive_window(kSessionIFCW);
+  set_server_initial_stream_flow_control_receive_window(kStreamIFCW);
+  set_server_initial_session_flow_control_receive_window(kSessionIFCW);
+
+  ASSERT_TRUE(Initialize());
+
+  // Wait for crypto handshake to finish. This should have contributed to the
+  // crypto stream flow control window, but not affected the session flow
+  // control window.
+  EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
+  server_thread_->WaitForCryptoHandshakeConfirmed();
+
+  QuicCryptoStream* crypto_stream = QuicSessionPeer::GetMutableCryptoStream(
+      client_->client()->client_session());
+  // In v47 and later, the crypto handshake (sent in CRYPTO frames) is not
+  // subject to flow control.
+  if (client_->client()->client_session()->connection()->transport_version() <
+      QUIC_VERSION_47) {
+    EXPECT_LT(QuicFlowControllerPeer::SendWindowSize(
+                  crypto_stream->flow_controller()),
+              kStreamIFCW);
+  }
+  EXPECT_EQ(kSessionIFCW,
+            QuicFlowControllerPeer::SendWindowSize(
+                client_->client()->client_session()->flow_controller()));
+
+  // Send a request with no body, and verify that the connection level window
+  // has not been affected.
+  EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
+
+  QuicHeadersStream* headers_stream = QuicSpdySessionPeer::GetHeadersStream(
+      client_->client()->client_session());
+  EXPECT_LT(
+      QuicFlowControllerPeer::SendWindowSize(headers_stream->flow_controller()),
+      kStreamIFCW);
+  EXPECT_EQ(kSessionIFCW,
+            QuicFlowControllerPeer::SendWindowSize(
+                client_->client()->client_session()->flow_controller()));
+
+  // Server should be in a similar state: connection flow control window should
+  // not have any bytes marked as received.
+  server_thread_->Pause();
+  QuicSession* session = GetServerSession();
+  QuicFlowController* server_connection_flow_controller =
+      session->flow_controller();
+  EXPECT_EQ(kSessionIFCW, QuicFlowControllerPeer::ReceiveWindowSize(
+                              server_connection_flow_controller));
+  server_thread_->Resume();
+}
+
+TEST_P(EndToEndTest, FlowControlsSynced) {
+  set_smaller_flow_control_receive_window();
+
+  ASSERT_TRUE(Initialize());
+
+  EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
+  server_thread_->WaitForCryptoHandshakeConfirmed();
+
+  server_thread_->Pause();
+  QuicSpdySession* const client_session = client_->client()->client_session();
+  auto* server_session = static_cast<QuicSpdySession*>(GetServerSession());
+  ExpectFlowControlsSynced(client_session->flow_controller(),
+                           server_session->flow_controller());
+  ExpectFlowControlsSynced(
+      QuicSessionPeer::GetMutableCryptoStream(client_session)
+          ->flow_controller(),
+      QuicSessionPeer::GetMutableCryptoStream(server_session)
+          ->flow_controller());
+  SpdyFramer spdy_framer(SpdyFramer::ENABLE_COMPRESSION);
+  SpdySettingsIR settings_frame;
+  settings_frame.AddSetting(SETTINGS_MAX_HEADER_LIST_SIZE,
+                            kDefaultMaxUncompressedHeaderSize);
+  SpdySerializedFrame frame(spdy_framer.SerializeFrame(settings_frame));
+  QuicFlowController* client_header_stream_flow_controller =
+      QuicSpdySessionPeer::GetHeadersStream(client_session)->flow_controller();
+  QuicFlowController* server_header_stream_flow_controller =
+      QuicSpdySessionPeer::GetHeadersStream(server_session)->flow_controller();
+  // Both client and server are sending this SETTINGS frame, and the send
+  // window is consumed. But because of timing issue, the server may send or
+  // not send the frame, and the client may send/ not send / receive / not
+  // receive the frame.
+  // TODO(fayang): Rewrite this part because it is hacky.
+  QuicByteCount win_difference1 = QuicFlowControllerPeer::ReceiveWindowSize(
+                                      server_header_stream_flow_controller) -
+                                  QuicFlowControllerPeer::SendWindowSize(
+                                      client_header_stream_flow_controller);
+  QuicByteCount win_difference2 = QuicFlowControllerPeer::ReceiveWindowSize(
+                                      client_header_stream_flow_controller) -
+                                  QuicFlowControllerPeer::SendWindowSize(
+                                      server_header_stream_flow_controller);
+  EXPECT_TRUE(win_difference1 == 0 || win_difference1 == frame.size());
+  EXPECT_TRUE(win_difference2 == 0 || win_difference2 == frame.size());
+
+  // Client *may* have received the SETTINGs frame.
+  // TODO(fayang): Rewrite this part because it is hacky.
+  float ratio1 = static_cast<float>(QuicFlowControllerPeer::ReceiveWindowSize(
+                     client_session->flow_controller())) /
+                 QuicFlowControllerPeer::ReceiveWindowSize(
+                     QuicSpdySessionPeer::GetHeadersStream(client_session)
+                         ->flow_controller());
+  float ratio2 = static_cast<float>(QuicFlowControllerPeer::ReceiveWindowSize(
+                     client_session->flow_controller())) /
+                 (QuicFlowControllerPeer::ReceiveWindowSize(
+                      QuicSpdySessionPeer::GetHeadersStream(client_session)
+                          ->flow_controller()) +
+                  frame.size());
+  EXPECT_TRUE(ratio1 == kSessionToStreamRatio ||
+              ratio2 == kSessionToStreamRatio);
+
+  server_thread_->Resume();
+}
+
+TEST_P(EndToEndTestWithTls, RequestWithNoBodyWillNeverSendStreamFrameWithFIN) {
+  // A stream created on receipt of a simple request with no body will never get
+  // a stream frame with a FIN. Verify that we don't keep track of the stream in
+  // the locally closed streams map: it will never be removed if so.
+  ASSERT_TRUE(Initialize());
+
+  // Send a simple headers only request, and receive response.
+  EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
+  EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
+
+  // Now verify that the server is not waiting for a final FIN or RST.
+  server_thread_->Pause();
+  QuicSession* session = GetServerSession();
+  EXPECT_EQ(
+      0u,
+      QuicSessionPeer::GetLocallyClosedStreamsHighestOffset(session).size());
+  server_thread_->Resume();
+}
+
+// A TestAckListener verifies that its OnAckNotification method has been
+// called exactly once on destruction.
+class TestAckListener : public QuicAckListenerInterface {
+ public:
+  explicit TestAckListener(int bytes_to_ack) : bytes_to_ack_(bytes_to_ack) {}
+
+  void OnPacketAcked(int acked_bytes,
+                     QuicTime::Delta /*delta_largest_observed*/) override {
+    ASSERT_LE(acked_bytes, bytes_to_ack_);
+    bytes_to_ack_ -= acked_bytes;
+  }
+
+  void OnPacketRetransmitted(int /*retransmitted_bytes*/) override {}
+
+  bool has_been_notified() const { return bytes_to_ack_ == 0; }
+
+ protected:
+  // Object is ref counted.
+  ~TestAckListener() override { EXPECT_EQ(0, bytes_to_ack_); }
+
+ private:
+  int bytes_to_ack_;
+};
+
+class TestResponseListener : public QuicSpdyClientBase::ResponseListener {
+ public:
+  void OnCompleteResponse(QuicStreamId id,
+                          const SpdyHeaderBlock& response_headers,
+                          const QuicString& response_body) override {
+    QUIC_DVLOG(1) << "response for stream " << id << " "
+                  << response_headers.DebugString() << "\n"
+                  << response_body;
+  }
+};
+
+TEST_P(EndToEndTest, AckNotifierWithPacketLossAndBlockedSocket) {
+  // Verify that even in the presence of packet loss and occasionally blocked
+  // socket,  an AckNotifierDelegate will get informed that the data it is
+  // interested in has been ACKed. This tests end-to-end ACK notification, and
+  // demonstrates that retransmissions do not break this functionality.
+  if (!BothSidesSupportStatelessRejects()) {
+    // TODO(jokulik): Until we support redundant SREJ packets, don't
+    // drop handshake packets for stateless rejects.
+    SetPacketLossPercentage(5);
+  }
+  ASSERT_TRUE(Initialize());
+
+  // Wait for the server SHLO before upping the packet loss.
+  EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
+  SetPacketLossPercentage(30);
+  client_writer_->set_fake_blocked_socket_percentage(10);
+
+  // Create a POST request and send the headers only.
+  SpdyHeaderBlock headers;
+  headers[":method"] = "POST";
+  headers[":path"] = "/foo";
+  headers[":scheme"] = "https";
+  headers[":authority"] = server_hostname_;
+
+  client_->SendMessage(headers, "", /*fin=*/false);
+
+  // Test the AckNotifier's ability to track multiple packets by making the
+  // request body exceed the size of a single packet.
+  QuicString request_string =
+      "a request body bigger than one packet" + QuicString(kMaxPacketSize, '.');
+
+  // The TestAckListener will cause a failure if not notified.
+  QuicReferenceCountedPointer<TestAckListener> ack_listener(
+      new TestAckListener(request_string.length()));
+
+  // Send the request, and register the delegate for ACKs.
+  client_->SendData(request_string, true, ack_listener);
+  client_->WaitForResponse();
+  EXPECT_EQ(kFooResponseBody, client_->response_body());
+  EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
+
+  // Send another request to flush out any pending ACKs on the server.
+  client_->SendSynchronousRequest("/bar");
+
+  // Make sure the delegate does get the notification it expects.
+  while (!ack_listener->has_been_notified()) {
+    // Waits for up to 50 ms.
+    client_->client()->WaitForEvents();
+  }
+}
+
+// Send a public reset from the server.
+TEST_P(EndToEndTestWithTls, ServerSendPublicReset) {
+  ASSERT_TRUE(Initialize());
+
+  EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
+  QuicConnection* client_connection =
+      client_->client()->client_session()->connection();
+  if (SupportsIetfQuicWithTls(client_connection->version())) {
+    // TLS handshake does not support stateless reset token yet.
+    return;
+  }
+  QuicUint128 stateless_reset_token = 0;
+  if (client_connection->version().handshake_protocol == PROTOCOL_QUIC_CRYPTO) {
+    QuicConfig* config = client_->client()->session()->config();
+    EXPECT_TRUE(config->HasReceivedStatelessResetToken());
+    stateless_reset_token = config->ReceivedStatelessResetToken();
+  }
+
+  // Send the public reset.
+  QuicConnectionId connection_id = client_connection->connection_id();
+  QuicPublicResetPacket header;
+  header.connection_id = connection_id;
+  QuicFramer framer(server_supported_versions_, QuicTime::Zero(),
+                    Perspective::IS_SERVER, kQuicDefaultConnectionIdLength);
+  std::unique_ptr<QuicEncryptedPacket> packet;
+  if (client_connection->transport_version() > QUIC_VERSION_43) {
+    packet = framer.BuildIetfStatelessResetPacket(connection_id,
+                                                  stateless_reset_token);
+  } else {
+    packet = framer.BuildPublicResetPacket(header);
+  }
+  // We must pause the server's thread in order to call WritePacket without
+  // race conditions.
+  server_thread_->Pause();
+  server_writer_->WritePacket(
+      packet->data(), packet->length(), server_address_.host(),
+      client_->client()->network_helper()->GetLatestClientAddress(), nullptr);
+  server_thread_->Resume();
+
+  // The request should fail.
+  EXPECT_EQ("", client_->SendSynchronousRequest("/foo"));
+  EXPECT_TRUE(client_->response_headers()->empty());
+  EXPECT_EQ(QUIC_PUBLIC_RESET, client_->connection_error());
+}
+
+// Send a public reset from the server for a different connection ID.
+// It should be ignored.
+TEST_P(EndToEndTestWithTls, ServerSendPublicResetWithDifferentConnectionId) {
+  ASSERT_TRUE(Initialize());
+
+  EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
+  QuicConnection* client_connection =
+      client_->client()->client_session()->connection();
+  if (SupportsIetfQuicWithTls(client_connection->version())) {
+    // TLS handshake does not support stateless reset token yet.
+    return;
+  }
+  QuicUint128 stateless_reset_token = 0;
+  if (client_connection->version().handshake_protocol == PROTOCOL_QUIC_CRYPTO) {
+    QuicConfig* config = client_->client()->session()->config();
+    EXPECT_TRUE(config->HasReceivedStatelessResetToken());
+    stateless_reset_token = config->ReceivedStatelessResetToken();
+  }
+  // Send the public reset.
+  QuicConnectionId incorrect_connection_id = TestConnectionId(
+      TestConnectionIdToUInt64(client_connection->connection_id()) + 1);
+  QuicPublicResetPacket header;
+  header.connection_id = incorrect_connection_id;
+  QuicFramer framer(server_supported_versions_, QuicTime::Zero(),
+                    Perspective::IS_SERVER, kQuicDefaultConnectionIdLength);
+  std::unique_ptr<QuicEncryptedPacket> packet;
+  testing::NiceMock<MockQuicConnectionDebugVisitor> visitor;
+  client_->client()->client_session()->connection()->set_debug_visitor(
+      &visitor);
+  if (client_connection->transport_version() > QUIC_VERSION_43) {
+    packet = framer.BuildIetfStatelessResetPacket(incorrect_connection_id,
+                                                  stateless_reset_token);
+    EXPECT_CALL(visitor, OnIncorrectConnectionId(incorrect_connection_id))
+        .Times(0);
+  } else {
+    packet = framer.BuildPublicResetPacket(header);
+    EXPECT_CALL(visitor, OnIncorrectConnectionId(incorrect_connection_id))
+        .Times(1);
+  }
+  // We must pause the server's thread in order to call WritePacket without
+  // race conditions.
+  server_thread_->Pause();
+  server_writer_->WritePacket(
+      packet->data(), packet->length(), server_address_.host(),
+      client_->client()->network_helper()->GetLatestClientAddress(), nullptr);
+  server_thread_->Resume();
+
+  if (client_connection->transport_version() > QUIC_VERSION_43) {
+    // The request should fail. IETF stateless reset does not include connection
+    // ID.
+    EXPECT_EQ("", client_->SendSynchronousRequest("/foo"));
+    EXPECT_TRUE(client_->response_headers()->empty());
+    EXPECT_EQ(QUIC_PUBLIC_RESET, client_->connection_error());
+    return;
+  }
+  // The connection should be unaffected.
+  EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
+  EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
+
+  client_->client()->client_session()->connection()->set_debug_visitor(nullptr);
+}
+
+// Send a public reset from the client for a different connection ID.
+// It should be ignored.
+TEST_P(EndToEndTestWithTls, ClientSendPublicResetWithDifferentConnectionId) {
+  ASSERT_TRUE(Initialize());
+
+  // Send the public reset.
+  QuicConnectionId incorrect_connection_id = TestConnectionId(
+      TestConnectionIdToUInt64(
+          client_->client()->client_session()->connection()->connection_id()) +
+      1);
+  QuicPublicResetPacket header;
+  header.connection_id = incorrect_connection_id;
+  QuicFramer framer(server_supported_versions_, QuicTime::Zero(),
+                    Perspective::IS_CLIENT, kQuicDefaultConnectionIdLength);
+  std::unique_ptr<QuicEncryptedPacket> packet(
+      framer.BuildPublicResetPacket(header));
+  client_writer_->WritePacket(
+      packet->data(), packet->length(),
+      client_->client()->network_helper()->GetLatestClientAddress().host(),
+      server_address_, nullptr);
+
+  // The connection should be unaffected.
+  EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
+  EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
+}
+
+// Send a version negotiation packet from the server for a different
+// connection ID.  It should be ignored.
+TEST_P(EndToEndTestWithTls,
+       ServerSendVersionNegotiationWithDifferentConnectionId) {
+  ASSERT_TRUE(Initialize());
+
+  EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
+
+  // Send the version negotiation packet.
+  QuicConnection* client_connection =
+      client_->client()->client_session()->connection();
+  QuicConnectionId incorrect_connection_id = TestConnectionId(
+      TestConnectionIdToUInt64(client_connection->connection_id()) + 1);
+  std::unique_ptr<QuicEncryptedPacket> packet(
+      QuicFramer::BuildVersionNegotiationPacket(
+          incorrect_connection_id,
+          client_connection->transport_version() > QUIC_VERSION_43,
+          server_supported_versions_));
+  testing::NiceMock<MockQuicConnectionDebugVisitor> visitor;
+  client_connection->set_debug_visitor(&visitor);
+  EXPECT_CALL(visitor, OnIncorrectConnectionId(incorrect_connection_id))
+      .Times(1);
+  // We must pause the server's thread in order to call WritePacket without
+  // race conditions.
+  server_thread_->Pause();
+  server_writer_->WritePacket(
+      packet->data(), packet->length(), server_address_.host(),
+      client_->client()->network_helper()->GetLatestClientAddress(), nullptr);
+  server_thread_->Resume();
+
+  // The connection should be unaffected.
+  EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
+  EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
+
+  client_connection->set_debug_visitor(nullptr);
+}
+
+// A bad header shouldn't tear down the connection, because the receiver can't
+// tell the connection ID.
+TEST_P(EndToEndTestWithTls, BadPacketHeaderTruncated) {
+  ASSERT_TRUE(Initialize());
+
+  // Start the connection.
+  EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
+  EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
+
+  // Packet with invalid public flags.
+  char packet[] = {// public flags (8 byte connection_id)
+                   0x3C,
+                   // truncated connection ID
+                   0x11};
+  client_writer_->WritePacket(
+      &packet[0], sizeof(packet),
+      client_->client()->network_helper()->GetLatestClientAddress().host(),
+      server_address_, nullptr);
+  // Give the server time to process the packet.
+  QuicSleep(QuicTime::Delta::FromMilliseconds(100));
+  // Pause the server so we can access the server's internals without races.
+  server_thread_->Pause();
+  QuicDispatcher* dispatcher =
+      QuicServerPeer::GetDispatcher(server_thread_->server());
+  EXPECT_EQ(QUIC_INVALID_PACKET_HEADER,
+            QuicDispatcherPeer::GetAndClearLastError(dispatcher));
+  server_thread_->Resume();
+
+  // The connection should not be terminated.
+  EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
+  EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
+}
+
+// A bad header shouldn't tear down the connection, because the receiver can't
+// tell the connection ID.
+TEST_P(EndToEndTestWithTls, BadPacketHeaderFlags) {
+  ASSERT_TRUE(Initialize());
+
+  // Start the connection.
+  EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
+  EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
+
+  // Packet with invalid public flags.
+  char packet[] = {
+      // invalid public flags
+      0xFF,
+      // connection_id
+      0x10,
+      0x32,
+      0x54,
+      0x76,
+      0x98,
+      0xBA,
+      0xDC,
+      0xFE,
+      // packet sequence number
+      0xBC,
+      0x9A,
+      0x78,
+      0x56,
+      0x34,
+      0x12,
+      // private flags
+      0x00,
+  };
+  client_writer_->WritePacket(
+      &packet[0], sizeof(packet),
+      client_->client()->network_helper()->GetLatestClientAddress().host(),
+      server_address_, nullptr);
+  // Give the server time to process the packet.
+  QuicSleep(QuicTime::Delta::FromMilliseconds(100));
+  // Pause the server so we can access the server's internals without races.
+  server_thread_->Pause();
+  QuicDispatcher* dispatcher =
+      QuicServerPeer::GetDispatcher(server_thread_->server());
+  EXPECT_EQ(QUIC_INVALID_PACKET_HEADER,
+            QuicDispatcherPeer::GetAndClearLastError(dispatcher));
+  server_thread_->Resume();
+
+  // The connection should not be terminated.
+  EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
+  EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
+}
+
+// Send a packet from the client with bad encrypted data.  The server should not
+// tear down the connection.
+TEST_P(EndToEndTestWithTls, BadEncryptedData) {
+  ASSERT_TRUE(Initialize());
+
+  // Start the connection.
+  EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
+  EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
+
+  std::unique_ptr<QuicEncryptedPacket> packet(ConstructEncryptedPacket(
+      client_->client()->client_session()->connection()->connection_id(),
+      EmptyQuicConnectionId(), false, false, 1, "At least 20 characters.",
+      CONNECTION_ID_PRESENT, CONNECTION_ID_ABSENT, PACKET_4BYTE_PACKET_NUMBER));
+  // Damage the encrypted data.
+  QuicString damaged_packet(packet->data(), packet->length());
+  damaged_packet[30] ^= 0x01;
+  QUIC_DLOG(INFO) << "Sending bad packet.";
+  client_writer_->WritePacket(
+      damaged_packet.data(), damaged_packet.length(),
+      client_->client()->network_helper()->GetLatestClientAddress().host(),
+      server_address_, nullptr);
+  // Give the server time to process the packet.
+  QuicSleep(QuicTime::Delta::FromMilliseconds(100));
+  // This error is sent to the connection's OnError (which ignores it), so the
+  // dispatcher doesn't see it.
+  // Pause the server so we can access the server's internals without races.
+  server_thread_->Pause();
+  QuicDispatcher* dispatcher =
+      QuicServerPeer::GetDispatcher(server_thread_->server());
+  EXPECT_EQ(QUIC_NO_ERROR,
+            QuicDispatcherPeer::GetAndClearLastError(dispatcher));
+  server_thread_->Resume();
+
+  // The connection should not be terminated.
+  EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
+  EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
+}
+
+TEST_P(EndToEndTestWithTls, CanceledStreamDoesNotBecomeZombie) {
+  ASSERT_TRUE(Initialize());
+  EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
+  // Lose the request.
+  SetPacketLossPercentage(100);
+  SpdyHeaderBlock headers;
+  headers[":method"] = "POST";
+  headers[":path"] = "/foo";
+  headers[":scheme"] = "https";
+  headers[":authority"] = server_hostname_;
+  client_->SendMessage(headers, "test_body", /*fin=*/false);
+  QuicSpdyClientStream* stream = client_->GetOrCreateStream();
+
+  // Cancel the stream.
+  stream->Reset(QUIC_STREAM_CANCELLED);
+  QuicSession* session = client_->client()->client_session();
+  // Verify canceled stream does not become zombie.
+  EXPECT_TRUE(QuicSessionPeer::zombie_streams(session).empty());
+  EXPECT_EQ(1u, QuicSessionPeer::closed_streams(session).size());
+}
+
+// A test stream that gives |response_body_| as an error response body.
+class ServerStreamWithErrorResponseBody : public QuicSimpleServerStream {
+ public:
+  ServerStreamWithErrorResponseBody(
+      QuicStreamId id,
+      QuicSpdySession* session,
+      QuicSimpleServerBackend* quic_simple_server_backend,
+      QuicString response_body)
+      : QuicSimpleServerStream(id,
+                               session,
+                               BIDIRECTIONAL,
+                               quic_simple_server_backend),
+        response_body_(std::move(response_body)) {}
+
+  ~ServerStreamWithErrorResponseBody() override = default;
+
+ protected:
+  void SendErrorResponse() override {
+    QUIC_DLOG(INFO) << "Sending error response for stream " << id();
+    SpdyHeaderBlock headers;
+    headers[":status"] = "500";
+    headers["content-length"] =
+        QuicTextUtils::Uint64ToString(response_body_.size());
+    // This method must call CloseReadSide to cause the test case, StopReading
+    // is not sufficient.
+    QuicStreamPeer::CloseReadSide(this);
+    SendHeadersAndBody(std::move(headers), response_body_);
+  }
+
+  QuicString response_body_;
+};
+
+class StreamWithErrorFactory : public QuicTestServer::StreamFactory {
+ public:
+  explicit StreamWithErrorFactory(QuicString response_body)
+      : response_body_(std::move(response_body)) {}
+
+  ~StreamWithErrorFactory() override = default;
+
+  QuicSimpleServerStream* CreateStream(
+      QuicStreamId id,
+      QuicSpdySession* session,
+      QuicSimpleServerBackend* quic_simple_server_backend) override {
+    return new ServerStreamWithErrorResponseBody(
+        id, session, quic_simple_server_backend, response_body_);
+  }
+
+ private:
+  QuicString response_body_;
+};
+
+// A test server stream that drops all received body.
+class ServerStreamThatDropsBody : public QuicSimpleServerStream {
+ public:
+  ServerStreamThatDropsBody(QuicStreamId id,
+                            QuicSpdySession* session,
+                            QuicSimpleServerBackend* quic_simple_server_backend)
+      : QuicSimpleServerStream(id,
+                               session,
+                               BIDIRECTIONAL,
+                               quic_simple_server_backend) {}
+
+  ~ServerStreamThatDropsBody() override = default;
+
+ protected:
+  void OnBodyAvailable() override {
+    while (HasBytesToRead()) {
+      struct iovec iov;
+      if (GetReadableRegions(&iov, 1) == 0) {
+        // No more data to read.
+        break;
+      }
+      QUIC_DVLOG(1) << "Processed " << iov.iov_len << " bytes for stream "
+                    << id();
+      MarkConsumed(iov.iov_len);
+    }
+
+    if (!sequencer()->IsClosed()) {
+      sequencer()->SetUnblocked();
+      return;
+    }
+
+    // If the sequencer is closed, then all the body, including the fin, has
+    // been consumed.
+    OnFinRead();
+
+    if (write_side_closed() || fin_buffered()) {
+      return;
+    }
+
+    SendResponse();
+  }
+};
+
+class ServerStreamThatDropsBodyFactory : public QuicTestServer::StreamFactory {
+ public:
+  ServerStreamThatDropsBodyFactory() = default;
+
+  ~ServerStreamThatDropsBodyFactory() override = default;
+
+  QuicSimpleServerStream* CreateStream(
+      QuicStreamId id,
+      QuicSpdySession* session,
+      QuicSimpleServerBackend* quic_simple_server_backend) override {
+    return new ServerStreamThatDropsBody(id, session,
+                                         quic_simple_server_backend);
+  }
+};
+
+// A test server stream that sends response with body size greater than 4GB.
+class ServerStreamThatSendsHugeResponse : public QuicSimpleServerStream {
+ public:
+  ServerStreamThatSendsHugeResponse(
+      QuicStreamId id,
+      QuicSpdySession* session,
+      QuicSimpleServerBackend* quic_simple_server_backend,
+      int64_t body_bytes)
+      : QuicSimpleServerStream(id,
+                               session,
+                               BIDIRECTIONAL,
+                               quic_simple_server_backend),
+        body_bytes_(body_bytes) {}
+
+  ~ServerStreamThatSendsHugeResponse() override = default;
+
+ protected:
+  void SendResponse() override {
+    QuicBackendResponse response;
+    QuicString body(body_bytes_, 'a');
+    response.set_body(body);
+    SendHeadersAndBodyAndTrailers(response.headers().Clone(), response.body(),
+                                  response.trailers().Clone());
+  }
+
+ private:
+  // Use a explicit int64_t rather than size_t to simulate a 64-bit server
+  // talking to a 32-bit client.
+  int64_t body_bytes_;
+};
+
+class ServerStreamThatSendsHugeResponseFactory
+    : public QuicTestServer::StreamFactory {
+ public:
+  explicit ServerStreamThatSendsHugeResponseFactory(int64_t body_bytes)
+      : body_bytes_(body_bytes) {}
+
+  ~ServerStreamThatSendsHugeResponseFactory() override = default;
+
+  QuicSimpleServerStream* CreateStream(
+      QuicStreamId id,
+      QuicSpdySession* session,
+      QuicSimpleServerBackend* quic_simple_server_backend) override {
+    return new ServerStreamThatSendsHugeResponse(
+        id, session, quic_simple_server_backend, body_bytes_);
+  }
+
+  int64_t body_bytes_;
+};
+
+TEST_P(EndToEndTest, EarlyResponseFinRecording) {
+  set_smaller_flow_control_receive_window();
+
+  // Verify that an incoming FIN is recorded in a stream object even if the read
+  // side has been closed.  This prevents an entry from being made in
+  // locally_close_streams_highest_offset_ (which will never be deleted).
+  // To set up the test condition, the server must do the following in order:
+  // start sending the response and call CloseReadSide
+  // receive the FIN of the request
+  // send the FIN of the response
+
+  // The response body must be larger than the flow control window so the server
+  // must receive a window update from the client before it can finish sending
+  // it.
+  uint32_t response_body_size =
+      2 * client_config_.GetInitialStreamFlowControlWindowToSend();
+  QuicString response_body(response_body_size, 'a');
+
+  StreamWithErrorFactory stream_factory(response_body);
+  SetSpdyStreamFactory(&stream_factory);
+
+  ASSERT_TRUE(Initialize());
+
+  EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
+
+  // A POST that gets an early error response, after the headers are received
+  // and before the body is received, due to invalid content-length.
+  // Set an invalid content-length, so the request will receive an early 500
+  // response.
+  SpdyHeaderBlock headers;
+  headers[":method"] = "POST";
+  headers[":path"] = "/garbage";
+  headers[":scheme"] = "https";
+  headers[":authority"] = server_hostname_;
+  headers["content-length"] = "-1";
+
+  // The body must be large enough that the FIN will be in a different packet
+  // than the end of the headers, but short enough to not require a flow control
+  // update.  This allows headers processing to trigger the error response
+  // before the request FIN is processed but receive the request FIN before the
+  // response is sent completely.
+  const uint32_t kRequestBodySize = kMaxPacketSize + 10;
+  QuicString request_body(kRequestBodySize, 'a');
+
+  // Send the request.
+  client_->SendMessage(headers, request_body);
+  client_->WaitForResponse();
+  EXPECT_EQ("500", client_->response_headers()->find(":status")->second);
+
+  // Pause the server so we can access the server's internals without races.
+  server_thread_->Pause();
+
+  QuicDispatcher* dispatcher =
+      QuicServerPeer::GetDispatcher(server_thread_->server());
+  QuicDispatcher::SessionMap const& map =
+      QuicDispatcherPeer::session_map(dispatcher);
+  auto it = map.begin();
+  EXPECT_TRUE(it != map.end());
+  QuicSession* server_session = it->second.get();
+
+  // The stream is not waiting for the arrival of the peer's final offset.
+  EXPECT_EQ(
+      0u, QuicSessionPeer::GetLocallyClosedStreamsHighestOffset(server_session)
+              .size());
+
+  server_thread_->Resume();
+}
+
+TEST_P(EndToEndTestWithTls, Trailers) {
+  // Test sending and receiving HTTP/2 Trailers (trailing HEADERS frames).
+  ASSERT_TRUE(Initialize());
+  EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
+
+  // Set reordering to ensure that Trailers arriving before body is ok.
+  SetPacketSendDelay(QuicTime::Delta::FromMilliseconds(2));
+  SetReorderPercentage(30);
+
+  // Add a response with headers, body, and trailers.
+  const QuicString kBody = "body content";
+
+  SpdyHeaderBlock headers;
+  headers[":status"] = "200";
+  headers[":version"] = "HTTP/1.1";
+  headers["content-length"] = QuicTextUtils::Uint64ToString(kBody.size());
+
+  SpdyHeaderBlock trailers;
+  trailers["some-trailing-header"] = "trailing-header-value";
+
+  memory_cache_backend_.AddResponse(server_hostname_, "/trailer_url",
+                                    std::move(headers), kBody,
+                                    trailers.Clone());
+
+  EXPECT_EQ(kBody, client_->SendSynchronousRequest("/trailer_url"));
+  EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
+  EXPECT_EQ(trailers, client_->response_trailers());
+}
+
+class EndToEndTestServerPush : public EndToEndTest {
+ protected:
+  const size_t kNumMaxStreams = 10;
+
+  EndToEndTestServerPush() : EndToEndTest() {
+    client_config_.SetMaxIncomingDynamicStreamsToSend(kNumMaxStreams);
+    server_config_.SetMaxIncomingDynamicStreamsToSend(kNumMaxStreams);
+    support_server_push_ = true;
+  }
+
+  // Add a request with its response and |num_resources| push resources into
+  // cache.
+  // If |resource_size| == 0, response body of push resources use default string
+  // concatenating with resource url. Otherwise, generate a string of
+  // |resource_size| as body.
+  void AddRequestAndResponseWithServerPush(QuicString host,
+                                           QuicString path,
+                                           QuicString response_body,
+                                           QuicString* push_urls,
+                                           const size_t num_resources,
+                                           const size_t resource_size) {
+    bool use_large_response = resource_size != 0;
+    QuicString large_resource;
+    if (use_large_response) {
+      // Generate a response common body larger than flow control window for
+      // push response.
+      large_resource = QuicString(resource_size, 'a');
+    }
+    std::list<QuicBackendResponse::ServerPushInfo> push_resources;
+    for (size_t i = 0; i < num_resources; ++i) {
+      QuicString url = push_urls[i];
+      QuicUrl resource_url(url);
+      QuicString body =
+          use_large_response
+              ? large_resource
+              : QuicStrCat("This is server push response body for ", url);
+      SpdyHeaderBlock response_headers;
+      response_headers[":version"] = "HTTP/1.1";
+      response_headers[":status"] = "200";
+      response_headers["content-length"] =
+          QuicTextUtils::Uint64ToString(body.size());
+      push_resources.push_back(QuicBackendResponse::ServerPushInfo(
+          resource_url, std::move(response_headers), kV3LowestPriority, body));
+    }
+
+    memory_cache_backend_.AddSimpleResponseWithServerPushResources(
+        host, path, 200, response_body, push_resources);
+  }
+};
+
+// Run all server push end to end tests with all supported versions.
+INSTANTIATE_TEST_SUITE_P(EndToEndTestsServerPush,
+                         EndToEndTestServerPush,
+                         ::testing::ValuesIn(GetTestParams(false, false)));
+
+TEST_P(EndToEndTestServerPush, ServerPush) {
+  ASSERT_TRUE(Initialize());
+  EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
+
+  // Set reordering to ensure that body arriving before PUSH_PROMISE is ok.
+  SetPacketSendDelay(QuicTime::Delta::FromMilliseconds(2));
+  SetReorderPercentage(30);
+
+  // Add a response with headers, body, and push resources.
+  const QuicString kBody = "body content";
+  size_t kNumResources = 4;
+  QuicString push_urls[] = {"https://example.com/font.woff",
+                            "https://example.com/script.js",
+                            "https://fonts.example.com/font.woff",
+                            "https://example.com/logo-hires.jpg"};
+  AddRequestAndResponseWithServerPush("example.com", "/push_example", kBody,
+                                      push_urls, kNumResources, 0);
+
+  client_->client()->set_response_listener(
+      std::unique_ptr<QuicSpdyClientBase::ResponseListener>(
+          new TestResponseListener));
+
+  QUIC_DVLOG(1) << "send request for /push_example";
+  EXPECT_EQ(kBody, client_->SendSynchronousRequest(
+                       "https://example.com/push_example"));
+  QuicHeadersStream* headers_stream = QuicSpdySessionPeer::GetHeadersStream(
+      client_->client()->client_session());
+  QuicStreamSequencer* sequencer = QuicStreamPeer::sequencer(headers_stream);
+  // Headers stream's sequencer buffer shouldn't be released because server push
+  // hasn't finished yet.
+  EXPECT_TRUE(QuicStreamSequencerPeer::IsUnderlyingBufferAllocated(sequencer));
+
+  for (const QuicString& url : push_urls) {
+    QUIC_DVLOG(1) << "send request for pushed stream on url " << url;
+    QuicString expected_body =
+        QuicStrCat("This is server push response body for ", url);
+    QuicString response_body = client_->SendSynchronousRequest(url);
+    QUIC_DVLOG(1) << "response body " << response_body;
+    EXPECT_EQ(expected_body, response_body);
+  }
+  EXPECT_FALSE(QuicStreamSequencerPeer::IsUnderlyingBufferAllocated(sequencer));
+}
+
+TEST_P(EndToEndTestServerPush, ServerPushUnderLimit) {
+  // Tests that sending a request which has 4 push resources will trigger server
+  // to push those 4 resources and client can handle pushed resources and match
+  // them with requests later.
+  ASSERT_TRUE(Initialize());
+
+  EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
+
+  // Set reordering to ensure that body arriving before PUSH_PROMISE is ok.
+  SetPacketSendDelay(QuicTime::Delta::FromMilliseconds(2));
+  SetReorderPercentage(30);
+
+  // Add a response with headers, body, and push resources.
+  const QuicString kBody = "body content";
+  size_t const kNumResources = 4;
+  QuicString push_urls[] = {
+      "https://example.com/font.woff",
+      "https://example.com/script.js",
+      "https://fonts.example.com/font.woff",
+      "https://example.com/logo-hires.jpg",
+  };
+  AddRequestAndResponseWithServerPush("example.com", "/push_example", kBody,
+                                      push_urls, kNumResources, 0);
+  client_->client()->set_response_listener(
+      std::unique_ptr<QuicSpdyClientBase::ResponseListener>(
+          new TestResponseListener));
+
+  // Send the first request: this will trigger the server to send all the push
+  // resources associated with this request, and these will be cached by the
+  // client.
+  EXPECT_EQ(kBody, client_->SendSynchronousRequest(
+                       "https://example.com/push_example"));
+
+  for (const QuicString& url : push_urls) {
+    // Sending subsequent requesets will not actually send anything on the wire,
+    // as the responses are already in the client's cache.
+    QUIC_DVLOG(1) << "send request for pushed stream on url " << url;
+    QuicString expected_body =
+        QuicStrCat("This is server push response body for ", url);
+    QuicString response_body = client_->SendSynchronousRequest(url);
+    QUIC_DVLOG(1) << "response body " << response_body;
+    EXPECT_EQ(expected_body, response_body);
+  }
+  // Expect only original request has been sent and push responses have been
+  // received as normal response.
+  EXPECT_EQ(1u, client_->num_requests());
+  EXPECT_EQ(1u + kNumResources, client_->num_responses());
+}
+
+TEST_P(EndToEndTestServerPush, ServerPushOverLimitNonBlocking) {
+  // Tests that when streams are not blocked by flow control or congestion
+  // control, pushing even more resources than max number of open outgoing
+  // streams should still work because all response streams get closed
+  // immediately after pushing resources.
+  ASSERT_TRUE(Initialize());
+  EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
+
+  // Set reordering to ensure that body arriving before PUSH_PROMISE is ok.
+  SetPacketSendDelay(QuicTime::Delta::FromMilliseconds(2));
+  SetReorderPercentage(30);
+
+  // Add a response with headers, body, and push resources.
+  const QuicString kBody = "body content";
+
+  // One more resource than max number of outgoing stream of this session.
+  const size_t kNumResources = 1 + kNumMaxStreams;  // 11.
+  QuicString push_urls[11];
+  for (size_t i = 0; i < kNumResources; ++i) {
+    push_urls[i] = QuicStrCat("https://example.com/push_resources", i);
+  }
+  AddRequestAndResponseWithServerPush("example.com", "/push_example", kBody,
+                                      push_urls, kNumResources, 0);
+  client_->client()->set_response_listener(
+      std::unique_ptr<QuicSpdyClientBase::ResponseListener>(
+          new TestResponseListener));
+
+  // Send the first request: this will trigger the server to send all the push
+  // resources associated with this request, and these will be cached by the
+  // client.
+  EXPECT_EQ(kBody, client_->SendSynchronousRequest(
+                       "https://example.com/push_example"));
+
+  for (const QuicString& url : push_urls) {
+    // Sending subsequent requesets will not actually send anything on the wire,
+    // as the responses are already in the client's cache.
+    EXPECT_EQ(QuicStrCat("This is server push response body for ", url),
+              client_->SendSynchronousRequest(url));
+  }
+
+  // Only 1 request should have been sent.
+  EXPECT_EQ(1u, client_->num_requests());
+  // The responses to the original request and all the promised resources
+  // should have been received.
+  EXPECT_EQ(12u, client_->num_responses());
+}
+
+TEST_P(EndToEndTestServerPush, ServerPushOverLimitWithBlocking) {
+  // Tests that when server tries to send more large resources(large enough to
+  // be blocked by flow control window or congestion control window) than max
+  // open outgoing streams , server can open upto max number of outgoing
+  // streams for them, and the rest will be queued up.
+
+  // Reset flow control windows.
+  size_t kFlowControlWnd = 20 * 1024;  // 20KB.
+  // Response body is larger than 1 flow controlblock window.
+  size_t kBodySize = kFlowControlWnd * 2;
+  set_client_initial_stream_flow_control_receive_window(kFlowControlWnd);
+  // Make sure conntection level flow control window is large enough not to
+  // block data being sent out though they will be blocked by stream level one.
+  set_client_initial_session_flow_control_receive_window(
+      kBodySize * kNumMaxStreams + 1024);
+
+  ASSERT_TRUE(Initialize());
+  EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
+
+  // Set reordering to ensure that body arriving before PUSH_PROMISE is ok.
+  SetPacketSendDelay(QuicTime::Delta::FromMilliseconds(2));
+  SetReorderPercentage(30);
+
+  // Add a response with headers, body, and push resources.
+  const QuicString kBody = "body content";
+
+  const size_t kNumResources = kNumMaxStreams + 1;
+  QuicString push_urls[11];
+  for (size_t i = 0; i < kNumResources; ++i) {
+    push_urls[i] = QuicStrCat("http://example.com/push_resources", i);
+  }
+  AddRequestAndResponseWithServerPush("example.com", "/push_example", kBody,
+                                      push_urls, kNumResources, kBodySize);
+
+  client_->client()->set_response_listener(
+      std::unique_ptr<QuicSpdyClientBase::ResponseListener>(
+          new TestResponseListener));
+
+  client_->SendRequest("https://example.com/push_example");
+
+  // Pause after the first response arrives.
+  while (!client_->response_complete()) {
+    // Because of priority, the first response arrived should be to original
+    // request.
+    client_->WaitForResponse();
+  }
+
+  // Check server session to see if it has max number of outgoing streams opened
+  // though more resources need to be pushed.
+  server_thread_->Pause();
+  EXPECT_EQ(kNumMaxStreams, GetServerSession()->GetNumOpenOutgoingStreams());
+  server_thread_->Resume();
+
+  EXPECT_EQ(1u, client_->num_requests());
+  EXPECT_EQ(1u, client_->num_responses());
+  EXPECT_EQ(kBody, client_->response_body());
+
+  // "Send" request for a promised resources will not really send out it because
+  // its response is being pushed(but blocked). And the following ack and
+  // flow control behavior of SendSynchronousRequests()
+  // will unblock the stream to finish receiving response.
+  client_->SendSynchronousRequest(push_urls[0]);
+  EXPECT_EQ(1u, client_->num_requests());
+  EXPECT_EQ(2u, client_->num_responses());
+
+  // Do same thing for the rest 10 resources.
+  for (size_t i = 1; i < kNumResources; ++i) {
+    client_->SendSynchronousRequest(push_urls[i]);
+  }
+
+  // Because of server push, client gets all pushed resources without actually
+  // sending requests for them.
+  EXPECT_EQ(1u, client_->num_requests());
+  // Including response to original request, 12 responses in total were
+  // received.
+  EXPECT_EQ(12u, client_->num_responses());
+}
+
+// TODO(fayang): this test seems to cause net_unittests timeouts :|
+TEST_P(EndToEndTest, DISABLED_TestHugePostWithPacketLoss) {
+  // This test tests a huge post with introduced packet loss from client to
+  // server and body size greater than 4GB, making sure QUIC code does not break
+  // for 32-bit builds.
+  ServerStreamThatDropsBodyFactory stream_factory;
+  SetSpdyStreamFactory(&stream_factory);
+  ASSERT_TRUE(Initialize());
+  // Set client's epoll server's time out to 0 to make this test be finished
+  // within a short time.
+  client_->epoll_server()->set_timeout_in_us(0);
+
+  EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
+  SetPacketLossPercentage(1);
+  // To avoid storing the whole request body in memory, use a loop to repeatedly
+  // send body size of kSizeBytes until the whole request body size is reached.
+  const int kSizeBytes = 128 * 1024;
+  // Request body size is 4G plus one more kSizeBytes.
+  int64_t request_body_size_bytes = pow(2, 32) + kSizeBytes;
+  ASSERT_LT(INT64_C(4294967296), request_body_size_bytes);
+  QuicString body(kSizeBytes, 'a');
+
+  SpdyHeaderBlock headers;
+  headers[":method"] = "POST";
+  headers[":path"] = "/foo";
+  headers[":scheme"] = "https";
+  headers[":authority"] = server_hostname_;
+  headers["content-length"] =
+      QuicTextUtils::Uint64ToString(request_body_size_bytes);
+
+  client_->SendMessage(headers, "", /*fin=*/false);
+
+  for (int i = 0; i < request_body_size_bytes / kSizeBytes; ++i) {
+    bool fin = (i == request_body_size_bytes - 1);
+    client_->SendData(QuicString(body.data(), kSizeBytes), fin);
+    client_->client()->WaitForEvents();
+  }
+  VerifyCleanConnection(true);
+}
+
+// TODO(fayang): this test seems to cause net_unittests timeouts :|
+TEST_P(EndToEndTest, DISABLED_TestHugeResponseWithPacketLoss) {
+  // This test tests a huge response with introduced loss from server to client
+  // and body size greater than 4GB, making sure QUIC code does not break for
+  // 32-bit builds.
+  const int kSizeBytes = 128 * 1024;
+  int64_t response_body_size_bytes = pow(2, 32) + kSizeBytes;
+  ASSERT_LT(4294967296, response_body_size_bytes);
+  ServerStreamThatSendsHugeResponseFactory stream_factory(
+      response_body_size_bytes);
+  SetSpdyStreamFactory(&stream_factory);
+
+  StartServer();
+
+  // Use a quic client that drops received body.
+  QuicTestClient* client =
+      new QuicTestClient(server_address_, server_hostname_, client_config_,
+                         client_supported_versions_);
+  client->client()->set_drop_response_body(true);
+  client->UseWriter(client_writer_);
+  client->Connect();
+  client_.reset(client);
+  static QuicEpollEvent event(EPOLLOUT);
+  client_writer_->Initialize(
+      QuicConnectionPeer::GetHelper(
+          client_->client()->client_session()->connection()),
+      QuicConnectionPeer::GetAlarmFactory(
+          client_->client()->client_session()->connection()),
+      QuicMakeUnique<ClientDelegate>(client_->client()));
+  initialized_ = true;
+  ASSERT_TRUE(client_->client()->connected());
+
+  EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
+  SetPacketLossPercentage(1);
+  client_->SendRequest("/huge_response");
+  client_->WaitForResponse();
+  // TODO(fayang): Fix this test to work with stateless rejects.
+  if (!BothSidesSupportStatelessRejects()) {
+    VerifyCleanConnection(true);
+  }
+}
+
+// Regression test for b/111515567
+TEST_P(EndToEndTest, AgreeOnStopWaiting) {
+  ASSERT_TRUE(Initialize());
+  EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
+
+  QuicConnection* client_connection =
+      client_->client()->client_session()->connection();
+  server_thread_->Pause();
+  QuicConnection* server_connection = GetServerConnection();
+  // Verify client and server connections agree on the value of
+  // no_stop_waiting_frames.
+  EXPECT_EQ(QuicConnectionPeer::GetNoStopWaitingFrames(client_connection),
+            QuicConnectionPeer::GetNoStopWaitingFrames(server_connection));
+  server_thread_->Resume();
+}
+
+// Regression test for b/111515567
+TEST_P(EndToEndTest, AgreeOnStopWaitingWithNoStopWaitingOption) {
+  QuicTagVector options;
+  options.push_back(kNSTP);
+  client_config_.SetConnectionOptionsToSend(options);
+  ASSERT_TRUE(Initialize());
+  EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
+
+  QuicConnection* client_connection =
+      client_->client()->client_session()->connection();
+  server_thread_->Pause();
+  QuicConnection* server_connection = GetServerConnection();
+  // Verify client and server connections agree on the value of
+  // no_stop_waiting_frames.
+  EXPECT_EQ(QuicConnectionPeer::GetNoStopWaitingFrames(client_connection),
+            QuicConnectionPeer::GetNoStopWaitingFrames(server_connection));
+  server_thread_->Resume();
+}
+
+TEST_P(EndToEndTest, ReleaseHeadersStreamBufferWhenIdle) {
+  // Tests that when client side has no active request and no waiting
+  // PUSH_PROMISE, its headers stream's sequencer buffer should be released.
+  ASSERT_TRUE(Initialize());
+  client_->SendSynchronousRequest("/foo");
+  QuicHeadersStream* headers_stream = QuicSpdySessionPeer::GetHeadersStream(
+      client_->client()->client_session());
+  QuicStreamSequencer* sequencer = QuicStreamPeer::sequencer(headers_stream);
+  EXPECT_FALSE(QuicStreamSequencerPeer::IsUnderlyingBufferAllocated(sequencer));
+}
+
+TEST_P(EndToEndTest, WayTooLongRequestHeaders) {
+  ASSERT_TRUE(Initialize());
+  SpdyHeaderBlock headers;
+  headers[":method"] = "GET";
+  headers[":path"] = "/foo";
+  headers[":scheme"] = "https";
+  headers[":authority"] = server_hostname_;
+  headers["key"] = QuicString(64 * 1024, 'a');
+
+  client_->SendMessage(headers, "");
+  client_->WaitForResponse();
+  EXPECT_EQ(QUIC_HEADERS_STREAM_DATA_DECOMPRESS_FAILURE,
+            client_->connection_error());
+}
+
+class WindowUpdateObserver : public QuicConnectionDebugVisitor {
+ public:
+  WindowUpdateObserver() : num_window_update_frames_(0), num_ping_frames_(0) {}
+
+  size_t num_window_update_frames() const { return num_window_update_frames_; }
+
+  size_t num_ping_frames() const { return num_ping_frames_; }
+
+  void OnWindowUpdateFrame(const QuicWindowUpdateFrame& frame,
+                           const QuicTime& receive_time) override {
+    ++num_window_update_frames_;
+  }
+
+  void OnPingFrame(const QuicPingFrame& frame) override { ++num_ping_frames_; }
+
+ private:
+  size_t num_window_update_frames_;
+  size_t num_ping_frames_;
+};
+
+TEST_P(EndToEndTest, WindowUpdateInAck) {
+  ASSERT_TRUE(Initialize());
+  EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
+  WindowUpdateObserver observer;
+  QuicConnection* client_connection =
+      client_->client()->client_session()->connection();
+  client_connection->set_debug_visitor(&observer);
+  // 100KB body.
+  QuicString body(100 * 1024, 'a');
+  SpdyHeaderBlock headers;
+  headers[":method"] = "POST";
+  headers[":path"] = "/foo";
+  headers[":scheme"] = "https";
+  headers[":authority"] = server_hostname_;
+
+  EXPECT_EQ(kFooResponseBody,
+            client_->SendCustomSynchronousRequest(headers, body));
+  client_->Disconnect();
+  EXPECT_LT(0u, observer.num_window_update_frames());
+  EXPECT_EQ(0u, observer.num_ping_frames());
+}
+
+TEST_P(EndToEndTest, SendStatelessResetTokenInShlo) {
+  ASSERT_TRUE(Initialize());
+  EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
+  QuicConfig* config = client_->client()->session()->config();
+  EXPECT_TRUE(config->HasReceivedStatelessResetToken());
+  EXPECT_EQ(QuicUtils::GenerateStatelessResetToken(
+                client_->client()->session()->connection()->connection_id()),
+            config->ReceivedStatelessResetToken());
+  client_->Disconnect();
+}
+
+// Regression test for b/116200989.
+TEST_P(EndToEndTest,
+       SendStatelessResetIfServerConnectionClosedLocallyDuringHandshake) {
+  connect_to_server_on_initialize_ = false;
+  ASSERT_TRUE(Initialize());
+
+  server_thread_->Pause();
+  QuicDispatcher* dispatcher =
+      QuicServerPeer::GetDispatcher(server_thread_->server());
+  ASSERT_EQ(0u, dispatcher->session_map().size());
+  // Note: this writer will only used by the server connection, not the time
+  // wait list.
+  QuicDispatcherPeer::UseWriter(
+      dispatcher,
+      // This cause the first server-sent packet, a.k.a REJ, to fail.
+      new BadPacketWriter(/*packet_causing_write_error=*/0, EPERM));
+  server_thread_->Resume();
+
+  client_.reset(CreateQuicClient(client_writer_));
+  EXPECT_EQ("", client_->SendSynchronousRequest("/foo"));
+
+  if (client_->client()->client_session()->connection()->transport_version() >
+      QUIC_VERSION_43) {
+    EXPECT_EQ(QUIC_HANDSHAKE_FAILED, client_->connection_error());
+  } else {
+    EXPECT_EQ(QUIC_PUBLIC_RESET, client_->connection_error());
+  }
+}
+
+// Regression test for b/116200989.
+TEST_P(EndToEndTest,
+       SendStatelessResetIfServerConnectionClosedLocallyAfterHandshake) {
+  // Prevent the connection from expiring in the time wait list.
+  FLAGS_quic_time_wait_list_seconds = 10000;
+  connect_to_server_on_initialize_ = false;
+  ASSERT_TRUE(Initialize());
+
+  // big_response_body is 64K, which is about 48 full-sized packets.
+  const size_t kBigResponseBodySize = 65536;
+  QuicData big_response_body(new char[kBigResponseBodySize](),
+                             kBigResponseBodySize, /*owns_buffer=*/true);
+  AddToCache("/big_response", 200, big_response_body.AsStringPiece());
+
+  server_thread_->Pause();
+  QuicDispatcher* dispatcher =
+      QuicServerPeer::GetDispatcher(server_thread_->server());
+  ASSERT_EQ(0u, dispatcher->session_map().size());
+  QuicDispatcherPeer::UseWriter(
+      dispatcher,
+      // This will cause an server write error with EPERM, while sending the
+      // response for /big_response.
+      new BadPacketWriter(/*packet_causing_write_error=*/20, EPERM));
+  server_thread_->Resume();
+
+  client_.reset(CreateQuicClient(client_writer_));
+
+  // First, a /foo request with small response should succeed.
+  EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
+  EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
+
+  // Second, a /big_response request with big response should fail.
+  EXPECT_LT(client_->SendSynchronousRequest("/big_response").length(),
+            kBigResponseBodySize);
+  EXPECT_EQ(QUIC_PUBLIC_RESET, client_->connection_error());
+}
+
+// Regression test of b/70782529.
+TEST_P(EndToEndTest, DoNotCrashOnPacketWriteError) {
+  ASSERT_TRUE(Initialize());
+  BadPacketWriter* bad_writer =
+      new BadPacketWriter(/*packet_causing_write_error=*/5,
+                          /*error_code=*/90);
+  std::unique_ptr<QuicTestClient> client(CreateQuicClient(bad_writer));
+
+  // 1 MB body.
+  QuicString body(1024 * 1024, 'a');
+  SpdyHeaderBlock headers;
+  headers[":method"] = "POST";
+  headers[":path"] = "/foo";
+  headers[":scheme"] = "https";
+  headers[":authority"] = server_hostname_;
+
+  client->SendCustomSynchronousRequest(headers, body);
+}
+
+// Regression test for b/71711996. This test sends a connectivity probing packet
+// as its last sent packet, and makes sure the server's ACK of that packet does
+// not cause the client to fail.
+TEST_P(EndToEndTest, LastPacketSentIsConnectivityProbing) {
+  ASSERT_TRUE(Initialize());
+
+  EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
+  EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
+
+  // Wait for the client's ACK (of the response) to be received by the server.
+  client_->WaitForDelayedAcks();
+
+  // We are sending a connectivity probing packet from an unchanged client
+  // address, so the server will not respond to us with a connectivity probing
+  // packet, however the server should send an ack-only packet to us.
+  client_->SendConnectivityProbing();
+
+  // Wait for the server's last ACK to be received by the client.
+  client_->WaitForDelayedAcks();
+}
+
+TEST_P(EndToEndTest, PreSharedKey) {
+  client_config_.set_max_time_before_crypto_handshake(
+      QuicTime::Delta::FromSeconds(1));
+  client_config_.set_max_idle_time_before_crypto_handshake(
+      QuicTime::Delta::FromSeconds(1));
+  pre_shared_key_client_ = "foobar";
+  pre_shared_key_server_ = "foobar";
+  ASSERT_TRUE(Initialize());
+
+  ASSERT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
+  EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
+}
+
+// TODO: reenable once we have a way to make this run faster.
+TEST_P(EndToEndTest, QUIC_TEST_DISABLED_IN_CHROME(PreSharedKeyMismatch)) {
+  client_config_.set_max_time_before_crypto_handshake(
+      QuicTime::Delta::FromSeconds(1));
+  client_config_.set_max_idle_time_before_crypto_handshake(
+      QuicTime::Delta::FromSeconds(1));
+  pre_shared_key_client_ = "foo";
+  pre_shared_key_server_ = "bar";
+  // One of two things happens when Initialize() returns:
+  // 1. Crypto handshake has completed, and it is unsuccessful. Initialize()
+  //    returns false.
+  // 2. Crypto handshake has not completed, Initialize() returns true. The call
+  //    to WaitForCryptoHandshakeConfirmed() will wait for the handshake and
+  //    return whether it is successful.
+  ASSERT_FALSE(Initialize() &&
+               client_->client()->WaitForCryptoHandshakeConfirmed());
+  EXPECT_EQ(QUIC_HANDSHAKE_TIMEOUT, client_->connection_error());
+}
+
+// TODO: reenable once we have a way to make this run faster.
+TEST_P(EndToEndTest, QUIC_TEST_DISABLED_IN_CHROME(PreSharedKeyNoClient)) {
+  client_config_.set_max_time_before_crypto_handshake(
+      QuicTime::Delta::FromSeconds(1));
+  client_config_.set_max_idle_time_before_crypto_handshake(
+      QuicTime::Delta::FromSeconds(1));
+  pre_shared_key_server_ = "foobar";
+  ASSERT_FALSE(Initialize() &&
+               client_->client()->WaitForCryptoHandshakeConfirmed());
+  EXPECT_EQ(QUIC_HANDSHAKE_TIMEOUT, client_->connection_error());
+}
+
+// TODO: reenable once we have a way to make this run faster.
+TEST_P(EndToEndTest, QUIC_TEST_DISABLED_IN_CHROME(PreSharedKeyNoServer)) {
+  client_config_.set_max_time_before_crypto_handshake(
+      QuicTime::Delta::FromSeconds(1));
+  client_config_.set_max_idle_time_before_crypto_handshake(
+      QuicTime::Delta::FromSeconds(1));
+  pre_shared_key_client_ = "foobar";
+  ASSERT_FALSE(Initialize() &&
+               client_->client()->WaitForCryptoHandshakeConfirmed());
+  EXPECT_EQ(QUIC_HANDSHAKE_TIMEOUT, client_->connection_error());
+}
+
+TEST_P(EndToEndTest, RequestAndStreamRstInOnePacket) {
+  // Regression test for b/80234898.
+  ASSERT_TRUE(Initialize());
+
+  // INCOMPLETE_RESPONSE will cause the server to not to send the trailer
+  // (and the FIN) after the response body.
+  QuicString response_body(1305, 'a');
+  SpdyHeaderBlock response_headers;
+  response_headers[":status"] = QuicTextUtils::Uint64ToString(200);
+  response_headers["content-length"] =
+      QuicTextUtils::Uint64ToString(response_body.length());
+  memory_cache_backend_.AddSpecialResponse(
+      server_hostname_, "/test_url", std::move(response_headers), response_body,
+      QuicBackendResponse::INCOMPLETE_RESPONSE);
+
+  EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
+  client_->WaitForDelayedAcks();
+
+  QuicSession* session = client_->client()->client_session();
+  const QuicPacketCount packets_sent_before =
+      session->connection()->GetStats().packets_sent;
+
+  client_->SendRequestAndRstTogether("/test_url");
+
+  // Expect exactly one packet is sent from the block above.
+  ASSERT_EQ(packets_sent_before + 1,
+            session->connection()->GetStats().packets_sent);
+
+  // Wait for the connection to become idle.
+  client_->WaitForDelayedAcks();
+
+  // The real expectation is the test does not crash or timeout.
+  EXPECT_EQ(QUIC_NO_ERROR, client_->connection_error());
+}
+
+TEST_P(EndToEndTest, ResetStreamOnTtlExpires) {
+  ASSERT_TRUE(Initialize());
+  EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
+  if (!client_->client()->client_session()->session_decides_what_to_write()) {
+    return;
+  }
+  SetPacketLossPercentage(30);
+
+  QuicSpdyClientStream* stream = client_->GetOrCreateStream();
+  // Set a TTL which expires immediately.
+  stream->MaybeSetTtl(QuicTime::Delta::FromMicroseconds(1));
+
+  // 1 MB body.
+  QuicString body(1024 * 1024, 'a');
+  stream->WriteOrBufferBody(body, true);
+  client_->WaitForResponse();
+  EXPECT_EQ(QUIC_STREAM_TTL_EXPIRED, client_->stream_error());
+}
+
+TEST_P(EndToEndTest, SendMessages) {
+  ASSERT_TRUE(Initialize());
+  EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
+  QuicSession* client_session = client_->client()->client_session();
+  QuicConnection* client_connection = client_session->connection();
+  if (client_connection->transport_version() <= QUIC_VERSION_44) {
+    return;
+  }
+
+  SetPacketLossPercentage(30);
+  ASSERT_GT(kMaxPacketSize, client_session->GetLargestMessagePayload());
+  ASSERT_LT(0, client_session->GetLargestMessagePayload());
+
+  QuicString message_string(kMaxPacketSize, 'a');
+  QuicStringPiece message_buffer(message_string);
+  QuicRandom* random =
+      QuicConnectionPeer::GetHelper(client_connection)->GetRandomGenerator();
+  QuicMemSliceStorage storage(nullptr, 0, nullptr, 0);
+  {
+    QuicConnection::ScopedPacketFlusher flusher(
+        client_session->connection(), QuicConnection::SEND_ACK_IF_PENDING);
+    // Verify the largest message gets successfully sent.
+    EXPECT_EQ(MessageResult(MESSAGE_STATUS_SUCCESS, 1),
+              client_session->SendMessage(MakeSpan(
+                  client_session->connection()
+                      ->helper()
+                      ->GetStreamSendBufferAllocator(),
+                  QuicStringPiece(message_buffer.data(),
+                                  client_session->GetLargestMessagePayload()),
+                  &storage)));
+    // Send more messages with size (0, largest_payload] until connection is
+    // write blocked.
+    const int kTestMaxNumberOfMessages = 100;
+    for (size_t i = 2; i <= kTestMaxNumberOfMessages; ++i) {
+      size_t message_length =
+          random->RandUint64() % client_session->GetLargestMessagePayload() + 1;
+      MessageResult result = client_session->SendMessage(MakeSpan(
+          client_session->connection()
+              ->helper()
+              ->GetStreamSendBufferAllocator(),
+          QuicStringPiece(message_buffer.data(), message_length), &storage));
+      if (result.status == MESSAGE_STATUS_BLOCKED) {
+        // Connection is write blocked.
+        break;
+      }
+      EXPECT_EQ(MessageResult(MESSAGE_STATUS_SUCCESS, i), result);
+    }
+  }
+
+  client_->WaitForDelayedAcks();
+  EXPECT_EQ(
+      MESSAGE_STATUS_TOO_LARGE,
+      client_session
+          ->SendMessage(MakeSpan(
+              client_session->connection()
+                  ->helper()
+                  ->GetStreamSendBufferAllocator(),
+              QuicStringPiece(message_buffer.data(),
+                              client_session->GetLargestMessagePayload() + 1),
+              &storage))
+          .status);
+  EXPECT_EQ(QUIC_NO_ERROR, client_->connection_error());
+}
+
+class EndToEndPacketReorderingTest : public EndToEndTest {
+ public:
+  void CreateClientWithWriter() override {
+    QUIC_LOG(ERROR) << "create client with reorder_writer_";
+    reorder_writer_ = new PacketReorderingWriter();
+    client_.reset(EndToEndTest::CreateQuicClient(reorder_writer_));
+  }
+
+  void SetUp() override {
+    // Don't initialize client writer in base class.
+    server_writer_ = new PacketDroppingTestWriter();
+  }
+
+ protected:
+  PacketReorderingWriter* reorder_writer_;
+};
+
+INSTANTIATE_TEST_SUITE_P(EndToEndPacketReorderingTests,
+                         EndToEndPacketReorderingTest,
+                         testing::ValuesIn(GetTestParams(false, false)));
+
+TEST_P(EndToEndPacketReorderingTest, ReorderedConnectivityProbing) {
+  ASSERT_TRUE(Initialize());
+
+  // Finish one request to make sure handshake established.
+  EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
+
+  // Wait for the connection to become idle, to make sure the packet gets
+  // delayed is the connectivity probing packet.
+  client_->WaitForDelayedAcks();
+
+  QuicSocketAddress old_addr =
+      client_->client()->network_helper()->GetLatestClientAddress();
+
+  // Migrate socket to the new IP address.
+  QuicIpAddress new_host = TestLoopback(2);
+  EXPECT_NE(old_addr.host(), new_host);
+  ASSERT_TRUE(client_->client()->MigrateSocket(new_host));
+
+  // Write a connectivity probing after the next /foo request.
+  reorder_writer_->SetDelay(1);
+  client_->SendConnectivityProbing();
+
+  ASSERT_TRUE(client_->MigrateSocketWithSpecifiedPort(old_addr.host(),
+                                                      old_addr.port()));
+
+  // The (delayed) connectivity probing will be sent after this request.
+  EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
+
+  // Send yet another request after the connectivity probing, when this request
+  // returns, the probing is guaranteed to have been received by the server, and
+  // the server's response to probing is guaranteed to have been received by the
+  // client.
+  EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
+
+  server_thread_->Pause();
+  QuicConnection* server_connection = GetServerConnection();
+  EXPECT_EQ(1u,
+            server_connection->GetStats().num_connectivity_probing_received);
+  server_thread_->Resume();
+
+  QuicConnection* client_connection =
+      client_->client()->client_session()->connection();
+  EXPECT_EQ(1u,
+            client_connection->GetStats().num_connectivity_probing_received);
+}
+
+TEST_P(EndToEndPacketReorderingTest, Buffer0RttRequest) {
+  ASSERT_TRUE(Initialize());
+  // Finish one request to make sure handshake established.
+  client_->SendSynchronousRequest("/foo");
+  // Disconnect for next 0-rtt request.
+  client_->Disconnect();
+
+  // Client get valid STK now. Do a 0-rtt request.
+  // Buffer a CHLO till another packets sent out.
+  reorder_writer_->SetDelay(1);
+  // Only send out a CHLO.
+  client_->client()->Initialize();
+  client_->client()->StartConnect();
+  EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
+  ASSERT_TRUE(client_->client()->connected());
+
+  // Send a request before handshake finishes.
+  SpdyHeaderBlock headers;
+  headers[":method"] = "POST";
+  headers[":path"] = "/bar";
+  headers[":scheme"] = "https";
+  headers[":authority"] = server_hostname_;
+
+  client_->SendMessage(headers, "");
+  client_->WaitForResponse();
+  EXPECT_EQ(kBarResponseBody, client_->response_body());
+  QuicConnectionStats client_stats =
+      client_->client()->client_session()->connection()->GetStats();
+  EXPECT_EQ(0u, client_stats.packets_lost);
+  if (ServerSendsVersionNegotiation()) {
+    EXPECT_EQ(2, client_->client()->GetNumSentClientHellos());
+  } else {
+    EXPECT_EQ(1, client_->client()->GetNumSentClientHellos());
+  }
+}
+
+// Test that STOP_SENDING makes it to the other side. Set up a client & server,
+// create a stream (do not close it), and then send a STOP_SENDING from one
+// side. The other side should get a call to QuicStream::OnStopSending.
+// (aside, test cribbed from RequestAndStreamRstInOnePacket)
+TEST_P(EndToEndTest, SimpleStopSendingTest) {
+  const uint16_t kStopSendingTestCode = 123;
+  ASSERT_TRUE(Initialize());
+  if (negotiated_version_.transport_version != QUIC_VERSION_99) {
+    return;
+  }
+  QuicSession* client_session = client_->client()->client_session();
+  ASSERT_NE(nullptr, client_session);
+  QuicConnection* client_connection = client_session->connection();
+  ASSERT_NE(nullptr, client_connection);
+
+  // STOP_SENDING will cause the server to not to send the trailer
+  // (and the FIN) after the response body. Instead, it sends a STOP_SENDING
+  // frame for the stream.
+  QuicString response_body(1305, 'a');
+  SpdyHeaderBlock response_headers;
+  response_headers[":status"] = QuicTextUtils::Uint64ToString(200);
+  response_headers["content-length"] =
+      QuicTextUtils::Uint64ToString(response_body.length());
+  memory_cache_backend_.AddStopSendingResponse(
+      server_hostname_, "/test_url", std::move(response_headers), response_body,
+      kStopSendingTestCode);
+
+  EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
+  client_->WaitForDelayedAcks();
+
+  QuicSession* session = client_->client()->client_session();
+  const QuicPacketCount packets_sent_before =
+      session->connection()->GetStats().packets_sent;
+
+  QuicStreamId stream_id = session->next_outgoing_bidirectional_stream_id();
+  client_->SendRequest("/test_url");
+
+  // Expect exactly one packet is sent from the block above.
+  ASSERT_EQ(packets_sent_before + 1,
+            session->connection()->GetStats().packets_sent);
+
+  // Wait for the connection to become idle.
+  client_->WaitForDelayedAcks();
+
+  // The real expectation is the test does not crash or timeout.
+  EXPECT_EQ(QUIC_NO_ERROR, client_->connection_error());
+  // And that the stop-sending code is received.
+  QuicSimpleClientStream* client_stream =
+      static_cast<QuicSimpleClientStream*>(client_->latest_created_stream());
+  ASSERT_NE(nullptr, client_stream);
+  // Make sure we have the correct stream
+  EXPECT_EQ(stream_id, client_stream->id());
+  EXPECT_EQ(kStopSendingTestCode, client_stream->last_stop_sending_code());
+}
+
+TEST_P(EndToEndTest, SimpleStopSendingRstStreamTest) {
+  ASSERT_TRUE(Initialize());
+
+  // Send a request without a fin, to keep the stream open
+  SpdyHeaderBlock headers;
+  headers[":method"] = "POST";
+  headers[":path"] = "/foo";
+  headers[":scheme"] = "https";
+  headers[":authority"] = server_hostname_;
+  client_->SendMessage(headers, "", /*fin=*/false);
+  // Stream should be open
+  ASSERT_NE(nullptr, client_->latest_created_stream());
+  EXPECT_FALSE(
+      QuicStreamPeer::write_side_closed(client_->latest_created_stream()));
+  EXPECT_FALSE(
+      QuicStreamPeer::read_side_closed(client_->latest_created_stream()));
+
+  // Send a RST_STREAM+STOP_SENDING on the stream
+  // Code is not important.
+  client_->latest_created_stream()->Reset(QUIC_BAD_APPLICATION_PAYLOAD);
+  client_->WaitForResponse();
+
+  // Stream should be gone.
+  ASSERT_EQ(nullptr, client_->latest_created_stream());
+}
+
+class BadShloPacketWriter : public QuicPacketWriterWrapper {
+ public:
+  BadShloPacketWriter() : error_returned_(false) {}
+  ~BadShloPacketWriter() override {}
+
+  WriteResult WritePacket(const char* buffer,
+                          size_t buf_len,
+                          const QuicIpAddress& self_address,
+                          const QuicSocketAddress& peer_address,
+                          quic::PerPacketOptions* options) override {
+    const WriteResult result = QuicPacketWriterWrapper::WritePacket(
+        buffer, buf_len, self_address, peer_address, options);
+    const uint8_t type_byte = buffer[0];
+    if (!error_returned_ && (type_byte & FLAGS_LONG_HEADER) &&
+        (((type_byte & 0x30) >> 4) == 1 || (type_byte & 0x7F) == 0x7C)) {
+      QUIC_DVLOG(1) << "Return write error for ZERO_RTT_PACKET";
+      error_returned_ = true;
+      return WriteResult(WRITE_STATUS_ERROR, QUIC_EMSGSIZE);
+    }
+    return result;
+  }
+
+ private:
+  bool error_returned_;
+};
+
+TEST_P(EndToEndTest, ZeroRttProtectedConnectionClose) {
+  // This test ensures ZERO_RTT_PROTECTED connection close could close a client
+  // which has switched to forward secure.
+  connect_to_server_on_initialize_ =
+      negotiated_version_.transport_version <= QUIC_VERSION_43;
+  ASSERT_TRUE(Initialize());
+  if (negotiated_version_.transport_version <= QUIC_VERSION_43) {
+    // Only runs for IETF QUIC header.
+    return;
+  }
+  server_thread_->Pause();
+  QuicDispatcher* dispatcher =
+      QuicServerPeer::GetDispatcher(server_thread_->server());
+  ASSERT_EQ(0u, dispatcher->session_map().size());
+  // Note: this writer will only used by the server connection, not the time
+  // wait list.
+  QuicDispatcherPeer::UseWriter(
+      dispatcher,
+      // This causes the first server sent ZERO_RTT_PROTECTED packet (i.e.,
+      // SHLO) to be sent, but WRITE_ERROR is returned. Such that a
+      // ZERO_RTT_PROTECTED connection close would be sent to a client with
+      // encryption level FORWARD_SECURE.
+      new BadShloPacketWriter());
+  server_thread_->Resume();
+
+  client_.reset(CreateQuicClient(client_writer_));
+  EXPECT_EQ("", client_->SendSynchronousRequest("/foo"));
+  // Verify ZERO_RTT_PROTECTED connection close is successfully processed by
+  // client which switches to FORWARD_SECURE.
+  EXPECT_EQ(QUIC_PACKET_WRITE_ERROR, client_->connection_error());
+}
+
+class BadShloPacketWriter2 : public QuicPacketWriterWrapper {
+ public:
+  BadShloPacketWriter2() : error_returned_(false) {}
+  ~BadShloPacketWriter2() override {}
+
+  WriteResult WritePacket(const char* buffer,
+                          size_t buf_len,
+                          const QuicIpAddress& self_address,
+                          const QuicSocketAddress& peer_address,
+                          quic::PerPacketOptions* options) override {
+    const uint8_t type_byte = buffer[0];
+    if ((type_byte & FLAGS_LONG_HEADER) &&
+        (((type_byte & 0x30) >> 4) == 1 || (type_byte & 0x7F) == 0x7C)) {
+      QUIC_DVLOG(1) << "Dropping ZERO_RTT_PACKET packet";
+      return WriteResult(WRITE_STATUS_OK, buf_len);
+    }
+    if (!error_returned_ && !(type_byte & FLAGS_LONG_HEADER)) {
+      QUIC_DVLOG(1) << "Return write error for short header packet";
+      error_returned_ = true;
+      return WriteResult(WRITE_STATUS_ERROR, QUIC_EMSGSIZE);
+    }
+    return QuicPacketWriterWrapper::WritePacket(buffer, buf_len, self_address,
+                                                peer_address, options);
+  }
+
+ private:
+  bool error_returned_;
+};
+
+TEST_P(EndToEndTest, ForwardSecureConnectionClose) {
+  // This test ensures ZERO_RTT_PROTECTED connection close is sent to a client
+  // which has ZERO_RTT_PROTECTED encryption level.
+  SetQuicReloadableFlag(quic_fix_termination_packets, true);
+  connect_to_server_on_initialize_ =
+      negotiated_version_.transport_version <= QUIC_VERSION_43;
+  ASSERT_TRUE(Initialize());
+  if (negotiated_version_.transport_version <= QUIC_VERSION_43) {
+    // Only runs for IETF QUIC header.
+    return;
+  }
+  server_thread_->Pause();
+  QuicDispatcher* dispatcher =
+      QuicServerPeer::GetDispatcher(server_thread_->server());
+  ASSERT_EQ(0u, dispatcher->session_map().size());
+  // Note: this writer will only used by the server connection, not the time
+  // wait list.
+  QuicDispatcherPeer::UseWriter(
+      dispatcher,
+      // This causes the all server sent ZERO_RTT_PROTECTED packets to be
+      // dropped, and first short header packet causes write error.
+      new BadShloPacketWriter2());
+  server_thread_->Resume();
+  client_.reset(CreateQuicClient(client_writer_));
+  EXPECT_EQ("", client_->SendSynchronousRequest("/foo"));
+  // Verify ZERO_RTT_PROTECTED connection close is successfully processed by
+  // client.
+  EXPECT_EQ(QUIC_PACKET_WRITE_ERROR, client_->connection_error());
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quic/core/http/http_decoder.cc b/quic/core/http/http_decoder.cc
new file mode 100644
index 0000000..e697821
--- /dev/null
+++ b/quic/core/http/http_decoder.cc
@@ -0,0 +1,411 @@
+// Copyright (c) 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/third_party/quiche/src/quic/core/http/http_decoder.h"
+#include "net/third_party/quiche/src/quic/core/quic_data_reader.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_bug_tracker.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_fallthrough.h"
+
+namespace quic {
+
+namespace {
+
+// Create a mask that sets the last |num_bits| to 1 and the rest to 0.
+inline uint8_t GetMaskFromNumBits(uint8_t num_bits) {
+  return (1u << num_bits) - 1;
+}
+
+// Extract |num_bits| from |flags| offset by |offset|.
+uint8_t ExtractBits(uint8_t flags, uint8_t num_bits, uint8_t offset) {
+  return (flags >> offset) & GetMaskFromNumBits(num_bits);
+}
+
+// Length of the type field of HTTP/3 frames.
+static const QuicByteCount kFrameTypeLength = 1;
+
+}  // namespace
+
+HttpDecoder::HttpDecoder()
+    : visitor_(nullptr),
+      state_(STATE_READING_FRAME_LENGTH),
+      current_frame_type_(0),
+      current_length_field_size_(0),
+      remaining_length_field_length_(0),
+      current_frame_length_(0),
+      remaining_frame_length_(0),
+      error_(QUIC_NO_ERROR),
+      error_detail_(""),
+      has_payload_(false) {}
+
+HttpDecoder::~HttpDecoder() {}
+
+QuicByteCount HttpDecoder::ProcessInput(const char* data, QuicByteCount len) {
+  has_payload_ = false;
+  QuicDataReader reader(data, len);
+  while (error_ == QUIC_NO_ERROR && reader.BytesRemaining() != 0) {
+    switch (state_) {
+      case STATE_READING_FRAME_LENGTH:
+        ReadFrameLength(&reader);
+        break;
+      case STATE_READING_FRAME_TYPE:
+        ReadFrameType(&reader);
+        break;
+      case STATE_READING_FRAME_PAYLOAD:
+        ReadFramePayload(&reader);
+        break;
+      case STATE_ERROR:
+        break;
+      default:
+        QUIC_BUG << "Invalid state: " << state_;
+    }
+  }
+
+  if (error_ != QUIC_NO_ERROR) {
+    return 0;
+  }
+
+  return len - reader.BytesRemaining();
+}
+
+void HttpDecoder::ReadFrameLength(QuicDataReader* reader) {
+  DCHECK_NE(0u, reader->BytesRemaining());
+  BufferFrameLength(reader);
+  if (remaining_length_field_length_ != 0) {
+    return;
+  }
+  QuicDataReader length_reader(length_buffer_.data(),
+                               current_length_field_size_);
+  if (!length_reader.ReadVarInt62(&current_frame_length_)) {
+    RaiseError(QUIC_INTERNAL_ERROR, "Unable to read frame length");
+    visitor_->OnError(this);
+    return;
+  }
+
+  state_ = STATE_READING_FRAME_TYPE;
+  remaining_frame_length_ = current_frame_length_;
+}
+
+void HttpDecoder::ReadFrameType(QuicDataReader* reader) {
+  DCHECK_NE(0u, reader->BytesRemaining());
+  if (!reader->ReadUInt8(&current_frame_type_)) {
+    RaiseError(QUIC_INTERNAL_ERROR, "Unable to read frame type");
+    return;
+  }
+
+  state_ = STATE_READING_FRAME_PAYLOAD;
+}
+
+void HttpDecoder::ReadFramePayload(QuicDataReader* reader) {
+  DCHECK_NE(0u, reader->BytesRemaining());
+  switch (current_frame_type_) {
+    case 0x0: {  // DATA
+      if (current_frame_length_ == remaining_frame_length_) {
+        visitor_->OnDataFrameStart(
+            Http3FrameLengths(current_length_field_size_ + kFrameTypeLength,
+                              current_frame_length_));
+      }
+      QuicByteCount bytes_to_read = std::min<QuicByteCount>(
+          remaining_frame_length_, reader->BytesRemaining());
+      QuicStringPiece payload;
+      if (!reader->ReadStringPiece(&payload, bytes_to_read)) {
+        RaiseError(QUIC_INTERNAL_ERROR, "Unable to read data");
+        return;
+      }
+      has_payload_ = true;
+      visitor_->OnDataFramePayload(payload);
+      remaining_frame_length_ -= payload.length();
+      if (remaining_frame_length_ == 0) {
+        state_ = STATE_READING_FRAME_LENGTH;
+        current_length_field_size_ = 0;
+        visitor_->OnDataFrameEnd();
+      }
+      return;
+    }
+    case 0x1: {  // HEADERS
+      if (current_frame_length_ == remaining_frame_length_) {
+        visitor_->OnHeadersFrameStart();
+      }
+      QuicByteCount bytes_to_read = std::min<QuicByteCount>(
+          remaining_frame_length_, reader->BytesRemaining());
+      QuicStringPiece payload;
+      if (!reader->ReadStringPiece(&payload, bytes_to_read)) {
+        RaiseError(QUIC_INTERNAL_ERROR, "Unable to read data");
+        return;
+      }
+      visitor_->OnHeadersFramePayload(payload);
+      remaining_frame_length_ -= payload.length();
+      if (remaining_frame_length_ == 0) {
+        state_ = STATE_READING_FRAME_LENGTH;
+        current_length_field_size_ = 0;
+        visitor_->OnHeadersFrameEnd(current_frame_length_);
+      }
+      return;
+    }
+    case 0x2: {  // PRIORITY
+      // TODO(rch): avoid buffering if the entire frame is present, and
+      // instead parse directly out of |reader|.
+      BufferFramePayload(reader);
+      if (remaining_frame_length_ == 0) {
+        PriorityFrame frame;
+        QuicDataReader reader(buffer_.data(), current_frame_length_);
+        if (!ParsePriorityFrame(&reader, &frame)) {
+          return;
+        }
+        visitor_->OnPriorityFrame(frame);
+        state_ = STATE_READING_FRAME_LENGTH;
+        current_length_field_size_ = 0;
+      }
+      return;
+    }
+    case 0x3: {  // CANCEL_PUSH
+      // TODO(rch): Handle partial delivery.
+      BufferFramePayload(reader);
+      if (remaining_frame_length_ == 0) {
+        CancelPushFrame frame;
+        QuicDataReader reader(buffer_.data(), current_frame_length_);
+        if (!reader.ReadVarInt62(&frame.push_id)) {
+          RaiseError(QUIC_INTERNAL_ERROR, "Unable to read push_id");
+          return;
+        }
+        visitor_->OnCancelPushFrame(frame);
+        state_ = STATE_READING_FRAME_LENGTH;
+        current_length_field_size_ = 0;
+      }
+      return;
+    }
+    case 0x4: {  // SETTINGS
+      // TODO(rch): Handle overly large SETTINGS frames. Either:
+      // 1. Impose a limit on SETTINGS frame size, and close the connection if
+      //    exceeded
+      // 2. Implement a streaming parsing mode.
+      BufferFramePayload(reader);
+      if (remaining_frame_length_ == 0) {
+        SettingsFrame frame;
+        QuicDataReader reader(buffer_.data(), current_frame_length_);
+        if (!ParseSettingsFrame(&reader, &frame)) {
+          return;
+        }
+        visitor_->OnSettingsFrame(frame);
+        state_ = STATE_READING_FRAME_LENGTH;
+        current_length_field_size_ = 0;
+      }
+      return;
+    }
+    case 0x5: {  // PUSH_PROMISE
+      if (current_frame_length_ == remaining_frame_length_) {
+        QuicByteCount bytes_remaining = reader->BytesRemaining();
+        PushId push_id;
+        // TODO(rch): Handle partial delivery of this field.
+        if (!reader->ReadVarInt62(&push_id)) {
+          RaiseError(QUIC_INTERNAL_ERROR, "Unable to read push_id");
+          return;
+        }
+        remaining_frame_length_ -= bytes_remaining - reader->BytesRemaining();
+        visitor_->OnPushPromiseFrameStart(push_id);
+      }
+      QuicByteCount bytes_to_read = std::min<QuicByteCount>(
+          remaining_frame_length_, reader->BytesRemaining());
+      if (bytes_to_read == 0) {
+        return;
+      }
+      QuicStringPiece payload;
+      if (!reader->ReadStringPiece(&payload, bytes_to_read)) {
+        RaiseError(QUIC_INTERNAL_ERROR, "Unable to read data");
+        return;
+      }
+      visitor_->OnPushPromiseFramePayload(payload);
+      remaining_frame_length_ -= payload.length();
+      if (remaining_frame_length_ == 0) {
+        state_ = STATE_READING_FRAME_LENGTH;
+        current_length_field_size_ = 0;
+        visitor_->OnPushPromiseFrameEnd();
+      }
+      return;
+    }
+    case 0x7: {  // GOAWAY
+      BufferFramePayload(reader);
+      if (remaining_frame_length_ == 0) {
+        GoAwayFrame frame;
+        QuicDataReader reader(buffer_.data(), current_frame_length_);
+        uint64_t stream_id;
+        if (!reader.ReadVarInt62(&stream_id)) {
+          RaiseError(QUIC_INTERNAL_ERROR, "Unable to read GOAWAY stream_id");
+          return;
+        }
+        frame.stream_id = stream_id;
+        visitor_->OnGoAwayFrame(frame);
+        state_ = STATE_READING_FRAME_LENGTH;
+        current_length_field_size_ = 0;
+      }
+      return;
+    }
+
+    case 0xD: {  // MAX_PUSH_ID
+      // TODO(rch): Handle partial delivery.
+      BufferFramePayload(reader);
+      if (remaining_frame_length_ == 0) {
+        QuicDataReader reader(buffer_.data(), current_frame_length_);
+        MaxPushIdFrame frame;
+        if (!reader.ReadVarInt62(&frame.push_id)) {
+          RaiseError(QUIC_INTERNAL_ERROR, "Unable to read push_id");
+          return;
+        }
+        visitor_->OnMaxPushIdFrame(frame);
+        state_ = STATE_READING_FRAME_LENGTH;
+        current_length_field_size_ = 0;
+      }
+      return;
+    }
+
+    case 0xE: {  // DUPLICATE_PUSH
+      BufferFramePayload(reader);
+      if (remaining_frame_length_ != 0) {
+        return;
+      }
+      QuicDataReader reader(buffer_.data(), current_frame_length_);
+      DuplicatePushFrame frame;
+      if (!reader.ReadVarInt62(&frame.push_id)) {
+        RaiseError(QUIC_INTERNAL_ERROR, "Unable to read push_id");
+        return;
+      }
+      visitor_->OnDuplicatePushFrame(frame);
+      state_ = STATE_READING_FRAME_LENGTH;
+      current_length_field_size_ = 0;
+      return;
+    }
+    // Reserved frame types.
+    // TODO(rch): Since these are actually the same behavior as the
+    // default, we probably don't need to special case them here?
+    case 0xB:
+      QUIC_FALLTHROUGH_INTENDED;
+    case 0xB + 0x1F:
+      QUIC_FALLTHROUGH_INTENDED;
+    case 0xB + 0x1F * 2:
+      QUIC_FALLTHROUGH_INTENDED;
+    case 0xB + 0x1F * 3:
+      QUIC_FALLTHROUGH_INTENDED;
+    case 0xB + 0x1F * 4:
+      QUIC_FALLTHROUGH_INTENDED;
+    case 0xB + 0x1F * 5:
+      QUIC_FALLTHROUGH_INTENDED;
+    case 0xB + 0x1F * 6:
+      QUIC_FALLTHROUGH_INTENDED;
+    case 0xB + 0x1F * 7:
+      QUIC_FALLTHROUGH_INTENDED;
+    default:
+      DiscardFramePayload(reader);
+  }
+}
+
+void HttpDecoder::DiscardFramePayload(QuicDataReader* reader) {
+  QuicByteCount bytes_to_read = std::min<QuicByteCount>(
+      remaining_frame_length_, reader->BytesRemaining());
+  QuicStringPiece payload;
+  if (!reader->ReadStringPiece(&payload, bytes_to_read)) {
+    RaiseError(QUIC_INTERNAL_ERROR, "Unable to read frame payload");
+    return;
+  }
+  remaining_frame_length_ -= payload.length();
+  if (remaining_frame_length_ == 0) {
+    state_ = STATE_READING_FRAME_LENGTH;
+    current_length_field_size_ = 0;
+  }
+}
+
+void HttpDecoder::BufferFramePayload(QuicDataReader* reader) {
+  if (current_frame_length_ == remaining_frame_length_) {
+    buffer_.erase(buffer_.size());
+    buffer_.reserve(current_frame_length_);
+  }
+  QuicByteCount bytes_to_read = std::min<QuicByteCount>(
+      remaining_frame_length_, reader->BytesRemaining());
+  if (!reader->ReadBytes(
+          &(buffer_[0]) + current_frame_length_ - remaining_frame_length_,
+          bytes_to_read)) {
+    RaiseError(QUIC_INTERNAL_ERROR, "Unable to read frame payload");
+    return;
+  }
+  remaining_frame_length_ -= bytes_to_read;
+}
+
+void HttpDecoder::BufferFrameLength(QuicDataReader* reader) {
+  if (current_length_field_size_ == 0) {
+    current_length_field_size_ = reader->PeekVarInt62Length();
+    if (current_length_field_size_ == 0) {
+      RaiseError(QUIC_INTERNAL_ERROR, "Unable to read frame length");
+      visitor_->OnError(this);
+      return;
+    }
+    remaining_length_field_length_ = current_length_field_size_;
+  }
+  if (current_length_field_size_ == remaining_length_field_length_) {
+    length_buffer_.erase(length_buffer_.size());
+    length_buffer_.reserve(current_length_field_size_);
+  }
+  QuicByteCount bytes_to_read = std::min<QuicByteCount>(
+      remaining_length_field_length_, reader->BytesRemaining());
+  if (!reader->ReadBytes(&(length_buffer_[0]) + current_length_field_size_ -
+                             remaining_length_field_length_,
+                         bytes_to_read)) {
+    RaiseError(QUIC_INTERNAL_ERROR, "Unable to read frame length");
+    visitor_->OnError(this);
+    return;
+  }
+  remaining_length_field_length_ -= bytes_to_read;
+}
+
+void HttpDecoder::RaiseError(QuicErrorCode error, QuicString error_detail) {
+  state_ = STATE_ERROR;
+  error_ = error;
+  error_detail_ = std::move(error_detail);
+}
+
+bool HttpDecoder::ParsePriorityFrame(QuicDataReader* reader,
+                                     PriorityFrame* frame) {
+  uint8_t flags;
+  if (!reader->ReadUInt8(&flags)) {
+    RaiseError(QUIC_INTERNAL_ERROR, "Unable to read priority frame flags");
+    return false;
+  }
+
+  frame->prioritized_type =
+      static_cast<PriorityElementType>(ExtractBits(flags, 2, 6));
+  frame->dependency_type =
+      static_cast<PriorityElementType>(ExtractBits(flags, 2, 4));
+  frame->exclusive = flags % 2 == 1;
+  if (!reader->ReadVarInt62(&frame->prioritized_element_id)) {
+    RaiseError(QUIC_INTERNAL_ERROR, "Unable to read prioritized_element_id");
+    return false;
+  }
+  if (!reader->ReadVarInt62(&frame->element_dependency_id)) {
+    RaiseError(QUIC_INTERNAL_ERROR, "Unable to read element_dependency_id");
+    return false;
+  }
+  if (!reader->ReadUInt8(&frame->weight)) {
+    RaiseError(QUIC_INTERNAL_ERROR, "Unable to read priority frame weight");
+    return false;
+  }
+  return true;
+}
+
+bool HttpDecoder::ParseSettingsFrame(QuicDataReader* reader,
+                                     SettingsFrame* frame) {
+  while (!reader->IsDoneReading()) {
+    uint16_t id;
+    if (!reader->ReadUInt16(&id)) {
+      RaiseError(QUIC_INTERNAL_ERROR,
+                 "Unable to read settings frame identifier");
+      return false;
+    }
+    uint64_t content;
+    if (!reader->ReadVarInt62(&content)) {
+      RaiseError(QUIC_INTERNAL_ERROR, "Unable to read settings frame content");
+      return false;
+    }
+    frame->values[id] = content;
+  }
+  return true;
+}
+
+}  // namespace quic
diff --git a/quic/core/http/http_decoder.h b/quic/core/http/http_decoder.h
new file mode 100644
index 0000000..910d189
--- /dev/null
+++ b/quic/core/http/http_decoder.h
@@ -0,0 +1,185 @@
+// Copyright (c) 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_HTTP_HTTP_DECODER_H_
+#define QUICHE_QUIC_CORE_HTTP_HTTP_DECODER_H_
+
+#include <cstddef>
+
+#include "net/third_party/quiche/src/quic/core/http/http_frames.h"
+#include "net/third_party/quiche/src/quic/core/quic_error_codes.h"
+#include "net/third_party/quiche/src/quic/core/quic_types.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_export.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_string_piece.h"
+
+namespace quic {
+
+class QuicDataReader;
+
+// Struct that stores meta data of a data frame.
+// |header_length| stores number of bytes header occupies.
+// |payload_length| stores number of bytes payload occupies.
+struct QUIC_EXPORT_PRIVATE Http3FrameLengths {
+  Http3FrameLengths(QuicByteCount header, QuicByteCount payload)
+      : header_length(header), payload_length(payload) {}
+
+  bool operator==(const Http3FrameLengths& other) const {
+    return (header_length == other.header_length) &&
+           (payload_length == other.payload_length);
+  }
+
+  QuicByteCount header_length;
+  QuicByteCount payload_length;
+};
+
+// A class for decoding the HTTP frames that are exchanged in an HTTP over QUIC
+// session.
+class QUIC_EXPORT_PRIVATE HttpDecoder {
+ public:
+  class QUIC_EXPORT_PRIVATE Visitor {
+   public:
+    virtual ~Visitor() {}
+
+    // Called if an error is detected.
+    virtual void OnError(HttpDecoder* decoder) = 0;
+
+    // Called when a PRIORITY frame has been successfully parsed.
+    virtual void OnPriorityFrame(const PriorityFrame& frame) = 0;
+
+    // Called when a CANCEL_PUSH frame has been successfully parsed.
+    virtual void OnCancelPushFrame(const CancelPushFrame& frame) = 0;
+
+    // Called when a MAX_PUSH_ID frame has been successfully parsed.
+    virtual void OnMaxPushIdFrame(const MaxPushIdFrame& frame) = 0;
+
+    // Called when a GOAWAY frame has been successfully parsed.
+    virtual void OnGoAwayFrame(const GoAwayFrame& frame) = 0;
+
+    // Called when a SETTINGS frame has been successfully parsed.
+    virtual void OnSettingsFrame(const SettingsFrame& frame) = 0;
+
+    // Called when a DUPLICATE_PUSH frame has been successfully parsed.
+    virtual void OnDuplicatePushFrame(const DuplicatePushFrame& frame) = 0;
+
+    // Called when a DATA frame has been received, |frame_lengths| will be
+    // passed to inform header length and payload length of the frame.
+    virtual void OnDataFrameStart(Http3FrameLengths frame_length) = 0;
+    // Called when the payload of a DATA frame has read. May be called
+    // multiple times for a single frame.
+    virtual void OnDataFramePayload(QuicStringPiece payload) = 0;
+    // Called when a DATA frame has been completely processed.
+    virtual void OnDataFrameEnd() = 0;
+
+    // Called when a HEADERS frame has been recevied.
+    virtual void OnHeadersFrameStart() = 0;
+    // Called when the payload of a HEADERS frame has read. May be called
+    // multiple times for a single frame.
+    virtual void OnHeadersFramePayload(QuicStringPiece payload) = 0;
+    // Called when a HEADERS frame has been completely processed.
+    // |frame_len| is the length of the HEADERS frame payload.
+    virtual void OnHeadersFrameEnd(QuicByteCount frame_len) = 0;
+
+    // Called when a PUSH_PROMISE frame has been recevied for |push_id|.
+    virtual void OnPushPromiseFrameStart(PushId push_id) = 0;
+    // Called when the payload of a PUSH_PROMISE frame has read. May be called
+    // multiple times for a single frame.
+    virtual void OnPushPromiseFramePayload(QuicStringPiece payload) = 0;
+    // Called when a PUSH_PROMISE frame has been completely processed.
+    virtual void OnPushPromiseFrameEnd() = 0;
+
+    // TODO(rch): Consider adding methods like:
+    // OnUnknownFrame{Start,Payload,End}()
+    // to allow callers to handle unknown frames.
+  };
+
+  HttpDecoder();
+
+  ~HttpDecoder();
+
+  // Set callbacks to be called from the decoder.  A visitor must be set, or
+  // else the decoder will crash.  It is acceptable for the visitor to do
+  // nothing.  If this is called multiple times, only the last visitor
+  // will be used.  |visitor| will be owned by the caller.
+  void set_visitor(Visitor* visitor) { visitor_ = visitor; }
+
+  // Processes the input and invokes the visitor for any frames.
+  // Returns the number of bytes consumed, or 0 if there was an error, in which
+  // case error() should be consulted.
+  QuicByteCount ProcessInput(const char* data, QuicByteCount len);
+
+  bool has_payload() { return has_payload_; }
+
+  QuicErrorCode error() const { return error_; }
+  const QuicString& error_detail() const { return error_detail_; }
+
+ private:
+  // Represents the current state of the parsing state machine.
+  enum HttpDecoderState {
+    STATE_READING_FRAME_LENGTH,
+    STATE_READING_FRAME_TYPE,
+    STATE_READING_FRAME_PAYLOAD,
+    STATE_ERROR
+  };
+
+  // Reads the length of a frame from |reader|. Sets error_ and error_detail_
+  // if there are any errors.
+  void ReadFrameLength(QuicDataReader* reader);
+
+  // Reads the type of a frame from |reader|. Sets error_ and error_detail_
+  // if there are any errors.
+  void ReadFrameType(QuicDataReader* reader);
+
+  // Reads the payload of the current frame from |reader| and processes it,
+  // possibly buffering the data or invoking the visitor.
+  void ReadFramePayload(QuicDataReader* reader);
+
+  // Discards any remaining frame payload from |reader|.
+  void DiscardFramePayload(QuicDataReader* reader);
+
+  // Buffers any remaining frame payload from |reader| into |buffer_|.
+  void BufferFramePayload(QuicDataReader* reader);
+
+  // Buffers any remaining frame length field from |reader| into
+  // |length_buffer_|
+  void BufferFrameLength(QuicDataReader* reader);
+
+  // Sets |error_| and |error_detail_| accordingly.
+  void RaiseError(QuicErrorCode error, QuicString error_detail);
+
+  // Parses the payload of a PRIORITY frame from |reader| into |frame|.
+  bool ParsePriorityFrame(QuicDataReader* reader, PriorityFrame* frame);
+
+  // Parses the payload of a SETTINGS frame from |reader| into |frame|.
+  bool ParseSettingsFrame(QuicDataReader* reader, SettingsFrame* frame);
+
+  // Visitor to invoke when messages are parsed.
+  Visitor* visitor_;  // Unowned.
+  // Current state of the parsing.
+  HttpDecoderState state_;
+  // Type of the frame currently being parsed.
+  uint8_t current_frame_type_;
+  // Size of the frame's length field.
+  QuicByteCount current_length_field_size_;
+  // Remaining length that's needed for the frame's length field.
+  QuicByteCount remaining_length_field_length_;
+  // Length of the payload of the frame currently being parsed.
+  QuicByteCount current_frame_length_;
+  // Remaining payload bytes to be parsed.
+  QuicByteCount remaining_frame_length_;
+  // Last error.
+  QuicErrorCode error_;
+  // The issue which caused |error_|
+  QuicString error_detail_;
+  // True if the call to ProcessInput() generates any payload. Flushed every
+  // time ProcessInput() is called.
+  bool has_payload_;
+  // Remaining unparsed data.
+  QuicString buffer_;
+  // Remaining unparsed length field data.
+  QuicString length_buffer_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_HTTP_HTTP_DECODER_H_
diff --git a/quic/core/http/http_decoder_test.cc b/quic/core/http/http_decoder_test.cc
new file mode 100644
index 0000000..c6d7d9f
--- /dev/null
+++ b/quic/core/http/http_decoder_test.cc
@@ -0,0 +1,409 @@
+// Copyright (c) 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/third_party/quiche/src/quic/core/http/http_decoder.h"
+#include "net/third_party/quiche/src/quic/core/http/http_encoder.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_arraysize.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_test.h"
+
+using testing::InSequence;
+
+namespace quic {
+
+class MockVisitor : public HttpDecoder::Visitor {
+ public:
+  virtual ~MockVisitor() = default;
+
+  // Called if an error is detected.
+  MOCK_METHOD1(OnError, void(HttpDecoder* decoder));
+
+  MOCK_METHOD1(OnPriorityFrame, void(const PriorityFrame& frame));
+  MOCK_METHOD1(OnCancelPushFrame, void(const CancelPushFrame& frame));
+  MOCK_METHOD1(OnMaxPushIdFrame, void(const MaxPushIdFrame& frame));
+  MOCK_METHOD1(OnGoAwayFrame, void(const GoAwayFrame& frame));
+  MOCK_METHOD1(OnSettingsFrame, void(const SettingsFrame& frame));
+  MOCK_METHOD1(OnDuplicatePushFrame, void(const DuplicatePushFrame& frame));
+
+  MOCK_METHOD1(OnDataFrameStart, void(Http3FrameLengths frame_lengths));
+  MOCK_METHOD1(OnDataFramePayload, void(QuicStringPiece payload));
+  MOCK_METHOD0(OnDataFrameEnd, void());
+
+  MOCK_METHOD0(OnHeadersFrameStart, void());
+  MOCK_METHOD1(OnHeadersFramePayload, void(QuicStringPiece payload));
+  MOCK_METHOD1(OnHeadersFrameEnd, void(QuicByteCount frame_len));
+
+  MOCK_METHOD1(OnPushPromiseFrameStart, void(PushId push_id));
+  MOCK_METHOD1(OnPushPromiseFramePayload, void(QuicStringPiece payload));
+  MOCK_METHOD0(OnPushPromiseFrameEnd, void());
+};
+
+class HttpDecoderTest : public QuicTest {
+ public:
+  HttpDecoderTest() { decoder_.set_visitor(&visitor_); }
+  HttpDecoder decoder_;
+  testing::StrictMock<MockVisitor> visitor_;
+};
+
+TEST_F(HttpDecoderTest, InitialState) {
+  EXPECT_EQ(QUIC_NO_ERROR, decoder_.error());
+  EXPECT_EQ("", decoder_.error_detail());
+}
+
+TEST_F(HttpDecoderTest, ReservedFramesNoPayload) {
+  for (int n = 0; n < 8; ++n) {
+    const uint8_t type = 0xB + 0x1F * n;
+    char input[] = {// length
+                    0x00,
+                    // type
+                    type};
+
+    EXPECT_EQ(2u, decoder_.ProcessInput(input, QUIC_ARRAYSIZE(input))) << n;
+    EXPECT_EQ(QUIC_NO_ERROR, decoder_.error());
+    ASSERT_EQ("", decoder_.error_detail());
+  }
+}
+
+TEST_F(HttpDecoderTest, ReservedFramesSmallPayload) {
+  for (int n = 0; n < 8; ++n) {
+    const uint8_t type = 0xB + 0x1F * n;
+    const uint8_t payload_size = 50;
+    char input[payload_size + 2] = {// length
+                                    payload_size,
+                                    // type
+                                    type};
+
+    EXPECT_EQ(QUIC_ARRAYSIZE(input),
+              decoder_.ProcessInput(input, QUIC_ARRAYSIZE(input)))
+        << n;
+    EXPECT_EQ(QUIC_NO_ERROR, decoder_.error());
+    ASSERT_EQ("", decoder_.error_detail());
+  }
+}
+
+TEST_F(HttpDecoderTest, ReservedFramesLargePayload) {
+  for (int n = 0; n < 8; ++n) {
+    const uint8_t type = 0xB + 0x1F * n;
+    const QuicByteCount payload_size = 256;
+    char input[payload_size + 3] = {// length
+                                    0x40 + 0x01, 0x00,
+                                    // type
+                                    type};
+
+    EXPECT_EQ(QUIC_ARRAYSIZE(input),
+              decoder_.ProcessInput(input, QUIC_ARRAYSIZE(input)))
+        << n;
+    EXPECT_EQ(QUIC_NO_ERROR, decoder_.error());
+    ASSERT_EQ("", decoder_.error_detail());
+  }
+}
+
+TEST_F(HttpDecoderTest, CancelPush) {
+  char input[] = {// length
+                  0x1,
+                  // type (CANCEL_PUSH)
+                  0x03,
+                  // Push Id
+                  0x01};
+
+  // Process the full frame.
+  EXPECT_CALL(visitor_, OnCancelPushFrame(CancelPushFrame({1})));
+  EXPECT_EQ(QUIC_ARRAYSIZE(input),
+            decoder_.ProcessInput(input, QUIC_ARRAYSIZE(input)));
+  EXPECT_EQ(QUIC_NO_ERROR, decoder_.error());
+  EXPECT_EQ("", decoder_.error_detail());
+
+  // Process the frame incremently.
+  EXPECT_CALL(visitor_, OnCancelPushFrame(CancelPushFrame({1})));
+  for (char c : input) {
+    EXPECT_EQ(1u, decoder_.ProcessInput(&c, 1));
+  }
+  EXPECT_EQ(QUIC_NO_ERROR, decoder_.error());
+  EXPECT_EQ("", decoder_.error_detail());
+}
+
+TEST_F(HttpDecoderTest, PushPromiseFrame) {
+  char input[] = {// length
+                  0x8,
+                  // type (PUSH_PROMISE)
+                  0x05,
+                  // Push Id
+                  0x01,
+                  // Header Block
+                  'H', 'e', 'a', 'd', 'e', 'r', 's'};
+
+  // Process the full frame.
+  InSequence s;
+  EXPECT_CALL(visitor_, OnPushPromiseFrameStart(1));
+  EXPECT_CALL(visitor_, OnPushPromiseFramePayload(QuicStringPiece("Headers")));
+  EXPECT_CALL(visitor_, OnPushPromiseFrameEnd());
+  EXPECT_EQ(QUIC_ARRAYSIZE(input),
+            decoder_.ProcessInput(input, QUIC_ARRAYSIZE(input)));
+  EXPECT_EQ(QUIC_NO_ERROR, decoder_.error());
+  EXPECT_EQ("", decoder_.error_detail());
+
+  // Process the frame incremently.
+  EXPECT_CALL(visitor_, OnPushPromiseFrameStart(1));
+  EXPECT_CALL(visitor_, OnPushPromiseFramePayload(QuicStringPiece("H")));
+  EXPECT_CALL(visitor_, OnPushPromiseFramePayload(QuicStringPiece("e")));
+  EXPECT_CALL(visitor_, OnPushPromiseFramePayload(QuicStringPiece("a")));
+  EXPECT_CALL(visitor_, OnPushPromiseFramePayload(QuicStringPiece("d")));
+  EXPECT_CALL(visitor_, OnPushPromiseFramePayload(QuicStringPiece("e")));
+  EXPECT_CALL(visitor_, OnPushPromiseFramePayload(QuicStringPiece("r")));
+  EXPECT_CALL(visitor_, OnPushPromiseFramePayload(QuicStringPiece("s")));
+  EXPECT_CALL(visitor_, OnPushPromiseFrameEnd());
+  for (char c : input) {
+    EXPECT_EQ(1u, decoder_.ProcessInput(&c, 1));
+  }
+  EXPECT_EQ(QUIC_NO_ERROR, decoder_.error());
+  EXPECT_EQ("", decoder_.error_detail());
+}
+
+TEST_F(HttpDecoderTest, MaxPushId) {
+  char input[] = {// length
+                  0x1,
+                  // type (MAX_PUSH_ID)
+                  0x0D,
+                  // Push Id
+                  0x01};
+
+  // Process the full frame.
+  EXPECT_CALL(visitor_, OnMaxPushIdFrame(MaxPushIdFrame({1})));
+  EXPECT_EQ(QUIC_ARRAYSIZE(input),
+            decoder_.ProcessInput(input, QUIC_ARRAYSIZE(input)));
+  EXPECT_EQ(QUIC_NO_ERROR, decoder_.error());
+  EXPECT_EQ("", decoder_.error_detail());
+
+  // Process the frame incremently.
+  EXPECT_CALL(visitor_, OnMaxPushIdFrame(MaxPushIdFrame({1})));
+  for (char c : input) {
+    EXPECT_EQ(1u, decoder_.ProcessInput(&c, 1));
+  }
+  EXPECT_EQ(QUIC_NO_ERROR, decoder_.error());
+  EXPECT_EQ("", decoder_.error_detail());
+}
+
+TEST_F(HttpDecoderTest, DuplicatePush) {
+  char input[] = {// length
+                  0x1,
+                  // type (DUPLICATE_PUSH)
+                  0x0E,
+                  // Push Id
+                  0x01};
+  // Process the full frame.
+  EXPECT_CALL(visitor_, OnDuplicatePushFrame(DuplicatePushFrame({1})));
+  EXPECT_EQ(QUIC_ARRAYSIZE(input),
+            decoder_.ProcessInput(input, QUIC_ARRAYSIZE(input)));
+  EXPECT_EQ(QUIC_NO_ERROR, decoder_.error());
+  EXPECT_EQ("", decoder_.error_detail());
+
+  // Process the frame incremently.
+  EXPECT_CALL(visitor_, OnDuplicatePushFrame(DuplicatePushFrame({1})));
+  for (char c : input) {
+    EXPECT_EQ(1u, decoder_.ProcessInput(&c, 1));
+  }
+  EXPECT_EQ(QUIC_NO_ERROR, decoder_.error());
+  EXPECT_EQ("", decoder_.error_detail());
+}
+
+TEST_F(HttpDecoderTest, PriorityFrame) {
+  char input[] = {// length
+                  0x4,
+                  // type (PRIORITY)
+                  0x2,
+                  // request stream, request stream, exclusive
+                  0x01,
+                  // prioritized_element_id
+                  0x03,
+                  // element_dependency_id
+                  0x04,
+                  // weight
+                  0xFF};
+
+  PriorityFrame frame;
+  frame.prioritized_type = REQUEST_STREAM;
+  frame.dependency_type = REQUEST_STREAM;
+  frame.exclusive = true;
+  frame.prioritized_element_id = 0x03;
+  frame.element_dependency_id = 0x04;
+  frame.weight = 0xFF;
+
+  // Process the full frame.
+  EXPECT_CALL(visitor_, OnPriorityFrame(frame));
+  EXPECT_EQ(QUIC_ARRAYSIZE(input),
+            decoder_.ProcessInput(input, QUIC_ARRAYSIZE(input)));
+  EXPECT_EQ(QUIC_NO_ERROR, decoder_.error());
+  EXPECT_EQ("", decoder_.error_detail());
+
+  /*
+  // Process the frame incremently.
+  EXPECT_CALL(visitor_, OnPriorityFrame(frame));
+  for (char c : input) {
+    EXPECT_EQ(1u, decoder_.ProcessInput(&c, 1));
+  }
+  EXPECT_EQ(QUIC_NO_ERROR, decoder_.error());
+  EXPECT_EQ("", decoder_.error_detail());
+  */
+}
+
+TEST_F(HttpDecoderTest, SettingsFrame) {
+  // clang-format off
+  char input[] = {
+      // length
+      0x06,
+      // type (SETTINGS)
+      0x04,
+      // identifier (SETTINGS_NUM_PLACEHOLDERS)
+      0x00,
+      0x03,
+      // content
+      0x02,
+      // identifier (SETTINGS_MAX_HEADER_LIST_SIZE)
+      0x00,
+      0x06,
+      // content
+      0x05,
+  };
+  // clang-format on
+
+  SettingsFrame frame;
+  frame.values[3] = 2;
+  frame.values[6] = 5;
+
+  // Process the full frame.
+  EXPECT_CALL(visitor_, OnSettingsFrame(frame));
+  EXPECT_EQ(QUIC_ARRAYSIZE(input),
+            decoder_.ProcessInput(input, QUIC_ARRAYSIZE(input)));
+  EXPECT_EQ(QUIC_NO_ERROR, decoder_.error());
+  EXPECT_EQ("", decoder_.error_detail());
+
+  // Process the frame incremently.
+  EXPECT_CALL(visitor_, OnSettingsFrame(frame));
+  for (char c : input) {
+    EXPECT_EQ(1u, decoder_.ProcessInput(&c, 1));
+  }
+  EXPECT_EQ(QUIC_NO_ERROR, decoder_.error());
+  EXPECT_EQ("", decoder_.error_detail());
+}
+
+TEST_F(HttpDecoderTest, DataFrame) {
+  char input[] = {// length
+                  0x05,
+                  // type (DATA)
+                  0x00,
+                  // data
+                  'D', 'a', 't', 'a', '!'};
+
+  // Process the full frame.
+  InSequence s;
+  EXPECT_CALL(visitor_, OnDataFrameStart(Http3FrameLengths(2, 5)));
+  EXPECT_CALL(visitor_, OnDataFramePayload(QuicStringPiece("Data!")));
+  EXPECT_CALL(visitor_, OnDataFrameEnd());
+  EXPECT_EQ(QUIC_ARRAYSIZE(input),
+            decoder_.ProcessInput(input, QUIC_ARRAYSIZE(input)));
+  EXPECT_EQ(QUIC_NO_ERROR, decoder_.error());
+  EXPECT_EQ("", decoder_.error_detail());
+
+  // Process the frame incremently.
+  EXPECT_CALL(visitor_, OnDataFrameStart(Http3FrameLengths(2, 5)));
+  EXPECT_CALL(visitor_, OnDataFramePayload(QuicStringPiece("D")));
+  EXPECT_CALL(visitor_, OnDataFramePayload(QuicStringPiece("a")));
+  EXPECT_CALL(visitor_, OnDataFramePayload(QuicStringPiece("t")));
+  EXPECT_CALL(visitor_, OnDataFramePayload(QuicStringPiece("a")));
+  EXPECT_CALL(visitor_, OnDataFramePayload(QuicStringPiece("!")));
+  EXPECT_CALL(visitor_, OnDataFrameEnd());
+  for (char c : input) {
+    EXPECT_EQ(1u, decoder_.ProcessInput(&c, 1));
+  }
+  EXPECT_EQ(QUIC_NO_ERROR, decoder_.error());
+  EXPECT_EQ("", decoder_.error_detail());
+}
+
+TEST_F(HttpDecoderTest, FrameHeaderPartialDelivery) {
+  // A large input that will occupy more than 1 byte in the length field.
+  QuicString input(2048, 'x');
+  HttpEncoder encoder;
+  std::unique_ptr<char[]> buffer;
+  QuicByteCount header_length =
+      encoder.SerializeDataFrameHeader(input.length(), &buffer);
+  QuicString header = QuicString(buffer.get(), header_length);
+  // Partially send only 1 byte of the header to process.
+  EXPECT_EQ(1u, decoder_.ProcessInput(header.data(), 1));
+  EXPECT_EQ(QUIC_NO_ERROR, decoder_.error());
+  EXPECT_EQ("", decoder_.error_detail());
+
+  // Send the rest of the header.
+  EXPECT_EQ(header_length - 1,
+            decoder_.ProcessInput(header.data() + 1, header_length - 1));
+  EXPECT_EQ(QUIC_NO_ERROR, decoder_.error());
+  EXPECT_EQ("", decoder_.error_detail());
+
+  // Send data.
+  EXPECT_CALL(visitor_, OnDataFrameStart(Http3FrameLengths(3, 2048)));
+  EXPECT_CALL(visitor_, OnDataFramePayload(QuicStringPiece(input)));
+  EXPECT_CALL(visitor_, OnDataFrameEnd());
+  EXPECT_EQ(2048u, decoder_.ProcessInput(input.data(), 2048));
+  EXPECT_EQ(QUIC_NO_ERROR, decoder_.error());
+  EXPECT_EQ("", decoder_.error_detail());
+}
+
+TEST_F(HttpDecoderTest, GoAway) {
+  char input[] = {// length
+                  0x1,
+                  // type (GOAWAY)
+                  0x07,
+                  // StreamId
+                  0x01};
+
+  // Process the full frame.
+  EXPECT_CALL(visitor_, OnGoAwayFrame(GoAwayFrame({1})));
+  EXPECT_EQ(QUIC_ARRAYSIZE(input),
+            decoder_.ProcessInput(input, QUIC_ARRAYSIZE(input)));
+  EXPECT_EQ(QUIC_NO_ERROR, decoder_.error());
+  EXPECT_EQ("", decoder_.error_detail());
+
+  // Process the frame incremently.
+  EXPECT_CALL(visitor_, OnGoAwayFrame(GoAwayFrame({1})));
+  for (char c : input) {
+    EXPECT_EQ(1u, decoder_.ProcessInput(&c, 1));
+  }
+  EXPECT_EQ(QUIC_NO_ERROR, decoder_.error());
+  EXPECT_EQ("", decoder_.error_detail());
+}
+
+TEST_F(HttpDecoderTest, HeadersFrame) {
+  char input[] = {// length
+                  0x07,
+                  // type (HEADERS)
+                  0x01,
+                  // headers
+                  'H', 'e', 'a', 'd', 'e', 'r', 's'};
+
+  // Process the full frame.
+  InSequence s;
+  EXPECT_CALL(visitor_, OnHeadersFrameStart());
+  EXPECT_CALL(visitor_, OnHeadersFramePayload(QuicStringPiece("Headers")));
+  EXPECT_CALL(visitor_, OnHeadersFrameEnd(7));
+  EXPECT_EQ(QUIC_ARRAYSIZE(input),
+            decoder_.ProcessInput(input, QUIC_ARRAYSIZE(input)));
+  EXPECT_EQ(QUIC_NO_ERROR, decoder_.error());
+  EXPECT_EQ("", decoder_.error_detail());
+
+  // Process the frame incremently.
+  EXPECT_CALL(visitor_, OnHeadersFrameStart());
+  EXPECT_CALL(visitor_, OnHeadersFramePayload(QuicStringPiece("H")));
+  EXPECT_CALL(visitor_, OnHeadersFramePayload(QuicStringPiece("e")));
+  EXPECT_CALL(visitor_, OnHeadersFramePayload(QuicStringPiece("a")));
+  EXPECT_CALL(visitor_, OnHeadersFramePayload(QuicStringPiece("d")));
+  EXPECT_CALL(visitor_, OnHeadersFramePayload(QuicStringPiece("e")));
+  EXPECT_CALL(visitor_, OnHeadersFramePayload(QuicStringPiece("r")));
+  EXPECT_CALL(visitor_, OnHeadersFramePayload(QuicStringPiece("s")));
+  EXPECT_CALL(visitor_, OnHeadersFrameEnd(7));
+  for (char c : input) {
+    EXPECT_EQ(1u, decoder_.ProcessInput(&c, 1));
+  }
+  EXPECT_EQ(QUIC_NO_ERROR, decoder_.error());
+  EXPECT_EQ("", decoder_.error_detail());
+}
+
+}  // namespace quic
diff --git a/quic/core/http/http_encoder.cc b/quic/core/http/http_encoder.cc
new file mode 100644
index 0000000..d2d1699
--- /dev/null
+++ b/quic/core/http/http_encoder.cc
@@ -0,0 +1,257 @@
+// Copyright (c) 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/third_party/quiche/src/quic/core/http/http_encoder.h"
+#include "net/third_party/quiche/src/quic/core/quic_data_writer.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_bug_tracker.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_fallthrough.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_logging.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_string.h"
+
+namespace quic {
+
+namespace {
+
+// Set the first byte of a PRIORITY frame according to its fields.
+uint8_t SetPriorityFields(uint8_t num,
+                          PriorityElementType type,
+                          bool prioritized) {
+  switch (type) {
+    case REQUEST_STREAM:
+      return num;
+    case PUSH_STREAM:
+      if (prioritized) {
+        return num | (1 << 6);
+      }
+      return num | (1 << 4);
+    case PLACEHOLDER:
+      if (prioritized) {
+        return num | (1 << 7);
+      }
+      return num | (1 << 5);
+    case ROOT_OF_TREE:
+      if (prioritized) {
+        num = num | (1 << 6);
+        return num | (1 << 7);
+      }
+      num = num | (1 << 4);
+      return num | (1 << 5);
+    default:
+      QUIC_NOTREACHED();
+      return num;
+  }
+}
+
+// Length of the type field of a frame.
+static const size_t kFrameTypeLength = 1;
+// Length of the weight field of a priority frame.
+static const size_t kPriorityWeightLength = 1;
+// Length of a priority frame's first byte.
+static const size_t kPriorityFirstByteLength = 1;
+// Length of a key in the map of a settings frame.
+static const size_t kSettingsMapKeyLength = 2;
+
+}  // namespace
+
+HttpEncoder::HttpEncoder() {}
+
+HttpEncoder::~HttpEncoder() {}
+
+QuicByteCount HttpEncoder::SerializeDataFrameHeader(
+    QuicByteCount payload_length,
+    std::unique_ptr<char[]>* output) {
+  DCHECK_NE(0u, payload_length);
+  QuicByteCount header_length =
+      QuicDataWriter::GetVarInt62Len(payload_length) + kFrameTypeLength;
+
+  output->reset(new char[header_length]);
+  QuicDataWriter writer(header_length, output->get());
+
+  if (WriteFrameHeader(payload_length, HttpFrameType::DATA, &writer)) {
+    return header_length;
+  }
+  return 0;
+}
+
+QuicByteCount HttpEncoder::SerializeHeadersFrameHeader(
+    QuicByteCount payload_length,
+    std::unique_ptr<char[]>* output) {
+  DCHECK_NE(0u, payload_length);
+  QuicByteCount header_length =
+      QuicDataWriter::GetVarInt62Len(payload_length) + kFrameTypeLength;
+
+  output->reset(new char[header_length]);
+  QuicDataWriter writer(header_length, output->get());
+
+  if (WriteFrameHeader(payload_length, HttpFrameType::HEADERS, &writer)) {
+    return header_length;
+  }
+  return 0;
+}
+
+QuicByteCount HttpEncoder::SerializePriorityFrame(
+    const PriorityFrame& priority,
+    std::unique_ptr<char[]>* output) {
+  QuicByteCount payload_length =
+      kPriorityFirstByteLength +
+      QuicDataWriter::GetVarInt62Len(priority.prioritized_element_id) +
+      QuicDataWriter::GetVarInt62Len(priority.element_dependency_id) +
+      kPriorityWeightLength;
+  QuicByteCount total_length = GetTotalLength(payload_length);
+
+  output->reset(new char[total_length]);
+  QuicDataWriter writer(total_length, output->get());
+
+  if (!WriteFrameHeader(payload_length, HttpFrameType::PRIORITY, &writer)) {
+    return 0;
+  }
+
+  // Set the first byte of the payload.
+  uint8_t bits = 0;
+  bits = SetPriorityFields(bits, priority.prioritized_type, true);
+  bits = SetPriorityFields(bits, priority.dependency_type, false);
+  if (priority.exclusive) {
+    bits |= 1;
+  }
+
+  if (writer.WriteUInt8(bits) &&
+      writer.WriteVarInt62(priority.prioritized_element_id) &&
+      writer.WriteVarInt62(priority.element_dependency_id) &&
+      writer.WriteUInt8(priority.weight)) {
+    return total_length;
+  }
+  return 0;
+}
+
+QuicByteCount HttpEncoder::SerializeCancelPushFrame(
+    const CancelPushFrame& cancel_push,
+    std::unique_ptr<char[]>* output) {
+  QuicByteCount payload_length =
+      QuicDataWriter::GetVarInt62Len(cancel_push.push_id);
+  QuicByteCount total_length = GetTotalLength(payload_length);
+
+  output->reset(new char[total_length]);
+  QuicDataWriter writer(total_length, output->get());
+
+  if (WriteFrameHeader(payload_length, HttpFrameType::CANCEL_PUSH, &writer) &&
+      writer.WriteVarInt62(cancel_push.push_id)) {
+    return total_length;
+  }
+  return 0;
+}
+
+QuicByteCount HttpEncoder::SerializeSettingsFrame(
+    const SettingsFrame& settings,
+    std::unique_ptr<char[]>* output) {
+  // Calculate the key sizes.
+  QuicByteCount payload_length = settings.values.size() * kSettingsMapKeyLength;
+  // Calculate the value sizes.
+  for (auto it = settings.values.begin(); it != settings.values.end(); ++it) {
+    payload_length += QuicDataWriter::GetVarInt62Len(it->second);
+  }
+
+  QuicByteCount total_length = GetTotalLength(payload_length);
+
+  output->reset(new char[total_length]);
+  QuicDataWriter writer(total_length, output->get());
+
+  if (!WriteFrameHeader(payload_length, HttpFrameType::SETTINGS, &writer)) {
+    return 0;
+  }
+
+  for (auto it = settings.values.begin(); it != settings.values.end(); ++it) {
+    if (!writer.WriteUInt16(it->first) || !writer.WriteVarInt62(it->second)) {
+      return 0;
+    }
+  }
+
+  return total_length;
+}
+
+QuicByteCount HttpEncoder::SerializePushPromiseFrameWithOnlyPushId(
+    const PushPromiseFrame& push_promise,
+    std::unique_ptr<char[]>* output) {
+  QuicByteCount payload_length =
+      QuicDataWriter::GetVarInt62Len(push_promise.push_id) +
+      push_promise.headers.length();
+  // GetTotalLength() is not used because headers will not be serialized.
+  QuicByteCount total_length =
+      QuicDataWriter::GetVarInt62Len(payload_length) + kFrameTypeLength +
+      QuicDataWriter::GetVarInt62Len(push_promise.push_id);
+
+  output->reset(new char[total_length]);
+  QuicDataWriter writer(total_length, output->get());
+
+  if (WriteFrameHeader(payload_length, HttpFrameType::PUSH_PROMISE, &writer) &&
+      writer.WriteVarInt62(push_promise.push_id)) {
+    return total_length;
+  }
+  return 0;
+}
+
+QuicByteCount HttpEncoder::SerializeGoAwayFrame(
+    const GoAwayFrame& goaway,
+    std::unique_ptr<char[]>* output) {
+  QuicByteCount payload_length =
+      QuicDataWriter::GetVarInt62Len(goaway.stream_id);
+  QuicByteCount total_length = GetTotalLength(payload_length);
+
+  output->reset(new char[total_length]);
+  QuicDataWriter writer(total_length, output->get());
+
+  if (WriteFrameHeader(payload_length, HttpFrameType::GOAWAY, &writer) &&
+      writer.WriteVarInt62(goaway.stream_id)) {
+    return total_length;
+  }
+  return 0;
+}
+
+QuicByteCount HttpEncoder::SerializeMaxPushIdFrame(
+    const MaxPushIdFrame& max_push_id,
+    std::unique_ptr<char[]>* output) {
+  QuicByteCount payload_length =
+      QuicDataWriter::GetVarInt62Len(max_push_id.push_id);
+  QuicByteCount total_length = GetTotalLength(payload_length);
+
+  output->reset(new char[total_length]);
+  QuicDataWriter writer(total_length, output->get());
+
+  if (WriteFrameHeader(payload_length, HttpFrameType::MAX_PUSH_ID, &writer) &&
+      writer.WriteVarInt62(max_push_id.push_id)) {
+    return total_length;
+  }
+  return 0;
+}
+
+QuicByteCount HttpEncoder::SerializeDuplicatePushFrame(
+    const DuplicatePushFrame& duplicate_push,
+    std::unique_ptr<char[]>* output) {
+  QuicByteCount payload_length =
+      QuicDataWriter::GetVarInt62Len(duplicate_push.push_id);
+  QuicByteCount total_length = GetTotalLength(payload_length);
+
+  output->reset(new char[total_length]);
+  QuicDataWriter writer(total_length, output->get());
+
+  if (WriteFrameHeader(payload_length, HttpFrameType::DUPLICATE_PUSH,
+                       &writer) &&
+      writer.WriteVarInt62(duplicate_push.push_id)) {
+    return total_length;
+  }
+  return 0;
+}
+
+bool HttpEncoder::WriteFrameHeader(QuicByteCount length,
+                                   HttpFrameType type,
+                                   QuicDataWriter* writer) {
+  return writer->WriteVarInt62(length) &&
+         writer->WriteUInt8(static_cast<uint8_t>(type));
+}
+
+QuicByteCount HttpEncoder::GetTotalLength(QuicByteCount payload_length) {
+  return QuicDataWriter::GetVarInt62Len(payload_length) + kFrameTypeLength +
+         payload_length;
+}
+
+}  // namespace quic
diff --git a/quic/core/http/http_encoder.h b/quic/core/http/http_encoder.h
new file mode 100644
index 0000000..f04e6e4
--- /dev/null
+++ b/quic/core/http/http_encoder.h
@@ -0,0 +1,85 @@
+// Copyright (c) 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_HTTP_HTTP_ENCODER_H_
+#define QUICHE_QUIC_CORE_HTTP_HTTP_ENCODER_H_
+
+#include <cstddef>
+
+#include "net/third_party/quiche/src/quic/core/http/http_frames.h"
+#include "net/third_party/quiche/src/quic/core/quic_error_codes.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_export.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_string_piece.h"
+
+namespace quic {
+
+class QuicDataWriter;
+
+// A class for encoding the HTTP frames that are exchanged in an HTTP over QUIC
+// session.
+class QUIC_EXPORT_PRIVATE HttpEncoder {
+ public:
+  HttpEncoder();
+
+  ~HttpEncoder();
+
+  // Serializes a DATA frame header into a new buffer stored in |output|.
+  // Returns the length of the buffer on success, or 0 otherwise.
+  QuicByteCount SerializeDataFrameHeader(QuicByteCount payload_length,
+                                         std::unique_ptr<char[]>* output);
+
+  // Serializes a HEADERS frame header into a new buffer stored in |output|.
+  // Returns the length of the buffer on success, or 0 otherwise.
+  QuicByteCount SerializeHeadersFrameHeader(QuicByteCount payload_length,
+                                            std::unique_ptr<char[]>* output);
+
+  // Serializes a PRIORITY frame into a new buffer stored in |output|.
+  // Returns the length of the buffer on success, or 0 otherwise.
+  QuicByteCount SerializePriorityFrame(const PriorityFrame& priority,
+                                       std::unique_ptr<char[]>* output);
+
+  // Serializes a CANCEL_PUSH frame into a new buffer stored in |output|.
+  // Returns the length of the buffer on success, or 0 otherwise.
+  QuicByteCount SerializeCancelPushFrame(const CancelPushFrame& cancel_push,
+                                         std::unique_ptr<char[]>* output);
+
+  // Serializes a SETTINGS frame into a new buffer stored in |output|.
+  // Returns the length of the buffer on success, or 0 otherwise.
+  QuicByteCount SerializeSettingsFrame(const SettingsFrame& settings,
+                                       std::unique_ptr<char[]>* output);
+
+  // Serializes the header and push_id of a PUSH_PROMISE frame into a new buffer
+  // stored in |output|. Returns the length of the buffer on success, or 0
+  // otherwise.
+  QuicByteCount SerializePushPromiseFrameWithOnlyPushId(
+      const PushPromiseFrame& push_promise,
+      std::unique_ptr<char[]>* output);
+
+  // Serializes a GOAWAY frame into a new buffer stored in |output|.
+  // Returns the length of the buffer on success, or 0 otherwise.
+  QuicByteCount SerializeGoAwayFrame(const GoAwayFrame& goaway,
+                                     std::unique_ptr<char[]>* output);
+
+  // Serializes a MAX_PUSH frame into a new buffer stored in |output|.
+  // Returns the length of the buffer on success, or 0 otherwise.
+  QuicByteCount SerializeMaxPushIdFrame(const MaxPushIdFrame& max_push_id,
+                                        std::unique_ptr<char[]>* output);
+
+  // Serialize a DUPLICATE_PUSH frame into a new buffer stored in |output|.
+  // Returns the length of the buffer on success, or 0 otherwise.
+  QuicByteCount SerializeDuplicatePushFrame(
+      const DuplicatePushFrame& duplicate_push,
+      std::unique_ptr<char[]>* output);
+
+ private:
+  bool WriteFrameHeader(QuicByteCount length,
+                        HttpFrameType type,
+                        QuicDataWriter* writer);
+
+  QuicByteCount GetTotalLength(QuicByteCount payload_length);
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_HTTP_HTTP_ENCODER_H_
diff --git a/quic/core/http/http_encoder_test.cc b/quic/core/http/http_encoder_test.cc
new file mode 100644
index 0000000..a484aed
--- /dev/null
+++ b/quic/core/http/http_encoder_test.cc
@@ -0,0 +1,185 @@
+// Copyright (c) 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/third_party/quiche/src/quic/core/http/http_encoder.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_arraysize.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_string.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_test.h"
+#include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h"
+
+namespace quic {
+namespace test {
+
+class HttpEncoderTest : public QuicTest {
+ public:
+  HttpEncoderTest() {}
+  HttpEncoder encoder_;
+};
+
+TEST_F(HttpEncoderTest, SerializeDataFrameHeader) {
+  std::unique_ptr<char[]> buffer;
+  uint64_t length =
+      encoder_.SerializeDataFrameHeader(/* payload_length = */ 5, &buffer);
+  char output[] = {// length
+                   0x05,
+                   // type (DATA)
+                   0x00};
+  EXPECT_EQ(QUIC_ARRAYSIZE(output), length);
+  CompareCharArraysWithHexError("DATA", buffer.get(), length, output,
+                                QUIC_ARRAYSIZE(output));
+}
+
+TEST_F(HttpEncoderTest, SerializeHeadersFrameHeader) {
+  std::unique_ptr<char[]> buffer;
+  uint64_t length =
+      encoder_.SerializeHeadersFrameHeader(/* payload_length = */ 7, &buffer);
+  char output[] = {// length
+                   0x07,
+                   // type (HEADERS)
+                   0x01};
+  EXPECT_EQ(QUIC_ARRAYSIZE(output), length);
+  CompareCharArraysWithHexError("HEADERS", buffer.get(), length, output,
+                                QUIC_ARRAYSIZE(output));
+}
+
+TEST_F(HttpEncoderTest, SerializePriorityFrame) {
+  PriorityFrame priority;
+  priority.prioritized_type = REQUEST_STREAM;
+  priority.dependency_type = REQUEST_STREAM;
+  priority.exclusive = true;
+  priority.prioritized_element_id = 0x03;
+  priority.element_dependency_id = 0x04;
+  priority.weight = 0xFF;
+  char output[] = {// length
+                   0x4,
+                   // type (PRIORITY)
+                   0x2,
+                   // request stream, request stream, exclusive
+                   0x01,
+                   // prioritized_element_id
+                   0x03,
+                   // element_dependency_id
+                   0x04,
+                   // weight
+                   0xFF};
+
+  std::unique_ptr<char[]> buffer;
+  uint64_t length = encoder_.SerializePriorityFrame(priority, &buffer);
+  EXPECT_EQ(QUIC_ARRAYSIZE(output), length);
+  CompareCharArraysWithHexError("PRIORITY", buffer.get(), length, output,
+                                QUIC_ARRAYSIZE(output));
+}
+
+TEST_F(HttpEncoderTest, SerializeCancelPushFrame) {
+  CancelPushFrame cancel_push;
+  cancel_push.push_id = 0x01;
+  char output[] = {// length
+                   0x1,
+                   // type (CANCEL_PUSH)
+                   0x03,
+                   // Push Id
+                   0x01};
+  std::unique_ptr<char[]> buffer;
+  uint64_t length = encoder_.SerializeCancelPushFrame(cancel_push, &buffer);
+  EXPECT_EQ(QUIC_ARRAYSIZE(output), length);
+  CompareCharArraysWithHexError("CANCEL_PUSH", buffer.get(), length, output,
+                                QUIC_ARRAYSIZE(output));
+}
+
+TEST_F(HttpEncoderTest, SerializeSettingsFrame) {
+  SettingsFrame settings;
+  settings.values[3] = 2;
+  settings.values[6] = 5;
+  char output[] = {
+      // length
+      0x06,
+      // type (SETTINGS)
+      0x04,
+      // identifier (SETTINGS_NUM_PLACEHOLDERS)
+      0x00,
+      0x03,
+      // content
+      0x02,
+      // identifier (SETTINGS_MAX_HEADER_LIST_SIZE)
+      0x00,
+      0x06,
+      // content
+      0x05,
+  };
+  std::unique_ptr<char[]> buffer;
+  uint64_t length = encoder_.SerializeSettingsFrame(settings, &buffer);
+  EXPECT_EQ(QUIC_ARRAYSIZE(output), length);
+  CompareCharArraysWithHexError("SETTINGS", buffer.get(), length, output,
+                                QUIC_ARRAYSIZE(output));
+}
+
+TEST_F(HttpEncoderTest, SerializePushPromiseFrameWithOnlyPushId) {
+  PushPromiseFrame push_promise;
+  push_promise.push_id = 0x01;
+  push_promise.headers = "Headers";
+  char output[] = {// length
+                   0x8,
+                   // type (PUSH_PROMISE)
+                   0x05,
+                   // Push Id
+                   0x01};
+  std::unique_ptr<char[]> buffer;
+  uint64_t length =
+      encoder_.SerializePushPromiseFrameWithOnlyPushId(push_promise, &buffer);
+  EXPECT_EQ(QUIC_ARRAYSIZE(output), length);
+  CompareCharArraysWithHexError("PUSH_PROMISE", buffer.get(), length, output,
+                                QUIC_ARRAYSIZE(output));
+}
+
+TEST_F(HttpEncoderTest, SerializeGoAwayFrame) {
+  GoAwayFrame goaway;
+  goaway.stream_id = 0x1;
+  char output[] = {// length
+                   0x1,
+                   // type (GOAWAY)
+                   0x07,
+                   // StreamId
+                   0x01};
+  std::unique_ptr<char[]> buffer;
+  uint64_t length = encoder_.SerializeGoAwayFrame(goaway, &buffer);
+  EXPECT_EQ(QUIC_ARRAYSIZE(output), length);
+  CompareCharArraysWithHexError("GOAWAY", buffer.get(), length, output,
+                                QUIC_ARRAYSIZE(output));
+}
+
+TEST_F(HttpEncoderTest, SerializeMaxPushIdFrame) {
+  MaxPushIdFrame max_push_id;
+  max_push_id.push_id = 0x1;
+  char output[] = {// length
+                   0x1,
+                   // type (MAX_PUSH_ID)
+                   0x0D,
+                   // Push Id
+                   0x01};
+  std::unique_ptr<char[]> buffer;
+  uint64_t length = encoder_.SerializeMaxPushIdFrame(max_push_id, &buffer);
+  EXPECT_EQ(QUIC_ARRAYSIZE(output), length);
+  CompareCharArraysWithHexError("MAX_PUSH_ID", buffer.get(), length, output,
+                                QUIC_ARRAYSIZE(output));
+}
+
+TEST_F(HttpEncoderTest, SerializeDuplicatePushFrame) {
+  DuplicatePushFrame duplicate_push;
+  duplicate_push.push_id = 0x1;
+  char output[] = {// length
+                   0x1,
+                   // type (DUPLICATE_PUSH)
+                   0x0E,
+                   // Push Id
+                   0x01};
+  std::unique_ptr<char[]> buffer;
+  uint64_t length =
+      encoder_.SerializeDuplicatePushFrame(duplicate_push, &buffer);
+  EXPECT_EQ(QUIC_ARRAYSIZE(output), length);
+  CompareCharArraysWithHexError("DUPLICATE_PUSH", buffer.get(), length, output,
+                                QUIC_ARRAYSIZE(output));
+}
+
+}  // namespace test
+}  // namespace quic
diff --git a/quic/core/http/http_frames.h b/quic/core/http/http_frames.h
new file mode 100644
index 0000000..ea11557
--- /dev/null
+++ b/quic/core/http/http_frames.h
@@ -0,0 +1,156 @@
+// Copyright (c) 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_HTTP_HTTP_FRAMES_H_
+#define QUICHE_QUIC_CORE_HTTP_HTTP_FRAMES_H_
+
+#include <map>
+
+#include "net/third_party/quiche/src/quic/core/quic_types.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_string_piece.h"
+#include "net/third_party/quiche/src/spdy/core/spdy_framer.h"
+
+namespace quic {
+
+enum class HttpFrameType : uint8_t {
+  DATA = 0x0,
+  HEADERS = 0x1,
+  PRIORITY = 0X2,
+  CANCEL_PUSH = 0X3,
+  SETTINGS = 0x4,
+  PUSH_PROMISE = 0x5,
+  GOAWAY = 0x7,
+  MAX_PUSH_ID = 0xD,
+  DUPLICATE_PUSH = 0xE
+};
+
+// 4.2.1.  DATA
+//
+//   DATA frames (type=0x0) convey arbitrary, variable-length sequences of
+//   octets associated with an HTTP request or response payload.
+struct DataFrame {
+  QuicStringPiece data;
+};
+
+// 4.2.2.  HEADERS
+//
+//   The HEADERS frame (type=0x1) is used to carry a header block,
+//   compressed using QPACK.
+struct HeadersFrame {
+  QuicStringPiece headers;
+};
+
+// 4.2.3.  PRIORITY
+//
+//   The PRIORITY (type=0x02) frame specifies the sender-advised priority
+//   of a stream
+enum PriorityElementType {
+  REQUEST_STREAM = 0,
+  PUSH_STREAM = 1,
+  PLACEHOLDER = 2,
+  ROOT_OF_TREE = 3
+};
+
+struct PriorityFrame {
+  PriorityElementType prioritized_type;
+  PriorityElementType dependency_type;
+  bool exclusive;
+  uint64_t prioritized_element_id;
+  uint64_t element_dependency_id;
+  uint8_t weight;
+
+  bool operator==(const PriorityFrame& rhs) const {
+    return prioritized_type == rhs.prioritized_type &&
+           dependency_type == rhs.dependency_type &&
+           exclusive == rhs.exclusive &&
+           prioritized_element_id == rhs.prioritized_element_id &&
+           element_dependency_id == rhs.element_dependency_id &&
+           weight == rhs.weight;
+  }
+};
+
+// 4.2.4.  CANCEL_PUSH
+//
+//   The CANCEL_PUSH frame (type=0x3) is used to request cancellation of
+//   server push prior to the push stream being created.
+using PushId = uint64_t;
+
+struct CancelPushFrame {
+  PushId push_id;
+
+  bool operator==(const CancelPushFrame& rhs) const {
+    return push_id == rhs.push_id;
+  }
+};
+
+// 4.2.5.  SETTINGS
+//
+//   The SETTINGS frame (type=0x4) conveys configuration parameters that
+//   affect how endpoints communicate, such as preferences and constraints
+//   on peer behavior
+
+using SettingsId = uint16_t;
+using SettingsMap = std::map<SettingsId, uint64_t>;
+
+struct SettingsFrame {
+  SettingsMap values;
+
+  bool operator==(const SettingsFrame& rhs) const {
+    return values == rhs.values;
+  }
+};
+
+// 4.2.6.  PUSH_PROMISE
+//
+//   The PUSH_PROMISE frame (type=0x05) is used to carry a request header
+//   set from server to client, as in HTTP/2.
+struct PushPromiseFrame {
+  PushId push_id;
+  QuicStringPiece headers;
+
+  bool operator==(const PushPromiseFrame& rhs) const {
+    return push_id == rhs.push_id && headers == rhs.headers;
+  }
+};
+
+// 4.2.7.  GOAWAY
+//
+//   The GOAWAY frame (type=0x7) is used to initiate graceful shutdown of
+//   a connection by a server.
+struct GoAwayFrame {
+  QuicStreamId stream_id;
+
+  bool operator==(const GoAwayFrame& rhs) const {
+    return stream_id == rhs.stream_id;
+  }
+};
+
+// 4.2.8.  MAX_PUSH_ID
+//
+//   The MAX_PUSH_ID frame (type=0xD) is used by clients to control the
+//   number of server pushes that the server can initiate.
+struct MaxPushIdFrame {
+  PushId push_id;
+
+  bool operator==(const MaxPushIdFrame& rhs) const {
+    return push_id == rhs.push_id;
+  }
+};
+
+// 4.2.9.  DUPLICATE_PUSH
+//
+//  The DUPLICATE_PUSH frame (type=0xE) is used by servers to indicate
+//  that an existing pushed resource is related to multiple client
+//  requests.
+struct DuplicatePushFrame {
+  PushId push_id;
+
+  bool operator==(const DuplicatePushFrame& rhs) const {
+    return push_id == rhs.push_id;
+  }
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_HTTP_HTTP_FRAMES_H_
diff --git a/quic/core/http/quic_client_promised_info.cc b/quic/core/http/quic_client_promised_info.cc
new file mode 100644
index 0000000..abfc4b4
--- /dev/null
+++ b/quic/core/http/quic_client_promised_info.cc
@@ -0,0 +1,144 @@
+// Copyright (c) 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/third_party/quiche/src/quic/core/http/quic_client_promised_info.h"
+
+#include <utility>
+
+#include "net/third_party/quiche/src/quic/core/http/spdy_utils.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_logging.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_ptr_util.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_string.h"
+#include "net/third_party/quiche/src/spdy/core/spdy_protocol.h"
+
+using spdy::SpdyHeaderBlock;
+
+namespace quic {
+
+QuicClientPromisedInfo::QuicClientPromisedInfo(
+    QuicSpdyClientSessionBase* session,
+    QuicStreamId id,
+    QuicString url)
+    : session_(session),
+      id_(id),
+      url_(std::move(url)),
+      client_request_delegate_(nullptr) {}
+
+QuicClientPromisedInfo::~QuicClientPromisedInfo() {}
+
+void QuicClientPromisedInfo::CleanupAlarm::OnAlarm() {
+  QUIC_DVLOG(1) << "self GC alarm for stream " << promised_->id_;
+  promised_->session()->OnPushStreamTimedOut(promised_->id_);
+  promised_->Reset(QUIC_PUSH_STREAM_TIMED_OUT);
+}
+
+void QuicClientPromisedInfo::Init() {
+  cleanup_alarm_.reset(session_->connection()->alarm_factory()->CreateAlarm(
+      new QuicClientPromisedInfo::CleanupAlarm(this)));
+  cleanup_alarm_->Set(
+      session_->connection()->helper()->GetClock()->ApproximateNow() +
+      QuicTime::Delta::FromSeconds(kPushPromiseTimeoutSecs));
+}
+
+bool QuicClientPromisedInfo::OnPromiseHeaders(const SpdyHeaderBlock& headers) {
+  // RFC7540, Section 8.2, requests MUST be safe [RFC7231], Section
+  // 4.2.1.  GET and HEAD are the methods that are safe and required.
+  SpdyHeaderBlock::const_iterator it = headers.find(spdy::kHttp2MethodHeader);
+  if (it == headers.end()) {
+    QUIC_DVLOG(1) << "Promise for stream " << id_ << " has no method";
+    Reset(QUIC_INVALID_PROMISE_METHOD);
+    return false;
+  }
+  if (!(it->second == "GET" || it->second == "HEAD")) {
+    QUIC_DVLOG(1) << "Promise for stream " << id_ << " has invalid method "
+                  << it->second;
+    Reset(QUIC_INVALID_PROMISE_METHOD);
+    return false;
+  }
+  if (!SpdyUtils::PromisedUrlIsValid(headers)) {
+    QUIC_DVLOG(1) << "Promise for stream " << id_ << " has invalid URL "
+                  << url_;
+    Reset(QUIC_INVALID_PROMISE_URL);
+    return false;
+  }
+  if (!session_->IsAuthorized(
+          SpdyUtils::GetPromisedHostNameFromHeaders(headers))) {
+    Reset(QUIC_UNAUTHORIZED_PROMISE_URL);
+    return false;
+  }
+  request_headers_ = headers.Clone();
+  return true;
+}
+
+void QuicClientPromisedInfo::OnResponseHeaders(const SpdyHeaderBlock& headers) {
+  response_headers_ = QuicMakeUnique<SpdyHeaderBlock>(headers.Clone());
+  if (client_request_delegate_) {
+    // We already have a client request waiting.
+    FinalValidation();
+  }
+}
+
+void QuicClientPromisedInfo::Reset(QuicRstStreamErrorCode error_code) {
+  QuicClientPushPromiseIndex::Delegate* delegate = client_request_delegate_;
+  session_->ResetPromised(id_, error_code);
+  session_->DeletePromised(this);
+  if (delegate) {
+    delegate->OnRendezvousResult(nullptr);
+  }
+}
+
+QuicAsyncStatus QuicClientPromisedInfo::FinalValidation() {
+  if (!client_request_delegate_->CheckVary(
+          client_request_headers_, request_headers_, *response_headers_)) {
+    Reset(QUIC_PROMISE_VARY_MISMATCH);
+    return QUIC_FAILURE;
+  }
+  QuicSpdyStream* stream = session_->GetPromisedStream(id_);
+  if (!stream) {
+    // This shouldn't be possible, as |ClientRequest| guards against
+    // closed stream for the synchronous case.  And in the
+    // asynchronous case, a RST can only be caught by |OnAlarm()|.
+    QUIC_BUG << "missing promised stream" << id_;
+  }
+  QuicClientPushPromiseIndex::Delegate* delegate = client_request_delegate_;
+  session_->DeletePromised(this);
+  // Stream can start draining now
+  if (delegate) {
+    delegate->OnRendezvousResult(stream);
+  }
+  return QUIC_SUCCESS;
+}
+
+QuicAsyncStatus QuicClientPromisedInfo::HandleClientRequest(
+    const SpdyHeaderBlock& request_headers,
+    QuicClientPushPromiseIndex::Delegate* delegate) {
+  if (session_->IsClosedStream(id_)) {
+    // There was a RST on the response stream.
+    session_->DeletePromised(this);
+    return QUIC_FAILURE;
+  }
+
+  if (is_validating()) {
+    // The push promise has already been matched to another request though
+    // pending for validation. Returns QUIC_FAILURE to the caller as it couldn't
+    // match a new request any more. This will not affect the validation of the
+    // other request.
+    return QUIC_FAILURE;
+  }
+
+  client_request_delegate_ = delegate;
+  client_request_headers_ = request_headers.Clone();
+  if (response_headers_ == nullptr) {
+    return QUIC_PENDING;
+  }
+  return FinalValidation();
+}
+
+void QuicClientPromisedInfo::Cancel() {
+  // Don't fire OnRendezvousResult() for client initiated cancel.
+  client_request_delegate_ = nullptr;
+  Reset(QUIC_STREAM_CANCELLED);
+}
+
+}  // namespace quic
diff --git a/quic/core/http/quic_client_promised_info.h b/quic/core/http/quic_client_promised_info.h
new file mode 100644
index 0000000..917c9f7
--- /dev/null
+++ b/quic/core/http/quic_client_promised_info.h
@@ -0,0 +1,114 @@
+// Copyright (c) 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_HTTP_QUIC_CLIENT_PROMISED_INFO_H_
+#define QUICHE_QUIC_CORE_HTTP_QUIC_CLIENT_PROMISED_INFO_H_
+
+#include <cstddef>
+
+#include "net/third_party/quiche/src/quic/core/quic_alarm.h"
+#include "net/third_party/quiche/src/quic/core/http/quic_client_push_promise_index.h"
+#include "net/third_party/quiche/src/quic/core/quic_packets.h"
+#include "net/third_party/quiche/src/quic/core/http/quic_spdy_client_session_base.h"
+#include "net/third_party/quiche/src/quic/core/http/quic_spdy_stream.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_export.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_string.h"
+#include "net/third_party/quiche/src/spdy/core/spdy_framer.h"
+
+namespace quic {
+
+namespace test {
+class QuicClientPromisedInfoPeer;
+}  // namespace test
+
+// QuicClientPromisedInfo tracks the client state of a server push
+// stream from the time a PUSH_PROMISE is received until rendezvous
+// between the promised response and the corresponding client request
+// is complete.
+class QUIC_EXPORT_PRIVATE QuicClientPromisedInfo
+    : public QuicClientPushPromiseIndex::TryHandle {
+ public:
+  // Interface to QuicSpdyClientStream
+  QuicClientPromisedInfo(QuicSpdyClientSessionBase* session,
+                         QuicStreamId id,
+                         QuicString url);
+  QuicClientPromisedInfo(const QuicClientPromisedInfo&) = delete;
+  QuicClientPromisedInfo& operator=(const QuicClientPromisedInfo&) = delete;
+  virtual ~QuicClientPromisedInfo();
+
+  void Init();
+
+  // Validate promise headers etc. Returns true if headers are valid.
+  bool OnPromiseHeaders(const spdy::SpdyHeaderBlock& headers);
+
+  // Store response, possibly proceed with final validation.
+  void OnResponseHeaders(const spdy::SpdyHeaderBlock& headers);
+
+  // Rendezvous between this promised stream and a client request that
+  // has a matching URL.
+  virtual QuicAsyncStatus HandleClientRequest(
+      const spdy::SpdyHeaderBlock& headers,
+      QuicClientPushPromiseIndex::Delegate* delegate);
+
+  void Cancel() override;
+
+  void Reset(QuicRstStreamErrorCode error_code);
+
+  // Client requests are initially associated to promises by matching
+  // URL in the client request against the URL in the promise headers,
+  // uing the |promised_by_url| map.  The push can be cross-origin, so
+  // the client should validate that the session is authoritative for
+  // the promised URL.  If not, it should call |RejectUnauthorized|.
+  QuicSpdyClientSessionBase* session() { return session_; }
+
+  // If the promised response contains Vary header, then the fields
+  // specified by Vary must match between the client request header
+  // and the promise headers (see https://crbug.com//554220).  Vary
+  // validation requires the response headers (for the actual Vary
+  // field list), the promise headers (taking the role of the "cached"
+  // request), and the client request headers.
+  spdy::SpdyHeaderBlock* request_headers() { return &request_headers_; }
+
+  spdy::SpdyHeaderBlock* response_headers() { return response_headers_.get(); }
+
+  // After validation, client will use this to access the pushed stream.
+
+  QuicStreamId id() const { return id_; }
+
+  const QuicString url() const { return url_; }
+
+  // Return true if there's a request pending matching this push promise.
+  bool is_validating() const { return client_request_delegate_ != nullptr; }
+
+ private:
+  friend class test::QuicClientPromisedInfoPeer;
+
+  class CleanupAlarm : public QuicAlarm::Delegate {
+   public:
+    explicit CleanupAlarm(QuicClientPromisedInfo* promised)
+        : promised_(promised) {}
+
+    void OnAlarm() override;
+
+    QuicClientPromisedInfo* promised_;
+  };
+
+  QuicAsyncStatus FinalValidation();
+
+  QuicSpdyClientSessionBase* session_;
+  QuicStreamId id_;
+  QuicString url_;
+  spdy::SpdyHeaderBlock request_headers_;
+  std::unique_ptr<spdy::SpdyHeaderBlock> response_headers_;
+  spdy::SpdyHeaderBlock client_request_headers_;
+  QuicClientPushPromiseIndex::Delegate* client_request_delegate_;
+
+  // The promise will commit suicide eventually if it is not claimed by a GET
+  // first.
+  std::unique_ptr<QuicAlarm> cleanup_alarm_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_HTTP_QUIC_CLIENT_PROMISED_INFO_H_
diff --git a/quic/core/http/quic_client_promised_info_test.cc b/quic/core/http/quic_client_promised_info_test.cc
new file mode 100644
index 0000000..2a7b1b0
--- /dev/null
+++ b/quic/core/http/quic_client_promised_info_test.cc
@@ -0,0 +1,355 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/third_party/quiche/src/quic/core/http/quic_client_promised_info.h"
+
+#include <memory>
+
+#include "base/macros.h"
+#include "net/third_party/quiche/src/quic/core/http/quic_spdy_client_session.h"
+#include "net/third_party/quiche/src/quic/core/http/spdy_utils.h"
+#include "net/third_party/quiche/src/quic/core/quic_utils.h"
+#include "net/third_party/quiche/src/quic/core/tls_client_handshaker.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_logging.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_ptr_util.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_socket_address.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_string.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_test.h"
+#include "net/third_party/quiche/src/quic/test_tools/crypto_test_utils.h"
+#include "net/third_party/quiche/src/quic/test_tools/quic_client_promised_info_peer.h"
+#include "net/third_party/quiche/src/quic/test_tools/quic_spdy_session_peer.h"
+#include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h"
+
+using spdy::SpdyHeaderBlock;
+using testing::_;
+using testing::StrictMock;
+
+namespace quic {
+namespace test {
+namespace {
+
+class MockQuicSpdyClientSession : public QuicSpdyClientSession {
+ public:
+  explicit MockQuicSpdyClientSession(
+      const ParsedQuicVersionVector& supported_versions,
+      QuicConnection* connection,
+      QuicClientPushPromiseIndex* push_promise_index)
+      : QuicSpdyClientSession(DefaultQuicConfig(),
+                              supported_versions,
+                              connection,
+                              QuicServerId("example.com", 443, false),
+                              &crypto_config_,
+                              push_promise_index),
+        crypto_config_(crypto_test_utils::ProofVerifierForTesting(),
+                       TlsClientHandshaker::CreateSslCtx()),
+        authorized_(true) {}
+  MockQuicSpdyClientSession(const MockQuicSpdyClientSession&) = delete;
+  MockQuicSpdyClientSession& operator=(const MockQuicSpdyClientSession&) =
+      delete;
+  ~MockQuicSpdyClientSession() override {}
+
+  bool IsAuthorized(const QuicString& authority) override {
+    return authorized_;
+  }
+
+  void set_authorized(bool authorized) { authorized_ = authorized; }
+
+  MOCK_METHOD1(CloseStream, void(QuicStreamId stream_id));
+
+ private:
+  QuicCryptoClientConfig crypto_config_;
+
+  bool authorized_;
+};
+
+class QuicClientPromisedInfoTest : public QuicTest {
+ public:
+  class StreamVisitor;
+
+  QuicClientPromisedInfoTest()
+      : connection_(new StrictMock<MockQuicConnection>(&helper_,
+                                                       &alarm_factory_,
+                                                       Perspective::IS_CLIENT)),
+        session_(connection_->supported_versions(),
+                 connection_,
+                 &push_promise_index_),
+        body_("hello world"),
+        promise_id_(
+            QuicUtils::GetInvalidStreamId(connection_->transport_version())) {
+    connection_->AdvanceTime(QuicTime::Delta::FromSeconds(1));
+    session_.Initialize();
+
+    headers_[":status"] = "200";
+    headers_["content-length"] = "11";
+
+    stream_ = QuicMakeUnique<QuicSpdyClientStream>(
+        GetNthClientInitiatedBidirectionalStreamId(
+            connection_->transport_version(), 0),
+        &session_, BIDIRECTIONAL);
+    stream_visitor_ = QuicMakeUnique<StreamVisitor>();
+    stream_->set_visitor(stream_visitor_.get());
+
+    push_promise_[":path"] = "/bar";
+    push_promise_[":authority"] = "www.google.com";
+    push_promise_[":version"] = "HTTP/1.1";
+    push_promise_[":method"] = "GET";
+    push_promise_[":scheme"] = "https";
+
+    promise_url_ = SpdyUtils::GetPromisedUrlFromHeaders(push_promise_);
+
+    client_request_ = push_promise_.Clone();
+    promise_id_ = GetNthServerInitiatedUnidirectionalStreamId(
+        connection_->transport_version(), 0);
+  }
+
+  class StreamVisitor : public QuicSpdyClientStream::Visitor {
+    void OnClose(QuicSpdyStream* stream) override {
+      QUIC_DVLOG(1) << "stream " << stream->id();
+    }
+  };
+
+  void ReceivePromise(QuicStreamId id) {
+    auto headers = AsHeaderList(push_promise_);
+    stream_->OnPromiseHeaderList(id, headers.uncompressed_header_bytes(),
+                                 headers);
+  }
+
+  MockQuicConnectionHelper helper_;
+  MockAlarmFactory alarm_factory_;
+  StrictMock<MockQuicConnection>* connection_;
+  QuicClientPushPromiseIndex push_promise_index_;
+
+  MockQuicSpdyClientSession session_;
+  std::unique_ptr<QuicSpdyClientStream> stream_;
+  std::unique_ptr<StreamVisitor> stream_visitor_;
+  std::unique_ptr<QuicSpdyClientStream> promised_stream_;
+  SpdyHeaderBlock headers_;
+  QuicString body_;
+  SpdyHeaderBlock push_promise_;
+  QuicStreamId promise_id_;
+  QuicString promise_url_;
+  SpdyHeaderBlock client_request_;
+};
+
+TEST_F(QuicClientPromisedInfoTest, PushPromise) {
+  ReceivePromise(promise_id_);
+
+  // Verify that the promise is in the unclaimed streams map.
+  EXPECT_NE(session_.GetPromisedById(promise_id_), nullptr);
+}
+
+TEST_F(QuicClientPromisedInfoTest, PushPromiseCleanupAlarm) {
+  ReceivePromise(promise_id_);
+
+  // Verify that the promise is in the unclaimed streams map.
+  QuicClientPromisedInfo* promised = session_.GetPromisedById(promise_id_);
+  ASSERT_NE(promised, nullptr);
+
+  // Fire the alarm that will cancel the promised stream.
+  EXPECT_CALL(*connection_, SendControlFrame(_));
+  EXPECT_CALL(*connection_,
+              OnStreamReset(promise_id_, QUIC_PUSH_STREAM_TIMED_OUT));
+  alarm_factory_.FireAlarm(QuicClientPromisedInfoPeer::GetAlarm(promised));
+
+  // Verify that the promise is gone after the alarm fires.
+  EXPECT_EQ(session_.GetPromisedById(promise_id_), nullptr);
+  EXPECT_EQ(session_.GetPromisedByUrl(promise_url_), nullptr);
+}
+
+TEST_F(QuicClientPromisedInfoTest, PushPromiseInvalidMethod) {
+  // Promise with an unsafe method
+  push_promise_[":method"] = "PUT";
+
+  EXPECT_CALL(*connection_, SendControlFrame(_));
+  EXPECT_CALL(*connection_,
+              OnStreamReset(promise_id_, QUIC_INVALID_PROMISE_METHOD));
+  ReceivePromise(promise_id_);
+
+  // Verify that the promise headers were ignored
+  EXPECT_EQ(session_.GetPromisedById(promise_id_), nullptr);
+  EXPECT_EQ(session_.GetPromisedByUrl(promise_url_), nullptr);
+}
+
+TEST_F(QuicClientPromisedInfoTest, PushPromiseMissingMethod) {
+  // Promise with a missing method
+  push_promise_.erase(":method");
+
+  EXPECT_CALL(*connection_, SendControlFrame(_));
+  EXPECT_CALL(*connection_,
+              OnStreamReset(promise_id_, QUIC_INVALID_PROMISE_METHOD));
+  ReceivePromise(promise_id_);
+
+  // Verify that the promise headers were ignored
+  EXPECT_EQ(session_.GetPromisedById(promise_id_), nullptr);
+  EXPECT_EQ(session_.GetPromisedByUrl(promise_url_), nullptr);
+}
+
+TEST_F(QuicClientPromisedInfoTest, PushPromiseInvalidUrl) {
+  // Remove required header field to make URL invalid
+  push_promise_.erase(":authority");
+
+  EXPECT_CALL(*connection_, SendControlFrame(_));
+  EXPECT_CALL(*connection_,
+              OnStreamReset(promise_id_, QUIC_INVALID_PROMISE_URL));
+  ReceivePromise(promise_id_);
+
+  // Verify that the promise headers were ignored
+  EXPECT_EQ(session_.GetPromisedById(promise_id_), nullptr);
+  EXPECT_EQ(session_.GetPromisedByUrl(promise_url_), nullptr);
+}
+
+TEST_F(QuicClientPromisedInfoTest, PushPromiseUnauthorizedUrl) {
+  session_.set_authorized(false);
+
+  EXPECT_CALL(*connection_, SendControlFrame(_));
+  EXPECT_CALL(*connection_,
+              OnStreamReset(promise_id_, QUIC_UNAUTHORIZED_PROMISE_URL));
+
+  ReceivePromise(promise_id_);
+
+  QuicClientPromisedInfo* promised = session_.GetPromisedById(promise_id_);
+  ASSERT_EQ(promised, nullptr);
+}
+
+TEST_F(QuicClientPromisedInfoTest, PushPromiseMismatch) {
+  ReceivePromise(promise_id_);
+
+  QuicClientPromisedInfo* promised = session_.GetPromisedById(promise_id_);
+  ASSERT_NE(promised, nullptr);
+
+  // Need to send the promised response headers and initiate the
+  // rendezvous for secondary validation to proceed.
+  QuicSpdyClientStream* promise_stream = static_cast<QuicSpdyClientStream*>(
+      session_.GetOrCreateStream(promise_id_));
+  auto headers = AsHeaderList(headers_);
+  promise_stream->OnStreamHeaderList(false, headers.uncompressed_header_bytes(),
+                                     headers);
+
+  TestPushPromiseDelegate delegate(/*match=*/false);
+  EXPECT_CALL(*connection_, SendControlFrame(_));
+  EXPECT_CALL(*connection_,
+              OnStreamReset(promise_id_, QUIC_PROMISE_VARY_MISMATCH));
+  EXPECT_CALL(session_, CloseStream(promise_id_));
+
+  promised->HandleClientRequest(client_request_, &delegate);
+}
+
+TEST_F(QuicClientPromisedInfoTest, PushPromiseVaryWaits) {
+  ReceivePromise(promise_id_);
+
+  QuicClientPromisedInfo* promised = session_.GetPromisedById(promise_id_);
+  EXPECT_FALSE(promised->is_validating());
+  ASSERT_NE(promised, nullptr);
+
+  // Now initiate rendezvous.
+  TestPushPromiseDelegate delegate(/*match=*/true);
+  promised->HandleClientRequest(client_request_, &delegate);
+  EXPECT_TRUE(promised->is_validating());
+
+  // Promise is still there, waiting for response.
+  EXPECT_NE(session_.GetPromisedById(promise_id_), nullptr);
+
+  // Send Response, should trigger promise validation and complete rendezvous
+  QuicSpdyClientStream* promise_stream = static_cast<QuicSpdyClientStream*>(
+      session_.GetOrCreateStream(promise_id_));
+  ASSERT_NE(promise_stream, nullptr);
+  auto headers = AsHeaderList(headers_);
+  promise_stream->OnStreamHeaderList(false, headers.uncompressed_header_bytes(),
+                                     headers);
+
+  // Promise is gone
+  EXPECT_EQ(session_.GetPromisedById(promise_id_), nullptr);
+}
+
+TEST_F(QuicClientPromisedInfoTest, PushPromiseVaryNoWait) {
+  ReceivePromise(promise_id_);
+
+  QuicClientPromisedInfo* promised = session_.GetPromisedById(promise_id_);
+  ASSERT_NE(promised, nullptr);
+
+  QuicSpdyClientStream* promise_stream = static_cast<QuicSpdyClientStream*>(
+      session_.GetOrCreateStream(promise_id_));
+  ASSERT_NE(promise_stream, nullptr);
+
+  // Send Response, should trigger promise validation and complete rendezvous
+  auto headers = AsHeaderList(headers_);
+  promise_stream->OnStreamHeaderList(false, headers.uncompressed_header_bytes(),
+                                     headers);
+
+  // Now initiate rendezvous.
+  TestPushPromiseDelegate delegate(/*match=*/true);
+  promised->HandleClientRequest(client_request_, &delegate);
+
+  // Promise is gone
+  EXPECT_EQ(session_.GetPromisedById(promise_id_), nullptr);
+  // Have a push stream
+  EXPECT_TRUE(delegate.rendezvous_fired());
+
+  EXPECT_NE(delegate.rendezvous_stream(), nullptr);
+}
+
+TEST_F(QuicClientPromisedInfoTest, PushPromiseWaitCancels) {
+  ReceivePromise(promise_id_);
+
+  QuicClientPromisedInfo* promised = session_.GetPromisedById(promise_id_);
+  ASSERT_NE(promised, nullptr);
+
+  // Now initiate rendezvous.
+  TestPushPromiseDelegate delegate(/*match=*/true);
+  promised->HandleClientRequest(client_request_, &delegate);
+
+  // Promise is still there, waiting for response.
+  EXPECT_NE(session_.GetPromisedById(promise_id_), nullptr);
+
+  // Create response stream, but no data yet.
+  session_.GetOrCreateStream(promise_id_);
+
+  // Cancel the promised stream.
+  EXPECT_CALL(session_, CloseStream(promise_id_));
+  EXPECT_CALL(*connection_, SendControlFrame(_));
+  EXPECT_CALL(*connection_, OnStreamReset(promise_id_, QUIC_STREAM_CANCELLED));
+  promised->Cancel();
+
+  // Promise is gone
+  EXPECT_EQ(session_.GetPromisedById(promise_id_), nullptr);
+}
+
+TEST_F(QuicClientPromisedInfoTest, PushPromiseDataClosed) {
+  ReceivePromise(promise_id_);
+
+  QuicClientPromisedInfo* promised = session_.GetPromisedById(promise_id_);
+  ASSERT_NE(promised, nullptr);
+
+  QuicSpdyClientStream* promise_stream = static_cast<QuicSpdyClientStream*>(
+      session_.GetOrCreateStream(promise_id_));
+  ASSERT_NE(promise_stream, nullptr);
+
+  // Send response, rendezvous will be able to finish synchronously.
+  auto headers = AsHeaderList(headers_);
+  promise_stream->OnStreamHeaderList(false, headers.uncompressed_header_bytes(),
+                                     headers);
+
+  EXPECT_CALL(session_, CloseStream(promise_id_));
+  EXPECT_CALL(*connection_, SendControlFrame(_));
+  EXPECT_CALL(*connection_,
+              OnStreamReset(promise_id_, QUIC_STREAM_PEER_GOING_AWAY));
+  session_.SendRstStream(promise_id_, QUIC_STREAM_PEER_GOING_AWAY, 0);
+
+  // Now initiate rendezvous.
+  TestPushPromiseDelegate delegate(/*match=*/true);
+  EXPECT_EQ(promised->HandleClientRequest(client_request_, &delegate),
+            QUIC_FAILURE);
+
+  // Got an indication of the stream failure, client should retry
+  // request.
+  EXPECT_FALSE(delegate.rendezvous_fired());
+  EXPECT_EQ(delegate.rendezvous_stream(), nullptr);
+
+  // Promise is gone
+  EXPECT_EQ(session_.GetPromisedById(promise_id_), nullptr);
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quic/core/http/quic_client_push_promise_index.cc b/quic/core/http/quic_client_push_promise_index.cc
new file mode 100644
index 0000000..2ba5951
--- /dev/null
+++ b/quic/core/http/quic_client_push_promise_index.cc
@@ -0,0 +1,47 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/third_party/quiche/src/quic/core/http/quic_client_push_promise_index.h"
+
+#include "net/third_party/quiche/src/quic/core/http/quic_client_promised_info.h"
+#include "net/third_party/quiche/src/quic/core/http/spdy_utils.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_string.h"
+
+using spdy::SpdyHeaderBlock;
+
+namespace quic {
+
+QuicClientPushPromiseIndex::QuicClientPushPromiseIndex() {}
+
+QuicClientPushPromiseIndex::~QuicClientPushPromiseIndex() {}
+
+QuicClientPushPromiseIndex::TryHandle::~TryHandle() {}
+
+QuicClientPromisedInfo* QuicClientPushPromiseIndex::GetPromised(
+    const QuicString& url) {
+  auto it = promised_by_url_.find(url);
+  if (it == promised_by_url_.end()) {
+    return nullptr;
+  }
+  return it->second;
+}
+
+QuicAsyncStatus QuicClientPushPromiseIndex::Try(
+    const spdy::SpdyHeaderBlock& request,
+    QuicClientPushPromiseIndex::Delegate* delegate,
+    TryHandle** handle) {
+  QuicString url(SpdyUtils::GetPromisedUrlFromHeaders(request));
+  auto it = promised_by_url_.find(url);
+  if (it != promised_by_url_.end()) {
+    QuicClientPromisedInfo* promised = it->second;
+    QuicAsyncStatus rv = promised->HandleClientRequest(request, delegate);
+    if (rv == QUIC_PENDING) {
+      *handle = promised;
+    }
+    return rv;
+  }
+  return QUIC_FAILURE;
+}
+
+}  // namespace quic
diff --git a/quic/core/http/quic_client_push_promise_index.h b/quic/core/http/quic_client_push_promise_index.h
new file mode 100644
index 0000000..5dd29b4
--- /dev/null
+++ b/quic/core/http/quic_client_push_promise_index.h
@@ -0,0 +1,98 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_HTTP_QUIC_CLIENT_PUSH_PROMISE_INDEX_H_
+#define QUICHE_QUIC_CORE_HTTP_QUIC_CLIENT_PUSH_PROMISE_INDEX_H_
+
+#include "net/third_party/quiche/src/quic/core/http/quic_spdy_client_session_base.h"
+#include "net/third_party/quiche/src/quic/core/quic_types.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_export.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_string.h"
+
+namespace quic {
+
+// QuicClientPushPromiseIndex is the interface to support rendezvous
+// between client requests and resources delivered via server push.
+// The same index can be shared across multiple sessions (e.g. for the
+// same browser users profile), since cross-origin pushes are allowed
+// (subject to authority constraints).
+
+class QUIC_EXPORT_PRIVATE QuicClientPushPromiseIndex {
+ public:
+  // Delegate is used to complete the rendezvous that began with
+  // |Try()|.
+  class QUIC_EXPORT_PRIVATE Delegate {
+   public:
+    virtual ~Delegate() {}
+
+    // The primary lookup matched request with push promise by URL.  A
+    // secondary match is necessary to ensure Vary (RFC 2616, 14.14)
+    // is honored.  If Vary is not present, return true.  If Vary is
+    // present, return whether designated header fields of
+    // |promise_request| and |client_request| match.
+    virtual bool CheckVary(const spdy::SpdyHeaderBlock& client_request,
+                           const spdy::SpdyHeaderBlock& promise_request,
+                           const spdy::SpdyHeaderBlock& promise_response) = 0;
+
+    // On rendezvous success, provides the promised |stream|.  Callee
+    // does not inherit ownership of |stream|.  On rendezvous failure,
+    // |stream| is |nullptr| and the client should retry the request.
+    // Rendezvous can fail due to promise validation failure or RST on
+    // promised stream.  |url| will have been removed from the index
+    // before |OnRendezvousResult()| is invoked, so a recursive call to
+    // |Try()| will return |QUIC_FAILURE|, which may be convenient for
+    // retry purposes.
+    virtual void OnRendezvousResult(QuicSpdyStream* stream) = 0;
+  };
+
+  class QUIC_EXPORT_PRIVATE TryHandle {
+   public:
+    // Cancel the request.
+    virtual void Cancel() = 0;
+
+   protected:
+    TryHandle() {}
+    TryHandle(const TryHandle&) = delete;
+    TryHandle& operator=(const TryHandle&) = delete;
+    ~TryHandle();
+  };
+
+  QuicClientPushPromiseIndex();
+  QuicClientPushPromiseIndex(const QuicClientPushPromiseIndex&) = delete;
+  QuicClientPushPromiseIndex& operator=(const QuicClientPushPromiseIndex&) =
+      delete;
+  virtual ~QuicClientPushPromiseIndex();
+
+  // Called by client code, used to enforce affinity between requests
+  // for promised streams and the session the promise came from.
+  QuicClientPromisedInfo* GetPromised(const QuicString& url);
+
+  // Called by client code, to initiate rendezvous between a request
+  // and a server push stream.  If |request|'s url is in the index,
+  // rendezvous will be attempted and may complete immediately or
+  // asynchronously.  If the matching promise and response headers
+  // have already arrived, the delegate's methods will fire
+  // recursively from within |Try()|.  Returns |QUIC_SUCCESS| if the
+  // rendezvous was a success. Returns |QUIC_FAILURE| if there was no
+  // matching promise, or if there was but the rendezvous has failed.
+  // Returns QUIC_PENDING if a matching promise was found, but the
+  // rendezvous needs to complete asynchronously because the promised
+  // response headers are not yet available.  If result is
+  // QUIC_PENDING, then |*handle| will set so that the caller may
+  // cancel the request if need be.  The caller does not inherit
+  // ownership of |*handle|, and it ceases to be valid if the caller
+  // invokes |handle->Cancel()| or if |delegate->OnReponse()| fires.
+  QuicAsyncStatus Try(const spdy::SpdyHeaderBlock& request,
+                      Delegate* delegate,
+                      TryHandle** handle);
+
+  QuicPromisedByUrlMap* promised_by_url() { return &promised_by_url_; }
+
+ private:
+  QuicPromisedByUrlMap promised_by_url_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_HTTP_QUIC_CLIENT_PUSH_PROMISE_INDEX_H_
diff --git a/quic/core/http/quic_client_push_promise_index_test.cc b/quic/core/http/quic_client_push_promise_index_test.cc
new file mode 100644
index 0000000..b68b41f
--- /dev/null
+++ b/quic/core/http/quic_client_push_promise_index_test.cc
@@ -0,0 +1,117 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/third_party/quiche/src/quic/core/http/quic_client_push_promise_index.h"
+
+#include "net/third_party/quiche/src/quic/core/http/quic_spdy_client_session.h"
+#include "net/third_party/quiche/src/quic/core/http/spdy_utils.h"
+#include "net/third_party/quiche/src/quic/core/tls_client_handshaker.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_string.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_test.h"
+#include "net/third_party/quiche/src/quic/test_tools/crypto_test_utils.h"
+#include "net/third_party/quiche/src/quic/test_tools/mock_quic_client_promised_info.h"
+#include "net/third_party/quiche/src/quic/test_tools/quic_spdy_session_peer.h"
+#include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h"
+
+using testing::_;
+using testing::Return;
+using testing::StrictMock;
+
+namespace quic {
+namespace test {
+namespace {
+
+class MockQuicSpdyClientSession : public QuicSpdyClientSession {
+ public:
+  explicit MockQuicSpdyClientSession(
+      const ParsedQuicVersionVector& supported_versions,
+      QuicConnection* connection,
+      QuicClientPushPromiseIndex* push_promise_index)
+      : QuicSpdyClientSession(DefaultQuicConfig(),
+                              supported_versions,
+                              connection,
+                              QuicServerId("example.com", 443, false),
+                              &crypto_config_,
+                              push_promise_index),
+        crypto_config_(crypto_test_utils::ProofVerifierForTesting(),
+                       TlsClientHandshaker::CreateSslCtx()) {}
+  MockQuicSpdyClientSession(const MockQuicSpdyClientSession&) = delete;
+  MockQuicSpdyClientSession& operator=(const MockQuicSpdyClientSession&) =
+      delete;
+  ~MockQuicSpdyClientSession() override {}
+
+  MOCK_METHOD1(CloseStream, void(QuicStreamId stream_id));
+
+ private:
+  QuicCryptoClientConfig crypto_config_;
+};
+
+class QuicClientPushPromiseIndexTest : public QuicTest {
+ public:
+  QuicClientPushPromiseIndexTest()
+      : connection_(new StrictMock<MockQuicConnection>(&helper_,
+                                                       &alarm_factory_,
+                                                       Perspective::IS_CLIENT)),
+        session_(connection_->supported_versions(), connection_, &index_),
+        promised_(&session_,
+                  GetNthServerInitiatedUnidirectionalStreamId(
+                      connection_->transport_version(),
+                      0),
+                  url_) {
+    request_[":path"] = "/bar";
+    request_[":authority"] = "www.google.com";
+    request_[":version"] = "HTTP/1.1";
+    request_[":method"] = "GET";
+    request_[":scheme"] = "https";
+    url_ = SpdyUtils::GetPromisedUrlFromHeaders(request_);
+  }
+
+  MockQuicConnectionHelper helper_;
+  MockAlarmFactory alarm_factory_;
+  StrictMock<MockQuicConnection>* connection_;
+  MockQuicSpdyClientSession session_;
+  QuicClientPushPromiseIndex index_;
+  spdy::SpdyHeaderBlock request_;
+  QuicString url_;
+  MockQuicClientPromisedInfo promised_;
+  QuicClientPushPromiseIndex::TryHandle* handle_;
+};
+
+TEST_F(QuicClientPushPromiseIndexTest, TryRequestSuccess) {
+  (*index_.promised_by_url())[url_] = &promised_;
+  EXPECT_CALL(promised_, HandleClientRequest(_, _))
+      .WillOnce(Return(QUIC_SUCCESS));
+  EXPECT_EQ(index_.Try(request_, nullptr, &handle_), QUIC_SUCCESS);
+}
+
+TEST_F(QuicClientPushPromiseIndexTest, TryRequestPending) {
+  (*index_.promised_by_url())[url_] = &promised_;
+  EXPECT_CALL(promised_, HandleClientRequest(_, _))
+      .WillOnce(Return(QUIC_PENDING));
+  EXPECT_EQ(index_.Try(request_, nullptr, &handle_), QUIC_PENDING);
+}
+
+TEST_F(QuicClientPushPromiseIndexTest, TryRequestFailure) {
+  (*index_.promised_by_url())[url_] = &promised_;
+  EXPECT_CALL(promised_, HandleClientRequest(_, _))
+      .WillOnce(Return(QUIC_FAILURE));
+  EXPECT_EQ(index_.Try(request_, nullptr, &handle_), QUIC_FAILURE);
+}
+
+TEST_F(QuicClientPushPromiseIndexTest, TryNoPromise) {
+  EXPECT_EQ(index_.Try(request_, nullptr, &handle_), QUIC_FAILURE);
+}
+
+TEST_F(QuicClientPushPromiseIndexTest, GetNoPromise) {
+  EXPECT_EQ(index_.GetPromised(url_), nullptr);
+}
+
+TEST_F(QuicClientPushPromiseIndexTest, GetPromise) {
+  (*index_.promised_by_url())[url_] = &promised_;
+  EXPECT_EQ(index_.GetPromised(url_), &promised_);
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quic/core/http/quic_header_list.cc b/quic/core/http/quic_header_list.cc
new file mode 100644
index 0000000..cb10248
--- /dev/null
+++ b/quic/core/http/quic_header_list.cc
@@ -0,0 +1,72 @@
+// Copyright (c) 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/third_party/quiche/src/quic/core/http/quic_header_list.h"
+
+#include "net/third_party/quiche/src/quic/core/quic_packets.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_flags.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_string.h"
+#include "net/third_party/quiche/src/spdy/core/spdy_protocol.h"
+
+namespace quic {
+
+QuicHeaderList::QuicHeaderList()
+    : max_header_list_size_(kDefaultMaxUncompressedHeaderSize),
+      current_header_list_size_(0),
+      uncompressed_header_bytes_(0),
+      compressed_header_bytes_(0) {}
+
+QuicHeaderList::QuicHeaderList(QuicHeaderList&& other) = default;
+
+QuicHeaderList::QuicHeaderList(const QuicHeaderList& other) = default;
+
+QuicHeaderList& QuicHeaderList::operator=(const QuicHeaderList& other) =
+    default;
+
+QuicHeaderList& QuicHeaderList::operator=(QuicHeaderList&& other) = default;
+
+QuicHeaderList::~QuicHeaderList() {}
+
+void QuicHeaderList::OnHeaderBlockStart() {
+  QUIC_BUG_IF(current_header_list_size_ != 0)
+      << "OnHeaderBlockStart called more than once!";
+}
+
+void QuicHeaderList::OnHeader(QuicStringPiece name, QuicStringPiece value) {
+  // Avoid infinite buffering of headers. No longer store headers
+  // once the current headers are over the limit.
+  if (current_header_list_size_ < max_header_list_size_) {
+    current_header_list_size_ += name.size();
+    current_header_list_size_ += value.size();
+    current_header_list_size_ += spdy::kPerHeaderOverhead;
+    header_list_.emplace_back(QuicString(name), QuicString(value));
+  }
+}
+
+void QuicHeaderList::OnHeaderBlockEnd(size_t uncompressed_header_bytes,
+                                      size_t compressed_header_bytes) {
+  uncompressed_header_bytes_ = uncompressed_header_bytes;
+  compressed_header_bytes_ = compressed_header_bytes;
+  if (current_header_list_size_ > max_header_list_size_) {
+    Clear();
+  }
+}
+
+void QuicHeaderList::Clear() {
+  header_list_.clear();
+  current_header_list_size_ = 0;
+  uncompressed_header_bytes_ = 0;
+  compressed_header_bytes_ = 0;
+}
+
+QuicString QuicHeaderList::DebugString() const {
+  QuicString s = "{ ";
+  for (const auto& p : *this) {
+    s.append(p.first + "=" + p.second + ", ");
+  }
+  s.append("}");
+  return s;
+}
+
+}  // namespace quic
diff --git a/quic/core/http/quic_header_list.h b/quic/core/http/quic_header_list.h
new file mode 100644
index 0000000..c7b4c80
--- /dev/null
+++ b/quic/core/http/quic_header_list.h
@@ -0,0 +1,88 @@
+// Copyright (c) 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_HTTP_QUIC_HEADER_LIST_H_
+#define QUICHE_QUIC_CORE_HTTP_QUIC_HEADER_LIST_H_
+
+#include <algorithm>
+#include <functional>
+#include <utility>
+
+#include "net/third_party/quiche/src/quic/platform/api/quic_bug_tracker.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_containers.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_export.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_string.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_string_piece.h"
+#include "net/third_party/quiche/src/spdy/core/spdy_header_block.h"
+#include "net/third_party/quiche/src/spdy/core/spdy_headers_handler_interface.h"
+
+namespace quic {
+
+// A simple class that accumulates header pairs
+class QUIC_EXPORT_PRIVATE QuicHeaderList
+    : public spdy::SpdyHeadersHandlerInterface {
+ public:
+  typedef QuicDeque<std::pair<QuicString, QuicString>> ListType;
+  typedef ListType::const_iterator const_iterator;
+
+  QuicHeaderList();
+  QuicHeaderList(QuicHeaderList&& other);
+  QuicHeaderList(const QuicHeaderList& other);
+  QuicHeaderList& operator=(QuicHeaderList&& other);
+  QuicHeaderList& operator=(const QuicHeaderList& other);
+  ~QuicHeaderList() override;
+
+  // From SpdyHeadersHandlerInteface.
+  void OnHeaderBlockStart() override;
+  void OnHeader(QuicStringPiece name, QuicStringPiece value) override;
+  void OnHeaderBlockEnd(size_t uncompressed_header_bytes,
+                        size_t compressed_header_bytes) override;
+
+  void Clear();
+
+  const_iterator begin() const { return header_list_.begin(); }
+  const_iterator end() const { return header_list_.end(); }
+
+  bool empty() const { return header_list_.empty(); }
+  size_t uncompressed_header_bytes() const {
+    return uncompressed_header_bytes_;
+  }
+  size_t compressed_header_bytes() const { return compressed_header_bytes_; }
+
+  void set_max_header_list_size(size_t max_header_list_size) {
+    max_header_list_size_ = max_header_list_size;
+  }
+
+  size_t max_header_list_size() const { return max_header_list_size_; }
+
+  QuicString DebugString() const;
+
+ private:
+  QuicDeque<std::pair<QuicString, QuicString>> header_list_;
+
+  // The limit on the size of the header list (defined by spec as name + value +
+  // overhead for each header field). Headers over this limit will not be
+  // buffered, and the list will be cleared upon OnHeaderBlockEnd.
+  size_t max_header_list_size_;
+
+  // Defined per the spec as the size of all header fields with an additional
+  // overhead for each field.
+  size_t current_header_list_size_;
+
+  // TODO(dahollings) Are these fields necessary?
+  size_t uncompressed_header_bytes_;
+  size_t compressed_header_bytes_;
+};
+
+inline bool operator==(const QuicHeaderList& l1, const QuicHeaderList& l2) {
+  auto pred = [](const std::pair<QuicString, QuicString>& p1,
+                 const std::pair<QuicString, QuicString>& p2) {
+    return p1.first == p2.first && p1.second == p2.second;
+  };
+  return std::equal(l1.begin(), l1.end(), l2.begin(), pred);
+}
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_HTTP_QUIC_HEADER_LIST_H_
diff --git a/quic/core/http/quic_header_list_test.cc b/quic/core/http/quic_header_list_test.cc
new file mode 100644
index 0000000..1b2a394
--- /dev/null
+++ b/quic/core/http/quic_header_list_test.cc
@@ -0,0 +1,67 @@
+// Copyright (c) 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/third_party/quiche/src/quic/core/http/quic_header_list.h"
+
+#include "net/third_party/quiche/src/quic/platform/api/quic_flags.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_string.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_test.h"
+
+namespace quic {
+
+class QuicHeaderListTest : public QuicTest {};
+
+// This test verifies that QuicHeaderList accumulates header pairs in order.
+TEST_F(QuicHeaderListTest, OnHeader) {
+  QuicHeaderList headers;
+  headers.OnHeader("foo", "bar");
+  headers.OnHeader("april", "fools");
+  headers.OnHeader("beep", "");
+
+  EXPECT_EQ("{ foo=bar, april=fools, beep=, }", headers.DebugString());
+}
+
+TEST_F(QuicHeaderListTest, TooLarge) {
+  QuicHeaderList headers;
+  QuicString key = "key";
+  QuicString value(1 << 18, '1');
+  // Send a header that exceeds max_header_list_size.
+  headers.OnHeader(key, value);
+  // Send a second header exceeding max_header_list_size.
+  headers.OnHeader(key + "2", value);
+  // We should not allocate more memory after exceeding max_header_list_size.
+  EXPECT_LT(headers.DebugString().size(), 2 * value.size());
+  size_t total_bytes = 2 * (key.size() + value.size()) + 1;
+  headers.OnHeaderBlockEnd(total_bytes, total_bytes);
+  EXPECT_TRUE(headers.empty());
+
+  EXPECT_EQ("{ }", headers.DebugString());
+}
+
+TEST_F(QuicHeaderListTest, NotTooLarge) {
+  QuicHeaderList headers;
+  headers.set_max_header_list_size(1 << 20);
+  QuicString key = "key";
+  QuicString value(1 << 18, '1');
+  headers.OnHeader(key, value);
+  size_t total_bytes = key.size() + value.size();
+  headers.OnHeaderBlockEnd(total_bytes, total_bytes);
+  EXPECT_FALSE(headers.empty());
+}
+
+// This test verifies that QuicHeaderList is copyable and assignable.
+TEST_F(QuicHeaderListTest, IsCopyableAndAssignable) {
+  QuicHeaderList headers;
+  headers.OnHeader("foo", "bar");
+  headers.OnHeader("april", "fools");
+  headers.OnHeader("beep", "");
+
+  QuicHeaderList headers2(headers);
+  QuicHeaderList headers3 = headers;
+
+  EXPECT_EQ("{ foo=bar, april=fools, beep=, }", headers2.DebugString());
+  EXPECT_EQ("{ foo=bar, april=fools, beep=, }", headers3.DebugString());
+}
+
+}  // namespace quic
diff --git a/quic/core/http/quic_headers_stream.cc b/quic/core/http/quic_headers_stream.cc
new file mode 100644
index 0000000..9c99ab7
--- /dev/null
+++ b/quic/core/http/quic_headers_stream.cc
@@ -0,0 +1,157 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/third_party/quiche/src/quic/core/http/quic_headers_stream.h"
+
+#include "net/third_party/quiche/src/quic/core/http/quic_spdy_session.h"
+#include "net/third_party/quiche/src/quic/core/quic_utils.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_arraysize.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_flag_utils.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_flags.h"
+
+namespace quic {
+
+QuicHeadersStream::CompressedHeaderInfo::CompressedHeaderInfo(
+    QuicStreamOffset headers_stream_offset,
+    QuicStreamOffset full_length,
+    QuicReferenceCountedPointer<QuicAckListenerInterface> ack_listener)
+    : headers_stream_offset(headers_stream_offset),
+      full_length(full_length),
+      unacked_length(full_length),
+      ack_listener(std::move(ack_listener)) {}
+
+QuicHeadersStream::CompressedHeaderInfo::CompressedHeaderInfo(
+    const CompressedHeaderInfo& other) = default;
+
+QuicHeadersStream::CompressedHeaderInfo::~CompressedHeaderInfo() {}
+
+QuicHeadersStream::QuicHeadersStream(QuicSpdySession* session)
+    : QuicStream(QuicUtils::GetHeadersStreamId(
+                     session->connection()->transport_version()),
+                 session,
+                 /*is_static=*/true,
+                 BIDIRECTIONAL),
+      spdy_session_(session) {
+  // The headers stream is exempt from connection level flow control.
+  DisableConnectionFlowControlForThisStream();
+}
+
+QuicHeadersStream::~QuicHeadersStream() {}
+
+void QuicHeadersStream::OnDataAvailable() {
+  struct iovec iov;
+  while (sequencer()->GetReadableRegion(&iov)) {
+    if (spdy_session_->ProcessHeaderData(iov) != iov.iov_len) {
+      // Error processing data.
+      return;
+    }
+    sequencer()->MarkConsumed(iov.iov_len);
+    MaybeReleaseSequencerBuffer();
+  }
+}
+
+void QuicHeadersStream::MaybeReleaseSequencerBuffer() {
+  if (spdy_session_->ShouldReleaseHeadersStreamSequencerBuffer()) {
+    sequencer()->ReleaseBufferIfEmpty();
+  }
+}
+
+bool QuicHeadersStream::OnStreamFrameAcked(QuicStreamOffset offset,
+                                           QuicByteCount data_length,
+                                           bool fin_acked,
+                                           QuicTime::Delta ack_delay_time,
+                                           QuicByteCount* newly_acked_length) {
+  QuicIntervalSet<QuicStreamOffset> newly_acked(offset, offset + data_length);
+  newly_acked.Difference(bytes_acked());
+  for (const auto& acked : newly_acked) {
+    QuicStreamOffset acked_offset = acked.min();
+    QuicByteCount acked_length = acked.max() - acked.min();
+    for (CompressedHeaderInfo& header : unacked_headers_) {
+      if (acked_offset < header.headers_stream_offset) {
+        // This header frame offset belongs to headers with smaller offset, stop
+        // processing.
+        break;
+      }
+
+      if (acked_offset >= header.headers_stream_offset + header.full_length) {
+        // This header frame belongs to headers with larger offset.
+        continue;
+      }
+
+      QuicByteCount header_offset = acked_offset - header.headers_stream_offset;
+      QuicByteCount header_length =
+          std::min(acked_length, header.full_length - header_offset);
+
+      if (header.unacked_length < header_length) {
+        QUIC_BUG << "Unsent stream data is acked. unacked_length: "
+                 << header.unacked_length << " acked_length: " << header_length;
+        CloseConnectionWithDetails(QUIC_INTERNAL_ERROR,
+                                   "Unsent stream data is acked");
+        return false;
+      }
+      if (header.ack_listener != nullptr && header_length > 0) {
+        header.ack_listener->OnPacketAcked(header_length, ack_delay_time);
+      }
+      header.unacked_length -= header_length;
+      acked_offset += header_length;
+      acked_length -= header_length;
+    }
+  }
+  // Remove headers which are fully acked. Please note, header frames can be
+  // acked out of order, but unacked_headers_ is cleaned up in order.
+  while (!unacked_headers_.empty() &&
+         unacked_headers_.front().unacked_length == 0) {
+    unacked_headers_.pop_front();
+  }
+  return QuicStream::OnStreamFrameAcked(offset, data_length, fin_acked,
+                                        ack_delay_time, newly_acked_length);
+}
+
+void QuicHeadersStream::OnStreamFrameRetransmitted(QuicStreamOffset offset,
+                                                   QuicByteCount data_length,
+                                                   bool /*fin_retransmitted*/) {
+  QuicStream::OnStreamFrameRetransmitted(offset, data_length, false);
+  for (CompressedHeaderInfo& header : unacked_headers_) {
+    if (offset < header.headers_stream_offset) {
+      // This header frame offset belongs to headers with smaller offset, stop
+      // processing.
+      break;
+    }
+
+    if (offset >= header.headers_stream_offset + header.full_length) {
+      // This header frame belongs to headers with larger offset.
+      continue;
+    }
+
+    QuicByteCount header_offset = offset - header.headers_stream_offset;
+    QuicByteCount retransmitted_length =
+        std::min(data_length, header.full_length - header_offset);
+    if (header.ack_listener != nullptr && retransmitted_length > 0) {
+      header.ack_listener->OnPacketRetransmitted(retransmitted_length);
+    }
+    offset += retransmitted_length;
+    data_length -= retransmitted_length;
+  }
+}
+
+void QuicHeadersStream::OnDataBuffered(
+    QuicStreamOffset offset,
+    QuicByteCount data_length,
+    const QuicReferenceCountedPointer<QuicAckListenerInterface>& ack_listener) {
+  // Populate unacked_headers_.
+  if (!unacked_headers_.empty() &&
+      (offset == unacked_headers_.back().headers_stream_offset +
+                     unacked_headers_.back().full_length) &&
+      ack_listener == unacked_headers_.back().ack_listener) {
+    // Try to combine with latest inserted entry if they belong to the same
+    // header (i.e., having contiguous offset and the same ack listener).
+    unacked_headers_.back().full_length += data_length;
+    unacked_headers_.back().unacked_length += data_length;
+  } else {
+    unacked_headers_.push_back(
+        CompressedHeaderInfo(offset, data_length, ack_listener));
+  }
+}
+
+}  // namespace quic
diff --git a/quic/core/http/quic_headers_stream.h b/quic/core/http/quic_headers_stream.h
new file mode 100644
index 0000000..abc0aeb
--- /dev/null
+++ b/quic/core/http/quic_headers_stream.h
@@ -0,0 +1,97 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_HTTP_QUIC_HEADERS_STREAM_H_
+#define QUICHE_QUIC_CORE_HTTP_QUIC_HEADERS_STREAM_H_
+
+#include <cstddef>
+#include <memory>
+
+#include "base/macros.h"
+#include "net/third_party/quiche/src/quic/core/http/quic_header_list.h"
+#include "net/third_party/quiche/src/quic/core/quic_packets.h"
+#include "net/third_party/quiche/src/quic/core/quic_stream.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_containers.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_export.h"
+#include "net/third_party/quiche/src/spdy/core/spdy_framer.h"
+
+namespace quic {
+
+class QuicSpdySession;
+
+namespace test {
+class QuicHeadersStreamPeer;
+}  // namespace test
+
+// Headers in QUIC are sent as HTTP/2 HEADERS or PUSH_PROMISE frames over a
+// reserved stream with the id 3.  Each endpoint (client and server) will
+// allocate an instance of QuicHeadersStream to send and receive headers.
+class QUIC_EXPORT_PRIVATE QuicHeadersStream : public QuicStream {
+ public:
+  explicit QuicHeadersStream(QuicSpdySession* session);
+  QuicHeadersStream(const QuicHeadersStream&) = delete;
+  QuicHeadersStream& operator=(const QuicHeadersStream&) = delete;
+  ~QuicHeadersStream() override;
+
+  // QuicStream implementation
+  void OnDataAvailable() override;
+
+  // Release underlying buffer if allowed.
+  void MaybeReleaseSequencerBuffer();
+
+  bool OnStreamFrameAcked(QuicStreamOffset offset,
+                          QuicByteCount data_length,
+                          bool fin_acked,
+                          QuicTime::Delta ack_delay_time,
+                          QuicByteCount* newly_acked_length) override;
+
+  void OnStreamFrameRetransmitted(QuicStreamOffset offset,
+                                  QuicByteCount data_length,
+                                  bool fin_retransmitted) override;
+
+ private:
+  friend class test::QuicHeadersStreamPeer;
+
+  // CompressedHeaderInfo includes simple information of a header, including
+  // offset in headers stream, unacked length and ack listener of this header.
+  struct QUIC_EXPORT_PRIVATE CompressedHeaderInfo {
+    CompressedHeaderInfo(
+        QuicStreamOffset headers_stream_offset,
+        QuicStreamOffset full_length,
+        QuicReferenceCountedPointer<QuicAckListenerInterface> ack_listener);
+    CompressedHeaderInfo(const CompressedHeaderInfo& other);
+    ~CompressedHeaderInfo();
+
+    // Offset the header was sent on the headers stream.
+    QuicStreamOffset headers_stream_offset;
+    // The full length of the header.
+    QuicByteCount full_length;
+    // The remaining bytes to be acked.
+    QuicByteCount unacked_length;
+    // Ack listener of this header, and it is notified once any of the bytes has
+    // been acked or retransmitted.
+    QuicReferenceCountedPointer<QuicAckListenerInterface> ack_listener;
+  };
+
+  // Returns true if the session is still connected.
+  bool IsConnected();
+
+  // Override to store mapping from offset, length to ack_listener. This
+  // ack_listener is notified once data within [offset, offset + length] is
+  // acked or retransmitted.
+  void OnDataBuffered(
+      QuicStreamOffset offset,
+      QuicByteCount data_length,
+      const QuicReferenceCountedPointer<QuicAckListenerInterface>& ack_listener)
+      override;
+
+  QuicSpdySession* spdy_session_;
+
+  // Headers that have not been fully acked.
+  QuicDeque<CompressedHeaderInfo> unacked_headers_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_HTTP_QUIC_HEADERS_STREAM_H_
diff --git a/quic/core/http/quic_headers_stream_test.cc b/quic/core/http/quic_headers_stream_test.cc
new file mode 100644
index 0000000..b6409b1
--- /dev/null
+++ b/quic/core/http/quic_headers_stream_test.cc
@@ -0,0 +1,968 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/third_party/quiche/src/quic/core/http/quic_headers_stream.h"
+
+#include <cstdint>
+#include <ostream>
+#include <tuple>
+#include <utility>
+#include <vector>
+
+#include "net/third_party/quiche/src/quic/core/http/spdy_utils.h"
+#include "net/third_party/quiche/src/quic/core/quic_data_writer.h"
+#include "net/third_party/quiche/src/quic/core/quic_utils.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_bug_tracker.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_expect_bug.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_flags.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_logging.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_ptr_util.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_str_cat.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_string.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_string_piece.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_test.h"
+#include "net/third_party/quiche/src/quic/test_tools/quic_connection_peer.h"
+#include "net/third_party/quiche/src/quic/test_tools/quic_spdy_session_peer.h"
+#include "net/third_party/quiche/src/quic/test_tools/quic_stream_peer.h"
+#include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h"
+#include "net/third_party/quiche/src/spdy/core/http2_frame_decoder_adapter.h"
+#include "net/third_party/quiche/src/spdy/core/spdy_alt_svc_wire_format.h"
+#include "net/third_party/quiche/src/spdy/core/spdy_protocol.h"
+#include "net/third_party/quiche/src/spdy/core/spdy_test_utils.h"
+
+using spdy::ERROR_CODE_PROTOCOL_ERROR;
+using spdy::SETTINGS_ENABLE_PUSH;
+using spdy::SETTINGS_HEADER_TABLE_SIZE;
+using spdy::SETTINGS_INITIAL_WINDOW_SIZE;
+using spdy::SETTINGS_MAX_CONCURRENT_STREAMS;
+using spdy::SETTINGS_MAX_FRAME_SIZE;
+using spdy::SETTINGS_MAX_HEADER_LIST_SIZE;
+using spdy::Spdy3PriorityToHttp2Weight;
+using spdy::SpdyAltSvcWireFormat;
+using spdy::SpdyDataIR;
+using spdy::SpdyErrorCode;
+using spdy::SpdyFramer;
+using spdy::SpdyFramerVisitorInterface;
+using spdy::SpdyGoAwayIR;
+using spdy::SpdyHeaderBlock;
+using spdy::SpdyHeadersHandlerInterface;
+using spdy::SpdyHeadersIR;
+using spdy::SpdyKnownSettingsId;
+using spdy::SpdyPingId;
+using spdy::SpdyPingIR;
+using spdy::SpdyPriority;
+using spdy::SpdyPriorityIR;
+using spdy::SpdyPushPromiseIR;
+using spdy::SpdyRstStreamIR;
+using spdy::SpdySerializedFrame;
+using spdy::SpdySettingsId;
+using spdy::SpdySettingsIR;
+using spdy::SpdyStreamId;
+using spdy::SpdyWindowUpdateIR;
+using spdy::test::TestHeadersHandler;
+using testing::_;
+using testing::AtLeast;
+using testing::InSequence;
+using testing::Invoke;
+using testing::Return;
+using testing::StrictMock;
+using testing::WithArgs;
+
+namespace quic {
+namespace test {
+
+class MockQuicHpackDebugVisitor : public QuicHpackDebugVisitor {
+ public:
+  MockQuicHpackDebugVisitor() : QuicHpackDebugVisitor() {}
+  MockQuicHpackDebugVisitor(const MockQuicHpackDebugVisitor&) = delete;
+  MockQuicHpackDebugVisitor& operator=(const MockQuicHpackDebugVisitor&) =
+      delete;
+
+  MOCK_METHOD1(OnUseEntry, void(QuicTime::Delta elapsed));
+};
+
+namespace {
+
+class MockVisitor : public SpdyFramerVisitorInterface {
+ public:
+  MOCK_METHOD1(OnError,
+               void(http2::Http2DecoderAdapter::SpdyFramerError error));
+  MOCK_METHOD3(OnDataFrameHeader,
+               void(SpdyStreamId stream_id, size_t length, bool fin));
+  MOCK_METHOD3(OnStreamFrameData,
+               void(SpdyStreamId stream_id, const char* data, size_t len));
+  MOCK_METHOD1(OnStreamEnd, void(SpdyStreamId stream_id));
+  MOCK_METHOD2(OnStreamPadding, void(SpdyStreamId stream_id, size_t len));
+  MOCK_METHOD1(OnHeaderFrameStart,
+               SpdyHeadersHandlerInterface*(SpdyStreamId stream_id));
+  MOCK_METHOD1(OnHeaderFrameEnd, void(SpdyStreamId stream_id));
+  MOCK_METHOD3(OnControlFrameHeaderData,
+               bool(SpdyStreamId stream_id,
+                    const char* header_data,
+                    size_t len));
+  MOCK_METHOD2(OnRstStream,
+               void(SpdyStreamId stream_id, SpdyErrorCode error_code));
+  MOCK_METHOD0(OnSettings, void());
+  MOCK_METHOD2(OnSetting, void(SpdySettingsId id, uint32_t value));
+  MOCK_METHOD0(OnSettingsAck, void());
+  MOCK_METHOD0(OnSettingsEnd, void());
+  MOCK_METHOD2(OnPing, void(SpdyPingId unique_id, bool is_ack));
+  MOCK_METHOD2(OnGoAway,
+               void(SpdyStreamId last_accepted_stream_id,
+                    SpdyErrorCode error_code));
+  MOCK_METHOD7(OnHeaders,
+               void(SpdyStreamId stream_id,
+                    bool has_priority,
+                    int weight,
+                    SpdyStreamId parent_stream_id,
+                    bool exclusive,
+                    bool fin,
+                    bool end));
+  MOCK_METHOD2(OnWindowUpdate,
+               void(SpdyStreamId stream_id, int delta_window_size));
+  MOCK_METHOD1(OnBlocked, void(SpdyStreamId stream_id));
+  MOCK_METHOD3(OnPushPromise,
+               void(SpdyStreamId stream_id,
+                    SpdyStreamId promised_stream_id,
+                    bool end));
+  MOCK_METHOD2(OnContinuation, void(SpdyStreamId stream_id, bool end));
+  MOCK_METHOD3(OnAltSvc,
+               void(SpdyStreamId stream_id,
+                    QuicStringPiece origin,
+                    const SpdyAltSvcWireFormat::AlternativeServiceVector&
+                        altsvc_vector));
+  MOCK_METHOD4(OnPriority,
+               void(SpdyStreamId stream_id,
+                    SpdyStreamId parent_stream_id,
+                    int weight,
+                    bool exclusive));
+  MOCK_METHOD2(OnUnknownFrame,
+               bool(SpdyStreamId stream_id, uint8_t frame_type));
+};
+
+struct TestParams {
+  TestParams(const ParsedQuicVersion& version, Perspective perspective)
+      : version(version), perspective(perspective) {
+    QUIC_LOG(INFO) << "TestParams: version: "
+                   << ParsedQuicVersionToString(version)
+                   << ", perspective: " << perspective;
+  }
+
+  TestParams(const TestParams& other)
+      : version(other.version), perspective(other.perspective) {}
+
+  ParsedQuicVersion version;
+  Perspective perspective;
+};
+
+std::vector<TestParams> GetTestParams() {
+  std::vector<TestParams> params;
+  ParsedQuicVersionVector all_supported_versions = AllSupportedVersions();
+  for (size_t i = 0; i < all_supported_versions.size(); ++i) {
+    for (Perspective p : {Perspective::IS_SERVER, Perspective::IS_CLIENT}) {
+      params.emplace_back(all_supported_versions[i], p);
+    }
+  }
+  return params;
+}
+
+class QuicHeadersStreamTest : public QuicTestWithParam<TestParams> {
+ public:
+  QuicHeadersStreamTest()
+      : connection_(new StrictMock<MockQuicConnection>(&helper_,
+                                                       &alarm_factory_,
+                                                       perspective(),
+                                                       GetVersion())),
+        session_(connection_),
+        body_("hello world"),
+        stream_frame_(
+            QuicUtils::GetHeadersStreamId(connection_->transport_version()),
+            /*fin=*/false,
+            /*offset=*/0,
+            ""),
+        next_promised_stream_id_(2) {
+    session_.Initialize();
+    headers_stream_ = QuicSpdySessionPeer::GetHeadersStream(&session_);
+    headers_[":version"] = "HTTP/1.1";
+    headers_[":status"] = "200 Ok";
+    headers_["content-length"] = "11";
+    framer_ = std::unique_ptr<SpdyFramer>(
+        new SpdyFramer(SpdyFramer::ENABLE_COMPRESSION));
+    deframer_ = std::unique_ptr<http2::Http2DecoderAdapter>(
+        new http2::Http2DecoderAdapter());
+    deframer_->set_visitor(&visitor_);
+    EXPECT_EQ(transport_version(), session_.connection()->transport_version());
+    EXPECT_TRUE(headers_stream_ != nullptr);
+    connection_->AdvanceTime(QuicTime::Delta::FromMilliseconds(1));
+    client_id_1_ = GetNthClientInitiatedBidirectionalStreamId(
+        connection_->transport_version(), 0);
+    client_id_2_ = GetNthClientInitiatedBidirectionalStreamId(
+        connection_->transport_version(), 1);
+    client_id_3_ = GetNthClientInitiatedBidirectionalStreamId(
+        connection_->transport_version(), 2);
+    next_stream_id_ =
+        QuicUtils::StreamIdDelta(connection_->transport_version());
+  }
+
+  QuicStreamId GetNthClientInitiatedId(int n) {
+    return GetNthClientInitiatedBidirectionalStreamId(
+        connection_->transport_version(), n);
+  }
+
+  QuicConsumedData SaveIov(size_t write_length) {
+    char* buf = new char[write_length];
+    QuicDataWriter writer(write_length, buf, NETWORK_BYTE_ORDER);
+    headers_stream_->WriteStreamData(headers_stream_->stream_bytes_written(),
+                                     write_length, &writer);
+    saved_data_.append(buf, write_length);
+    delete[] buf;
+    return QuicConsumedData(write_length, false);
+  }
+
+  void SavePayload(const char* data, size_t len) {
+    saved_payloads_.append(data, len);
+  }
+
+  bool SaveHeaderData(const char* data, int len) {
+    saved_header_data_.append(data, len);
+    return true;
+  }
+
+  void SaveHeaderDataStringPiece(QuicStringPiece data) {
+    saved_header_data_.append(data.data(), data.length());
+  }
+
+  void SavePromiseHeaderList(QuicStreamId /* stream_id */,
+                             QuicStreamId /* promised_stream_id */,
+                             size_t size,
+                             const QuicHeaderList& header_list) {
+    SaveToHandler(size, header_list);
+  }
+
+  void SaveHeaderList(QuicStreamId /* stream_id */,
+                      bool /* fin */,
+                      size_t size,
+                      const QuicHeaderList& header_list) {
+    SaveToHandler(size, header_list);
+  }
+
+  void SaveToHandler(size_t size, const QuicHeaderList& header_list) {
+    headers_handler_ = QuicMakeUnique<TestHeadersHandler>();
+    headers_handler_->OnHeaderBlockStart();
+    for (const auto& p : header_list) {
+      headers_handler_->OnHeader(p.first, p.second);
+    }
+    headers_handler_->OnHeaderBlockEnd(size, size);
+  }
+
+  void WriteAndExpectRequestHeaders(QuicStreamId stream_id,
+                                    bool fin,
+                                    SpdyPriority priority) {
+    WriteHeadersAndCheckData(stream_id, fin, priority, true /*is_request*/);
+  }
+
+  void WriteAndExpectResponseHeaders(QuicStreamId stream_id, bool fin) {
+    WriteHeadersAndCheckData(stream_id, fin, 0, false /*is_request*/);
+  }
+
+  void WriteHeadersAndCheckData(QuicStreamId stream_id,
+                                bool fin,
+                                SpdyPriority priority,
+                                bool is_request) {
+    // Write the headers and capture the outgoing data
+    EXPECT_CALL(session_, WritevData(headers_stream_,
+                                     QuicUtils::GetHeadersStreamId(
+                                         connection_->transport_version()),
+                                     _, _, NO_FIN))
+        .WillOnce(WithArgs<2>(Invoke(this, &QuicHeadersStreamTest::SaveIov)));
+    QuicSpdySessionPeer::WriteHeadersOnHeadersStream(
+        &session_, stream_id, headers_.Clone(), fin, priority, nullptr);
+
+    // Parse the outgoing data and check that it matches was was written.
+    if (is_request) {
+      EXPECT_CALL(visitor_,
+                  OnHeaders(stream_id, kHasPriority,
+                            Spdy3PriorityToHttp2Weight(priority),
+                            /*parent_stream_id=*/0,
+                            /*exclusive=*/false, fin, kFrameComplete));
+    } else {
+      EXPECT_CALL(visitor_,
+                  OnHeaders(stream_id, !kHasPriority,
+                            /*priority=*/0,
+                            /*parent_stream_id=*/0,
+                            /*exclusive=*/false, fin, kFrameComplete));
+    }
+    headers_handler_ = QuicMakeUnique<TestHeadersHandler>();
+    EXPECT_CALL(visitor_, OnHeaderFrameStart(stream_id))
+        .WillOnce(Return(headers_handler_.get()));
+    EXPECT_CALL(visitor_, OnHeaderFrameEnd(stream_id)).Times(1);
+    if (fin) {
+      EXPECT_CALL(visitor_, OnStreamEnd(stream_id));
+    }
+    deframer_->ProcessInput(saved_data_.data(), saved_data_.length());
+    EXPECT_FALSE(deframer_->HasError())
+        << http2::Http2DecoderAdapter::SpdyFramerErrorToString(
+               deframer_->spdy_framer_error());
+
+    CheckHeaders();
+    saved_data_.clear();
+  }
+
+  void CheckHeaders() {
+    EXPECT_EQ(headers_, headers_handler_->decoded_block());
+    headers_handler_.reset();
+  }
+
+  Perspective perspective() const { return GetParam().perspective; }
+
+  QuicTransportVersion transport_version() const {
+    return GetParam().version.transport_version;
+  }
+
+  ParsedQuicVersionVector GetVersion() {
+    ParsedQuicVersionVector versions;
+    versions.push_back(GetParam().version);
+    return versions;
+  }
+
+  void TearDownLocalConnectionState() {
+    QuicConnectionPeer::TearDownLocalConnectionState(connection_);
+  }
+
+  QuicStreamId NextPromisedStreamId() {
+    return next_promised_stream_id_ += next_stream_id_;
+  }
+
+  static const bool kFrameComplete = true;
+  static const bool kHasPriority = true;
+
+  MockQuicConnectionHelper helper_;
+  MockAlarmFactory alarm_factory_;
+  StrictMock<MockQuicConnection>* connection_;
+  StrictMock<MockQuicSpdySession> session_;
+  QuicHeadersStream* headers_stream_;
+  SpdyHeaderBlock headers_;
+  std::unique_ptr<TestHeadersHandler> headers_handler_;
+  QuicString body_;
+  QuicString saved_data_;
+  QuicString saved_header_data_;
+  QuicString saved_payloads_;
+  std::unique_ptr<SpdyFramer> framer_;
+  std::unique_ptr<http2::Http2DecoderAdapter> deframer_;
+  StrictMock<MockVisitor> visitor_;
+  QuicStreamFrame stream_frame_;
+  QuicStreamId next_promised_stream_id_;
+  QuicStreamId client_id_1_;
+  QuicStreamId client_id_2_;
+  QuicStreamId client_id_3_;
+  QuicStreamId next_stream_id_;
+};
+
+// Run all tests with each version and perspective (client or server).
+INSTANTIATE_TEST_SUITE_P(Tests, QuicHeadersStreamTest,
+                         ::testing::ValuesIn(GetTestParams()));
+
+TEST_P(QuicHeadersStreamTest, StreamId) {
+  EXPECT_EQ(QuicUtils::GetHeadersStreamId(connection_->transport_version()),
+            headers_stream_->id());
+}
+
+TEST_P(QuicHeadersStreamTest, WriteHeaders) {
+  for (QuicStreamId stream_id = client_id_1_; stream_id < client_id_3_;
+       stream_id += next_stream_id_) {
+    for (bool fin : {false, true}) {
+      if (perspective() == Perspective::IS_SERVER) {
+        WriteAndExpectResponseHeaders(stream_id, fin);
+      } else {
+        for (SpdyPriority priority = 0; priority < 7; ++priority) {
+          // TODO(rch): implement priorities correctly.
+          WriteAndExpectRequestHeaders(stream_id, fin, 0);
+        }
+      }
+    }
+  }
+}
+
+TEST_P(QuicHeadersStreamTest, WritePushPromises) {
+  for (QuicStreamId stream_id = client_id_1_; stream_id < client_id_3_;
+       stream_id += next_stream_id_) {
+    QuicStreamId promised_stream_id = NextPromisedStreamId();
+    if (perspective() == Perspective::IS_SERVER) {
+      // Write the headers and capture the outgoing data
+      EXPECT_CALL(session_, WritevData(headers_stream_,
+                                       QuicUtils::GetHeadersStreamId(
+                                           connection_->transport_version()),
+                                       _, _, NO_FIN))
+          .WillOnce(WithArgs<2>(Invoke(this, &QuicHeadersStreamTest::SaveIov)));
+      session_.WritePushPromise(stream_id, promised_stream_id,
+                                headers_.Clone());
+
+      // Parse the outgoing data and check that it matches was was written.
+      EXPECT_CALL(visitor_,
+                  OnPushPromise(stream_id, promised_stream_id, kFrameComplete));
+      headers_handler_ = QuicMakeUnique<TestHeadersHandler>();
+      EXPECT_CALL(visitor_, OnHeaderFrameStart(stream_id))
+          .WillOnce(Return(headers_handler_.get()));
+      EXPECT_CALL(visitor_, OnHeaderFrameEnd(stream_id)).Times(1);
+      deframer_->ProcessInput(saved_data_.data(), saved_data_.length());
+      EXPECT_FALSE(deframer_->HasError())
+          << http2::Http2DecoderAdapter::SpdyFramerErrorToString(
+                 deframer_->spdy_framer_error());
+      CheckHeaders();
+      saved_data_.clear();
+    } else {
+      EXPECT_QUIC_BUG(session_.WritePushPromise(stream_id, promised_stream_id,
+                                                headers_.Clone()),
+                      "Client shouldn't send PUSH_PROMISE");
+    }
+  }
+}
+
+TEST_P(QuicHeadersStreamTest, ProcessRawData) {
+  for (QuicStreamId stream_id = client_id_1_; stream_id < client_id_3_;
+       stream_id += next_stream_id_) {
+    for (bool fin : {false, true}) {
+      for (SpdyPriority priority = 0; priority < 7; ++priority) {
+        // Replace with "WriteHeadersAndSaveData"
+        SpdySerializedFrame frame;
+        if (perspective() == Perspective::IS_SERVER) {
+          SpdyHeadersIR headers_frame(stream_id, headers_.Clone());
+          headers_frame.set_fin(fin);
+          headers_frame.set_has_priority(true);
+          headers_frame.set_weight(Spdy3PriorityToHttp2Weight(0));
+          frame = framer_->SerializeFrame(headers_frame);
+          EXPECT_CALL(session_, OnStreamHeadersPriority(stream_id, 0));
+        } else {
+          SpdyHeadersIR headers_frame(stream_id, headers_.Clone());
+          headers_frame.set_fin(fin);
+          frame = framer_->SerializeFrame(headers_frame);
+        }
+        EXPECT_CALL(session_,
+                    OnStreamHeaderList(stream_id, fin, frame.size(), _))
+            .WillOnce(Invoke(this, &QuicHeadersStreamTest::SaveHeaderList));
+        stream_frame_.data_buffer = frame.data();
+        stream_frame_.data_length = frame.size();
+        headers_stream_->OnStreamFrame(stream_frame_);
+        stream_frame_.offset += frame.size();
+        CheckHeaders();
+      }
+    }
+  }
+}
+
+TEST_P(QuicHeadersStreamTest, ProcessPushPromise) {
+  if (perspective() == Perspective::IS_SERVER) {
+    return;
+  }
+  for (QuicStreamId stream_id = client_id_1_; stream_id < client_id_3_;
+       stream_id += next_stream_id_) {
+    QuicStreamId promised_stream_id = NextPromisedStreamId();
+    SpdyPushPromiseIR push_promise(stream_id, promised_stream_id,
+                                   headers_.Clone());
+    SpdySerializedFrame frame(framer_->SerializeFrame(push_promise));
+    if (perspective() == Perspective::IS_SERVER) {
+      EXPECT_CALL(*connection_,
+                  CloseConnection(QUIC_INVALID_HEADERS_STREAM_DATA,
+                                  "PUSH_PROMISE not supported.", _))
+          .WillRepeatedly(InvokeWithoutArgs(
+              this, &QuicHeadersStreamTest::TearDownLocalConnectionState));
+    } else {
+      EXPECT_CALL(session_, OnPromiseHeaderList(stream_id, promised_stream_id,
+                                                frame.size(), _))
+          .WillOnce(
+              Invoke(this, &QuicHeadersStreamTest::SavePromiseHeaderList));
+    }
+    stream_frame_.data_buffer = frame.data();
+    stream_frame_.data_length = frame.size();
+    headers_stream_->OnStreamFrame(stream_frame_);
+    if (perspective() == Perspective::IS_CLIENT) {
+      stream_frame_.offset += frame.size();
+      CheckHeaders();
+    }
+  }
+}
+
+TEST_P(QuicHeadersStreamTest, ProcessPriorityFrame) {
+  QuicStreamId parent_stream_id = 0;
+  for (SpdyPriority priority = 0; priority < 7; ++priority) {
+    for (QuicStreamId stream_id = client_id_1_; stream_id < client_id_3_;
+         stream_id += next_stream_id_) {
+      int weight = Spdy3PriorityToHttp2Weight(priority);
+      SpdyPriorityIR priority_frame(stream_id, parent_stream_id, weight, true);
+      SpdySerializedFrame frame(framer_->SerializeFrame(priority_frame));
+      parent_stream_id = stream_id;
+      if (transport_version() <= QUIC_VERSION_39) {
+        EXPECT_CALL(*connection_,
+                    CloseConnection(QUIC_INVALID_HEADERS_STREAM_DATA,
+                                    "SPDY PRIORITY frame received.", _))
+            .WillRepeatedly(InvokeWithoutArgs(
+                this, &QuicHeadersStreamTest::TearDownLocalConnectionState));
+      } else if (perspective() == Perspective::IS_CLIENT) {
+        EXPECT_CALL(*connection_,
+                    CloseConnection(QUIC_INVALID_HEADERS_STREAM_DATA,
+                                    "Server must not send PRIORITY frames.", _))
+            .WillRepeatedly(InvokeWithoutArgs(
+                this, &QuicHeadersStreamTest::TearDownLocalConnectionState));
+      } else {
+        EXPECT_CALL(session_, OnPriorityFrame(stream_id, priority)).Times(1);
+      }
+      stream_frame_.data_buffer = frame.data();
+      stream_frame_.data_length = frame.size();
+      headers_stream_->OnStreamFrame(stream_frame_);
+      stream_frame_.offset += frame.size();
+    }
+  }
+}
+
+TEST_P(QuicHeadersStreamTest, ProcessPushPromiseDisabledSetting) {
+  session_.OnConfigNegotiated();
+  SpdySettingsIR data;
+  // Respect supported settings frames SETTINGS_ENABLE_PUSH.
+  data.AddSetting(SETTINGS_ENABLE_PUSH, 0);
+  SpdySerializedFrame frame(framer_->SerializeFrame(data));
+  stream_frame_.data_buffer = frame.data();
+  stream_frame_.data_length = frame.size();
+  if (perspective() == Perspective::IS_CLIENT) {
+    EXPECT_CALL(
+        *connection_,
+        CloseConnection(QUIC_INVALID_HEADERS_STREAM_DATA,
+                        "Unsupported field of HTTP/2 SETTINGS frame: 2", _));
+  }
+  headers_stream_->OnStreamFrame(stream_frame_);
+  EXPECT_EQ(session_.server_push_enabled(),
+            perspective() == Perspective::IS_CLIENT);
+}
+
+TEST_P(QuicHeadersStreamTest, ProcessLargeRawData) {
+  QuicSpdySessionPeer::SetMaxUncompressedHeaderBytes(&session_, 256 * 1024);
+  // We want to create a frame that is more than the SPDY Framer's max control
+  // frame size, which is 16K, but less than the HPACK decoders max decode
+  // buffer size, which is 32K.
+  headers_["key0"] = QuicString(1 << 13, '.');
+  headers_["key1"] = QuicString(1 << 13, '.');
+  headers_["key2"] = QuicString(1 << 13, '.');
+  for (QuicStreamId stream_id = client_id_1_; stream_id < client_id_3_;
+       stream_id += next_stream_id_) {
+    for (bool fin : {false, true}) {
+      for (SpdyPriority priority = 0; priority < 7; ++priority) {
+        // Replace with "WriteHeadersAndSaveData"
+        SpdySerializedFrame frame;
+        if (perspective() == Perspective::IS_SERVER) {
+          SpdyHeadersIR headers_frame(stream_id, headers_.Clone());
+          headers_frame.set_fin(fin);
+          headers_frame.set_has_priority(true);
+          headers_frame.set_weight(Spdy3PriorityToHttp2Weight(0));
+          frame = framer_->SerializeFrame(headers_frame);
+          EXPECT_CALL(session_, OnStreamHeadersPriority(stream_id, 0));
+        } else {
+          SpdyHeadersIR headers_frame(stream_id, headers_.Clone());
+          headers_frame.set_fin(fin);
+          frame = framer_->SerializeFrame(headers_frame);
+        }
+        EXPECT_CALL(session_,
+                    OnStreamHeaderList(stream_id, fin, frame.size(), _))
+            .WillOnce(Invoke(this, &QuicHeadersStreamTest::SaveHeaderList));
+        stream_frame_.data_buffer = frame.data();
+        stream_frame_.data_length = frame.size();
+        headers_stream_->OnStreamFrame(stream_frame_);
+        stream_frame_.offset += frame.size();
+        CheckHeaders();
+      }
+    }
+  }
+}
+
+TEST_P(QuicHeadersStreamTest, ProcessBadData) {
+  const char kBadData[] = "blah blah blah";
+  EXPECT_CALL(*connection_,
+              CloseConnection(QUIC_INVALID_HEADERS_STREAM_DATA, _, _))
+      .Times(::testing::AnyNumber());
+  stream_frame_.data_buffer = kBadData;
+  stream_frame_.data_length = strlen(kBadData);
+  headers_stream_->OnStreamFrame(stream_frame_);
+}
+
+TEST_P(QuicHeadersStreamTest, ProcessSpdyDataFrame) {
+  SpdyDataIR data(/* stream_id = */ 2, "ping");
+  SpdySerializedFrame frame(framer_->SerializeFrame(data));
+
+  EXPECT_CALL(*connection_, CloseConnection(QUIC_INVALID_HEADERS_STREAM_DATA,
+                                            "SPDY DATA frame received.", _))
+      .WillOnce(InvokeWithoutArgs(
+          this, &QuicHeadersStreamTest::TearDownLocalConnectionState));
+  stream_frame_.data_buffer = frame.data();
+  stream_frame_.data_length = frame.size();
+  headers_stream_->OnStreamFrame(stream_frame_);
+}
+
+TEST_P(QuicHeadersStreamTest, ProcessSpdyRstStreamFrame) {
+  SpdyRstStreamIR data(/* stream_id = */ 2, ERROR_CODE_PROTOCOL_ERROR);
+  SpdySerializedFrame frame(framer_->SerializeFrame(data));
+  EXPECT_CALL(*connection_,
+              CloseConnection(QUIC_INVALID_HEADERS_STREAM_DATA,
+                              "SPDY RST_STREAM frame received.", _))
+      .WillOnce(InvokeWithoutArgs(
+          this, &QuicHeadersStreamTest::TearDownLocalConnectionState));
+  stream_frame_.data_buffer = frame.data();
+  stream_frame_.data_length = frame.size();
+  headers_stream_->OnStreamFrame(stream_frame_);
+}
+
+TEST_P(QuicHeadersStreamTest, RespectHttp2SettingsFrameSupportedFields) {
+  const uint32_t kTestHeaderTableSize = 1000;
+  SpdySettingsIR data;
+  // Respect supported settings frames SETTINGS_HEADER_TABLE_SIZE,
+  // SETTINGS_MAX_HEADER_LIST_SIZE.
+  data.AddSetting(SETTINGS_HEADER_TABLE_SIZE, kTestHeaderTableSize);
+  data.AddSetting(SETTINGS_MAX_HEADER_LIST_SIZE, 2000);
+  SpdySerializedFrame frame(framer_->SerializeFrame(data));
+  stream_frame_.data_buffer = frame.data();
+  stream_frame_.data_length = frame.size();
+  headers_stream_->OnStreamFrame(stream_frame_);
+  EXPECT_EQ(kTestHeaderTableSize, QuicSpdySessionPeer::GetSpdyFramer(&session_)
+                                      .header_encoder_table_size());
+}
+
+TEST_P(QuicHeadersStreamTest, RespectHttp2SettingsFrameUnsupportedFields) {
+  SpdySettingsIR data;
+  // Does not support SETTINGS_MAX_CONCURRENT_STREAMS,
+  // SETTINGS_INITIAL_WINDOW_SIZE, SETTINGS_ENABLE_PUSH and
+  // SETTINGS_MAX_FRAME_SIZE.
+  data.AddSetting(SETTINGS_MAX_CONCURRENT_STREAMS, 100);
+  data.AddSetting(SETTINGS_INITIAL_WINDOW_SIZE, 100);
+  data.AddSetting(SETTINGS_ENABLE_PUSH, 1);
+  data.AddSetting(SETTINGS_MAX_FRAME_SIZE, 1250);
+  SpdySerializedFrame frame(framer_->SerializeFrame(data));
+  EXPECT_CALL(
+      *connection_,
+      CloseConnection(QUIC_INVALID_HEADERS_STREAM_DATA,
+                      QuicStrCat("Unsupported field of HTTP/2 SETTINGS frame: ",
+                                 SETTINGS_MAX_CONCURRENT_STREAMS),
+                      _));
+  EXPECT_CALL(
+      *connection_,
+      CloseConnection(QUIC_INVALID_HEADERS_STREAM_DATA,
+                      QuicStrCat("Unsupported field of HTTP/2 SETTINGS frame: ",
+                                 SETTINGS_INITIAL_WINDOW_SIZE),
+                      _));
+  if (session_.perspective() == Perspective::IS_CLIENT) {
+    EXPECT_CALL(*connection_,
+                CloseConnection(
+                    QUIC_INVALID_HEADERS_STREAM_DATA,
+                    QuicStrCat("Unsupported field of HTTP/2 SETTINGS frame: ",
+                               SETTINGS_ENABLE_PUSH),
+                    _));
+  }
+  EXPECT_CALL(
+      *connection_,
+      CloseConnection(QUIC_INVALID_HEADERS_STREAM_DATA,
+                      QuicStrCat("Unsupported field of HTTP/2 SETTINGS frame: ",
+                                 SETTINGS_MAX_FRAME_SIZE),
+                      _));
+  stream_frame_.data_buffer = frame.data();
+  stream_frame_.data_length = frame.size();
+  headers_stream_->OnStreamFrame(stream_frame_);
+}
+
+TEST_P(QuicHeadersStreamTest, ProcessSpdyPingFrame) {
+  SpdyPingIR data(1);
+  SpdySerializedFrame frame(framer_->SerializeFrame(data));
+  EXPECT_CALL(*connection_, CloseConnection(QUIC_INVALID_HEADERS_STREAM_DATA,
+                                            "SPDY PING frame received.", _))
+      .WillOnce(InvokeWithoutArgs(
+          this, &QuicHeadersStreamTest::TearDownLocalConnectionState));
+  stream_frame_.data_buffer = frame.data();
+  stream_frame_.data_length = frame.size();
+  headers_stream_->OnStreamFrame(stream_frame_);
+}
+
+TEST_P(QuicHeadersStreamTest, ProcessSpdyGoAwayFrame) {
+  SpdyGoAwayIR data(/* last_good_stream_id = */ 1, ERROR_CODE_PROTOCOL_ERROR,
+                    "go away");
+  SpdySerializedFrame frame(framer_->SerializeFrame(data));
+  EXPECT_CALL(*connection_, CloseConnection(QUIC_INVALID_HEADERS_STREAM_DATA,
+                                            "SPDY GOAWAY frame received.", _))
+      .WillOnce(InvokeWithoutArgs(
+          this, &QuicHeadersStreamTest::TearDownLocalConnectionState));
+  stream_frame_.data_buffer = frame.data();
+  stream_frame_.data_length = frame.size();
+  headers_stream_->OnStreamFrame(stream_frame_);
+}
+
+TEST_P(QuicHeadersStreamTest, ProcessSpdyWindowUpdateFrame) {
+  SpdyWindowUpdateIR data(/* stream_id = */ 1, /* delta = */ 1);
+  SpdySerializedFrame frame(framer_->SerializeFrame(data));
+  EXPECT_CALL(*connection_,
+              CloseConnection(QUIC_INVALID_HEADERS_STREAM_DATA,
+                              "SPDY WINDOW_UPDATE frame received.", _))
+      .WillOnce(InvokeWithoutArgs(
+          this, &QuicHeadersStreamTest::TearDownLocalConnectionState));
+  stream_frame_.data_buffer = frame.data();
+  stream_frame_.data_length = frame.size();
+  headers_stream_->OnStreamFrame(stream_frame_);
+}
+
+TEST_P(QuicHeadersStreamTest, NoConnectionLevelFlowControl) {
+  EXPECT_FALSE(QuicStreamPeer::StreamContributesToConnectionFlowControl(
+      headers_stream_));
+}
+
+TEST_P(QuicHeadersStreamTest, HpackDecoderDebugVisitor) {
+  auto hpack_decoder_visitor =
+      QuicMakeUnique<StrictMock<MockQuicHpackDebugVisitor>>();
+  {
+    InSequence seq;
+    // Number of indexed representations generated in headers below.
+    for (int i = 1; i < 28; i++) {
+      EXPECT_CALL(*hpack_decoder_visitor,
+                  OnUseEntry(QuicTime::Delta::FromMilliseconds(i)))
+          .Times(4);
+    }
+  }
+  QuicSpdySessionPeer::SetHpackDecoderDebugVisitor(
+      &session_, std::move(hpack_decoder_visitor));
+
+  // Create some headers we expect to generate entries in HPACK's
+  // dynamic table, in addition to content-length.
+  headers_["key0"] = QuicString(1 << 1, '.');
+  headers_["key1"] = QuicString(1 << 2, '.');
+  headers_["key2"] = QuicString(1 << 3, '.');
+  for (QuicStreamId stream_id = client_id_1_; stream_id < client_id_3_;
+       stream_id += next_stream_id_) {
+    for (bool fin : {false, true}) {
+      for (SpdyPriority priority = 0; priority < 7; ++priority) {
+        // Replace with "WriteHeadersAndSaveData"
+        SpdySerializedFrame frame;
+        if (perspective() == Perspective::IS_SERVER) {
+          SpdyHeadersIR headers_frame(stream_id, headers_.Clone());
+          headers_frame.set_fin(fin);
+          headers_frame.set_has_priority(true);
+          headers_frame.set_weight(Spdy3PriorityToHttp2Weight(0));
+          frame = framer_->SerializeFrame(headers_frame);
+          EXPECT_CALL(session_, OnStreamHeadersPriority(stream_id, 0));
+        } else {
+          SpdyHeadersIR headers_frame(stream_id, headers_.Clone());
+          headers_frame.set_fin(fin);
+          frame = framer_->SerializeFrame(headers_frame);
+        }
+        EXPECT_CALL(session_,
+                    OnStreamHeaderList(stream_id, fin, frame.size(), _))
+            .WillOnce(Invoke(this, &QuicHeadersStreamTest::SaveHeaderList));
+        stream_frame_.data_buffer = frame.data();
+        stream_frame_.data_length = frame.size();
+        connection_->AdvanceTime(QuicTime::Delta::FromMilliseconds(1));
+        headers_stream_->OnStreamFrame(stream_frame_);
+        stream_frame_.offset += frame.size();
+        CheckHeaders();
+      }
+    }
+  }
+}
+
+TEST_P(QuicHeadersStreamTest, HpackEncoderDebugVisitor) {
+  auto hpack_encoder_visitor =
+      QuicMakeUnique<StrictMock<MockQuicHpackDebugVisitor>>();
+  if (perspective() == Perspective::IS_SERVER) {
+    InSequence seq;
+    for (int i = 1; i < 4; i++) {
+      EXPECT_CALL(*hpack_encoder_visitor,
+                  OnUseEntry(QuicTime::Delta::FromMilliseconds(i)));
+    }
+  } else {
+    InSequence seq;
+    for (int i = 1; i < 28; i++) {
+      EXPECT_CALL(*hpack_encoder_visitor,
+                  OnUseEntry(QuicTime::Delta::FromMilliseconds(i)));
+    }
+  }
+  QuicSpdySessionPeer::SetHpackEncoderDebugVisitor(
+      &session_, std::move(hpack_encoder_visitor));
+
+  for (QuicStreamId stream_id = client_id_1_; stream_id < client_id_3_;
+       stream_id += next_stream_id_) {
+    for (bool fin : {false, true}) {
+      if (perspective() == Perspective::IS_SERVER) {
+        WriteAndExpectResponseHeaders(stream_id, fin);
+        connection_->AdvanceTime(QuicTime::Delta::FromMilliseconds(1));
+      } else {
+        for (SpdyPriority priority = 0; priority < 7; ++priority) {
+          // TODO(rch): implement priorities correctly.
+          WriteAndExpectRequestHeaders(stream_id, fin, 0);
+          connection_->AdvanceTime(QuicTime::Delta::FromMilliseconds(1));
+        }
+      }
+    }
+  }
+}
+
+TEST_P(QuicHeadersStreamTest, AckSentData) {
+  EXPECT_CALL(session_, WritevData(headers_stream_,
+                                   QuicUtils::GetHeadersStreamId(
+                                       connection_->transport_version()),
+                                   _, _, NO_FIN))
+      .WillRepeatedly(Invoke(MockQuicSession::ConsumeData));
+  InSequence s;
+  QuicReferenceCountedPointer<MockAckListener> ack_listener1(
+      new MockAckListener());
+  QuicReferenceCountedPointer<MockAckListener> ack_listener2(
+      new MockAckListener());
+  QuicReferenceCountedPointer<MockAckListener> ack_listener3(
+      new MockAckListener());
+
+  // Packet 1.
+  headers_stream_->WriteOrBufferData("Header5", false, ack_listener1);
+  headers_stream_->WriteOrBufferData("Header5", false, ack_listener1);
+  headers_stream_->WriteOrBufferData("Header7", false, ack_listener2);
+
+  // Packet 2.
+  headers_stream_->WriteOrBufferData("Header9", false, ack_listener3);
+  headers_stream_->WriteOrBufferData("Header7", false, ack_listener2);
+
+  // Packet 3.
+  headers_stream_->WriteOrBufferData("Header9", false, ack_listener3);
+
+  // Packet 2 gets retransmitted.
+  EXPECT_CALL(*ack_listener3, OnPacketRetransmitted(7)).Times(1);
+  EXPECT_CALL(*ack_listener2, OnPacketRetransmitted(7)).Times(1);
+  headers_stream_->OnStreamFrameRetransmitted(21, 7, false);
+  headers_stream_->OnStreamFrameRetransmitted(28, 7, false);
+
+  // Packets are acked in order: 2, 3, 1.
+  QuicByteCount newly_acked_length = 0;
+  EXPECT_CALL(*ack_listener3, OnPacketAcked(7, _));
+  EXPECT_CALL(*ack_listener2, OnPacketAcked(7, _));
+  EXPECT_TRUE(headers_stream_->OnStreamFrameAcked(
+      21, 7, false, QuicTime::Delta::Zero(), &newly_acked_length));
+  EXPECT_EQ(7u, newly_acked_length);
+  EXPECT_TRUE(headers_stream_->OnStreamFrameAcked(
+      28, 7, false, QuicTime::Delta::Zero(), &newly_acked_length));
+  EXPECT_EQ(7u, newly_acked_length);
+
+  EXPECT_CALL(*ack_listener3, OnPacketAcked(7, _));
+  EXPECT_TRUE(headers_stream_->OnStreamFrameAcked(
+      35, 7, false, QuicTime::Delta::Zero(), &newly_acked_length));
+  EXPECT_EQ(7u, newly_acked_length);
+
+  EXPECT_CALL(*ack_listener1, OnPacketAcked(7, _));
+  EXPECT_CALL(*ack_listener1, OnPacketAcked(7, _));
+  EXPECT_TRUE(headers_stream_->OnStreamFrameAcked(
+      0, 7, false, QuicTime::Delta::Zero(), &newly_acked_length));
+  EXPECT_EQ(7u, newly_acked_length);
+  EXPECT_TRUE(headers_stream_->OnStreamFrameAcked(
+      7, 7, false, QuicTime::Delta::Zero(), &newly_acked_length));
+  EXPECT_EQ(7u, newly_acked_length);
+  // Unsent data is acked.
+  EXPECT_CALL(*ack_listener2, OnPacketAcked(7, _));
+  EXPECT_TRUE(headers_stream_->OnStreamFrameAcked(
+      14, 10, false, QuicTime::Delta::Zero(), &newly_acked_length));
+  EXPECT_EQ(7u, newly_acked_length);
+}
+
+TEST_P(QuicHeadersStreamTest, FrameContainsMultipleHeaders) {
+  // In this test, a stream frame can contain multiple headers.
+  EXPECT_CALL(session_, WritevData(headers_stream_,
+                                   QuicUtils::GetHeadersStreamId(
+                                       connection_->transport_version()),
+                                   _, _, NO_FIN))
+      .WillRepeatedly(Invoke(MockQuicSession::ConsumeData));
+  InSequence s;
+  QuicReferenceCountedPointer<MockAckListener> ack_listener1(
+      new MockAckListener());
+  QuicReferenceCountedPointer<MockAckListener> ack_listener2(
+      new MockAckListener());
+  QuicReferenceCountedPointer<MockAckListener> ack_listener3(
+      new MockAckListener());
+
+  headers_stream_->WriteOrBufferData("Header5", false, ack_listener1);
+  headers_stream_->WriteOrBufferData("Header5", false, ack_listener1);
+  headers_stream_->WriteOrBufferData("Header7", false, ack_listener2);
+  headers_stream_->WriteOrBufferData("Header9", false, ack_listener3);
+  headers_stream_->WriteOrBufferData("Header7", false, ack_listener2);
+  headers_stream_->WriteOrBufferData("Header9", false, ack_listener3);
+
+  // Frame 1 is retransmitted.
+  EXPECT_CALL(*ack_listener1, OnPacketRetransmitted(14));
+  EXPECT_CALL(*ack_listener2, OnPacketRetransmitted(3));
+  headers_stream_->OnStreamFrameRetransmitted(0, 17, false);
+
+  // Frames are acked in order: 2, 3, 1.
+  QuicByteCount newly_acked_length = 0;
+  EXPECT_CALL(*ack_listener2, OnPacketAcked(4, _));
+  EXPECT_CALL(*ack_listener3, OnPacketAcked(7, _));
+  EXPECT_CALL(*ack_listener2, OnPacketAcked(2, _));
+  EXPECT_TRUE(headers_stream_->OnStreamFrameAcked(
+      17, 13, false, QuicTime::Delta::Zero(), &newly_acked_length));
+  EXPECT_EQ(13u, newly_acked_length);
+
+  EXPECT_CALL(*ack_listener2, OnPacketAcked(5, _));
+  EXPECT_CALL(*ack_listener3, OnPacketAcked(7, _));
+  EXPECT_TRUE(headers_stream_->OnStreamFrameAcked(
+      30, 12, false, QuicTime::Delta::Zero(), &newly_acked_length));
+  EXPECT_EQ(12u, newly_acked_length);
+
+  EXPECT_CALL(*ack_listener1, OnPacketAcked(14, _));
+  EXPECT_CALL(*ack_listener2, OnPacketAcked(3, _));
+  EXPECT_TRUE(headers_stream_->OnStreamFrameAcked(
+      0, 17, false, QuicTime::Delta::Zero(), &newly_acked_length));
+  EXPECT_EQ(17u, newly_acked_length);
+}
+
+TEST_P(QuicHeadersStreamTest, HeadersGetAckedMultipleTimes) {
+  EXPECT_CALL(session_, WritevData(headers_stream_,
+                                   QuicUtils::GetHeadersStreamId(
+                                       connection_->transport_version()),
+                                   _, _, NO_FIN))
+      .WillRepeatedly(Invoke(MockQuicSession::ConsumeData));
+  InSequence s;
+  QuicReferenceCountedPointer<MockAckListener> ack_listener1(
+      new MockAckListener());
+  QuicReferenceCountedPointer<MockAckListener> ack_listener2(
+      new MockAckListener());
+  QuicReferenceCountedPointer<MockAckListener> ack_listener3(
+      new MockAckListener());
+
+  // Send [0, 42).
+  headers_stream_->WriteOrBufferData("Header5", false, ack_listener1);
+  headers_stream_->WriteOrBufferData("Header5", false, ack_listener1);
+  headers_stream_->WriteOrBufferData("Header7", false, ack_listener2);
+  headers_stream_->WriteOrBufferData("Header9", false, ack_listener3);
+  headers_stream_->WriteOrBufferData("Header7", false, ack_listener2);
+  headers_stream_->WriteOrBufferData("Header9", false, ack_listener3);
+
+  // Ack [15, 20), [5, 25), [10, 17), [0, 12) and [22, 42).
+  QuicByteCount newly_acked_length = 0;
+  EXPECT_CALL(*ack_listener2, OnPacketAcked(5, _));
+  EXPECT_TRUE(headers_stream_->OnStreamFrameAcked(
+      15, 5, false, QuicTime::Delta::Zero(), &newly_acked_length));
+  EXPECT_EQ(5u, newly_acked_length);
+
+  EXPECT_CALL(*ack_listener1, OnPacketAcked(9, _));
+  EXPECT_CALL(*ack_listener2, OnPacketAcked(1, _));
+  EXPECT_CALL(*ack_listener2, OnPacketAcked(1, _));
+  EXPECT_CALL(*ack_listener3, OnPacketAcked(4, _));
+  EXPECT_TRUE(headers_stream_->OnStreamFrameAcked(
+      5, 20, false, QuicTime::Delta::Zero(), &newly_acked_length));
+  EXPECT_EQ(15u, newly_acked_length);
+
+  // Duplicate ack.
+  EXPECT_FALSE(headers_stream_->OnStreamFrameAcked(
+      10, 7, false, QuicTime::Delta::Zero(), &newly_acked_length));
+  EXPECT_EQ(0u, newly_acked_length);
+
+  EXPECT_CALL(*ack_listener1, OnPacketAcked(5, _));
+  EXPECT_TRUE(headers_stream_->OnStreamFrameAcked(
+      0, 12, false, QuicTime::Delta::Zero(), &newly_acked_length));
+  EXPECT_EQ(5u, newly_acked_length);
+
+  EXPECT_CALL(*ack_listener3, OnPacketAcked(3, _));
+  EXPECT_CALL(*ack_listener2, OnPacketAcked(7, _));
+  EXPECT_CALL(*ack_listener3, OnPacketAcked(7, _));
+  EXPECT_TRUE(headers_stream_->OnStreamFrameAcked(
+      22, 20, false, QuicTime::Delta::Zero(), &newly_acked_length));
+  EXPECT_EQ(17u, newly_acked_length);
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quic/core/http/quic_server_session_base.cc b/quic/core/http/quic_server_session_base.cc
new file mode 100644
index 0000000..f240ece
--- /dev/null
+++ b/quic/core/http/quic_server_session_base.cc
@@ -0,0 +1,277 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/third_party/quiche/src/quic/core/http/quic_server_session_base.h"
+
+#include "net/third_party/quiche/src/quic/core/proto/cached_network_parameters.pb.h"
+#include "net/third_party/quiche/src/quic/core/quic_connection.h"
+#include "net/third_party/quiche/src/quic/core/quic_stream.h"
+#include "net/third_party/quiche/src/quic/core/quic_utils.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_bug_tracker.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_flag_utils.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_flags.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_logging.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_string.h"
+
+namespace quic {
+
+QuicServerSessionBase::QuicServerSessionBase(
+    const QuicConfig& config,
+    const ParsedQuicVersionVector& supported_versions,
+    QuicConnection* connection,
+    Visitor* visitor,
+    QuicCryptoServerStream::Helper* helper,
+    const QuicCryptoServerConfig* crypto_config,
+    QuicCompressedCertsCache* compressed_certs_cache)
+    : QuicSpdySession(connection, visitor, config, supported_versions),
+      crypto_config_(crypto_config),
+      compressed_certs_cache_(compressed_certs_cache),
+      helper_(helper),
+      bandwidth_resumption_enabled_(false),
+      bandwidth_estimate_sent_to_client_(QuicBandwidth::Zero()),
+      last_scup_time_(QuicTime::Zero()) {}
+
+QuicServerSessionBase::~QuicServerSessionBase() {}
+
+void QuicServerSessionBase::Initialize() {
+  crypto_stream_.reset(
+      CreateQuicCryptoServerStream(crypto_config_, compressed_certs_cache_));
+  QuicSpdySession::Initialize();
+}
+
+void QuicServerSessionBase::OnConfigNegotiated() {
+  QuicSpdySession::OnConfigNegotiated();
+
+  if (!config()->HasReceivedConnectionOptions()) {
+    return;
+  }
+
+  // Enable bandwidth resumption if peer sent correct connection options.
+  const bool last_bandwidth_resumption =
+      ContainsQuicTag(config()->ReceivedConnectionOptions(), kBWRE);
+  const bool max_bandwidth_resumption =
+      ContainsQuicTag(config()->ReceivedConnectionOptions(), kBWMX);
+  bandwidth_resumption_enabled_ =
+      last_bandwidth_resumption || max_bandwidth_resumption;
+
+  // If the client has provided a bandwidth estimate from the same serving
+  // region as this server, then decide whether to use the data for bandwidth
+  // resumption.
+  const CachedNetworkParameters* cached_network_params =
+      crypto_stream_->PreviousCachedNetworkParams();
+  if (cached_network_params != nullptr &&
+      cached_network_params->serving_region() == serving_region_) {
+    // Log the received connection parameters, regardless of how they
+    // get used for bandwidth resumption.
+    connection()->OnReceiveConnectionState(*cached_network_params);
+
+    if (bandwidth_resumption_enabled_) {
+      // Only do bandwidth resumption if estimate is recent enough.
+      const uint64_t seconds_since_estimate =
+          connection()->clock()->WallNow().ToUNIXSeconds() -
+          cached_network_params->timestamp();
+      if (seconds_since_estimate <= kNumSecondsPerHour) {
+        connection()->ResumeConnectionState(*cached_network_params,
+                                            max_bandwidth_resumption);
+      }
+    }
+  }
+}
+
+void QuicServerSessionBase::OnConnectionClosed(QuicErrorCode error,
+                                               const QuicString& error_details,
+                                               ConnectionCloseSource source) {
+  QuicSession::OnConnectionClosed(error, error_details, source);
+  // In the unlikely event we get a connection close while doing an asynchronous
+  // crypto event, make sure we cancel the callback.
+  if (crypto_stream_ != nullptr) {
+    crypto_stream_->CancelOutstandingCallbacks();
+  }
+}
+
+void QuicServerSessionBase::OnCongestionWindowChange(QuicTime now) {
+  if (!bandwidth_resumption_enabled_) {
+    return;
+  }
+  // Only send updates when the application has no data to write.
+  if (HasDataToWrite()) {
+    return;
+  }
+
+  // If not enough time has passed since the last time we sent an update to the
+  // client, or not enough packets have been sent, then return early.
+  const QuicSentPacketManager& sent_packet_manager =
+      connection()->sent_packet_manager();
+  int64_t srtt_ms =
+      sent_packet_manager.GetRttStats()->smoothed_rtt().ToMilliseconds();
+  int64_t now_ms = (now - last_scup_time_).ToMilliseconds();
+  int64_t packets_since_last_scup = 0;
+  const QuicPacketNumber largest_sent_packet =
+      connection()->sent_packet_manager().GetLargestSentPacket();
+  if (largest_sent_packet.IsInitialized()) {
+    packets_since_last_scup =
+        last_scup_packet_number_.IsInitialized()
+            ? largest_sent_packet - last_scup_packet_number_
+            : largest_sent_packet.ToUint64();
+  }
+  if (now_ms < (kMinIntervalBetweenServerConfigUpdatesRTTs * srtt_ms) ||
+      now_ms < kMinIntervalBetweenServerConfigUpdatesMs ||
+      packets_since_last_scup < kMinPacketsBetweenServerConfigUpdates) {
+    return;
+  }
+
+  // If the bandwidth recorder does not have a valid estimate, return early.
+  const QuicSustainedBandwidthRecorder* bandwidth_recorder =
+      sent_packet_manager.SustainedBandwidthRecorder();
+  if (bandwidth_recorder == nullptr || !bandwidth_recorder->HasEstimate()) {
+    return;
+  }
+
+  // The bandwidth recorder has recorded at least one sustained bandwidth
+  // estimate. Check that it's substantially different from the last one that
+  // we sent to the client, and if so, send the new one.
+  QuicBandwidth new_bandwidth_estimate =
+      bandwidth_recorder->BandwidthEstimate();
+
+  int64_t bandwidth_delta =
+      std::abs(new_bandwidth_estimate.ToBitsPerSecond() -
+               bandwidth_estimate_sent_to_client_.ToBitsPerSecond());
+
+  // Define "substantial" difference as a 50% increase or decrease from the
+  // last estimate.
+  bool substantial_difference =
+      bandwidth_delta >
+      0.5 * bandwidth_estimate_sent_to_client_.ToBitsPerSecond();
+  if (!substantial_difference) {
+    return;
+  }
+
+  bandwidth_estimate_sent_to_client_ = new_bandwidth_estimate;
+  QUIC_DVLOG(1) << "Server: sending new bandwidth estimate (KBytes/s): "
+                << bandwidth_estimate_sent_to_client_.ToKBytesPerSecond();
+
+  // Include max bandwidth in the update.
+  QuicBandwidth max_bandwidth_estimate =
+      bandwidth_recorder->MaxBandwidthEstimate();
+  int32_t max_bandwidth_timestamp = bandwidth_recorder->MaxBandwidthTimestamp();
+
+  // Fill the proto before passing it to the crypto stream to send.
+  const int32_t bw_estimate_bytes_per_second =
+      BandwidthToCachedParameterBytesPerSecond(
+          bandwidth_estimate_sent_to_client_);
+  const int32_t max_bw_estimate_bytes_per_second =
+      BandwidthToCachedParameterBytesPerSecond(max_bandwidth_estimate);
+  QUIC_BUG_IF(max_bw_estimate_bytes_per_second < 0)
+      << max_bw_estimate_bytes_per_second;
+  QUIC_BUG_IF(bw_estimate_bytes_per_second < 0) << bw_estimate_bytes_per_second;
+
+  CachedNetworkParameters cached_network_params;
+  cached_network_params.set_bandwidth_estimate_bytes_per_second(
+      bw_estimate_bytes_per_second);
+  cached_network_params.set_max_bandwidth_estimate_bytes_per_second(
+      max_bw_estimate_bytes_per_second);
+  cached_network_params.set_max_bandwidth_timestamp_seconds(
+      max_bandwidth_timestamp);
+  cached_network_params.set_min_rtt_ms(
+      sent_packet_manager.GetRttStats()->min_rtt().ToMilliseconds());
+  cached_network_params.set_previous_connection_state(
+      bandwidth_recorder->EstimateRecordedDuringSlowStart()
+          ? CachedNetworkParameters::SLOW_START
+          : CachedNetworkParameters::CONGESTION_AVOIDANCE);
+  cached_network_params.set_timestamp(
+      connection()->clock()->WallNow().ToUNIXSeconds());
+  if (!serving_region_.empty()) {
+    cached_network_params.set_serving_region(serving_region_);
+  }
+
+  crypto_stream_->SendServerConfigUpdate(&cached_network_params);
+
+  connection()->OnSendConnectionState(cached_network_params);
+
+  last_scup_time_ = now;
+  last_scup_packet_number_ =
+      connection()->sent_packet_manager().GetLargestSentPacket();
+}
+
+bool QuicServerSessionBase::ShouldCreateIncomingStream(QuicStreamId id) {
+  if (!connection()->connected()) {
+    QUIC_BUG << "ShouldCreateIncomingStream called when disconnected";
+    return false;
+  }
+
+  if (QuicUtils::IsServerInitiatedStreamId(connection()->transport_version(),
+                                           id)) {
+    QUIC_DLOG(INFO) << "Invalid incoming even stream_id:" << id;
+    connection()->CloseConnection(
+        QUIC_INVALID_STREAM_ID, "Client created even numbered stream",
+        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+    return false;
+  }
+  return true;
+}
+
+bool QuicServerSessionBase::ShouldCreateOutgoingBidirectionalStream() {
+  if (!connection()->connected()) {
+    QUIC_BUG
+        << "ShouldCreateOutgoingBidirectionalStream called when disconnected";
+    return false;
+  }
+  if (!crypto_stream_->encryption_established()) {
+    QUIC_BUG << "Encryption not established so no outgoing stream created.";
+    return false;
+  }
+
+  if (!GetQuicReloadableFlag(quic_use_common_stream_check) &&
+      connection()->transport_version() != QUIC_VERSION_99) {
+    if (GetNumOpenOutgoingStreams() >=
+        stream_id_manager().max_open_outgoing_streams()) {
+      VLOG(1) << "No more streams should be created. "
+              << "Already " << GetNumOpenOutgoingStreams() << " open.";
+      return false;
+    }
+  }
+  QUIC_RELOADABLE_FLAG_COUNT_N(quic_use_common_stream_check, 2, 2);
+  return CanOpenNextOutgoingBidirectionalStream();
+}
+
+bool QuicServerSessionBase::ShouldCreateOutgoingUnidirectionalStream() {
+  if (!connection()->connected()) {
+    QUIC_BUG
+        << "ShouldCreateOutgoingUnidirectionalStream called when disconnected";
+    return false;
+  }
+  if (!crypto_stream_->encryption_established()) {
+    QUIC_BUG << "Encryption not established so no outgoing stream created.";
+    return false;
+  }
+
+  if (!GetQuicReloadableFlag(quic_use_common_stream_check) &&
+      connection()->transport_version() != QUIC_VERSION_99) {
+    if (GetNumOpenOutgoingStreams() >=
+        stream_id_manager().max_open_outgoing_streams()) {
+      VLOG(1) << "No more streams should be created. "
+              << "Already " << GetNumOpenOutgoingStreams() << " open.";
+      return false;
+    }
+  }
+
+  return CanOpenNextOutgoingUnidirectionalStream();
+}
+
+QuicCryptoServerStreamBase* QuicServerSessionBase::GetMutableCryptoStream() {
+  return crypto_stream_.get();
+}
+
+const QuicCryptoServerStreamBase* QuicServerSessionBase::GetCryptoStream()
+    const {
+  return crypto_stream_.get();
+}
+
+int32_t QuicServerSessionBase::BandwidthToCachedParameterBytesPerSecond(
+    const QuicBandwidth& bandwidth) {
+  return static_cast<int32_t>(std::min<int64_t>(
+      bandwidth.ToBytesPerSecond(), std::numeric_limits<uint32_t>::max()));
+}
+
+}  // namespace quic
diff --git a/quic/core/http/quic_server_session_base.h b/quic/core/http/quic_server_session_base.h
new file mode 100644
index 0000000..55a8d60
--- /dev/null
+++ b/quic/core/http/quic_server_session_base.h
@@ -0,0 +1,140 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// A server specific QuicSession subclass.
+
+#ifndef QUICHE_QUIC_CORE_HTTP_QUIC_SERVER_SESSION_BASE_H_
+#define QUICHE_QUIC_CORE_HTTP_QUIC_SERVER_SESSION_BASE_H_
+
+#include <cstdint>
+#include <memory>
+#include <set>
+#include <vector>
+
+#include "base/macros.h"
+#include "net/third_party/quiche/src/quic/core/crypto/quic_compressed_certs_cache.h"
+#include "net/third_party/quiche/src/quic/core/http/quic_spdy_session.h"
+#include "net/third_party/quiche/src/quic/core/quic_crypto_server_stream.h"
+#include "net/third_party/quiche/src/quic/core/quic_packets.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_export.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_string.h"
+
+namespace quic {
+
+class QuicConfig;
+class QuicConnection;
+class QuicCryptoServerConfig;
+
+namespace test {
+class QuicServerSessionBasePeer;
+class QuicSimpleServerSessionPeer;
+}  // namespace test
+
+class QUIC_EXPORT_PRIVATE QuicServerSessionBase : public QuicSpdySession {
+ public:
+  // Does not take ownership of |connection|. |crypto_config| must outlive the
+  // session. |helper| must outlive any created crypto streams.
+  QuicServerSessionBase(const QuicConfig& config,
+                        const ParsedQuicVersionVector& supported_versions,
+                        QuicConnection* connection,
+                        QuicSession::Visitor* visitor,
+                        QuicCryptoServerStream::Helper* helper,
+                        const QuicCryptoServerConfig* crypto_config,
+                        QuicCompressedCertsCache* compressed_certs_cache);
+  QuicServerSessionBase(const QuicServerSessionBase&) = delete;
+  QuicServerSessionBase& operator=(const QuicServerSessionBase&) = delete;
+
+  // Override the base class to cancel any ongoing asychronous crypto.
+  void OnConnectionClosed(QuicErrorCode error,
+                          const QuicString& error_details,
+                          ConnectionCloseSource source) override;
+
+  // Sends a server config update to the client, containing new bandwidth
+  // estimate.
+  void OnCongestionWindowChange(QuicTime now) override;
+
+  ~QuicServerSessionBase() override;
+
+  void Initialize() override;
+
+  const QuicCryptoServerStreamBase* crypto_stream() const {
+    return crypto_stream_.get();
+  }
+
+  // Override base class to process bandwidth related config received from
+  // client.
+  void OnConfigNegotiated() override;
+
+  void set_serving_region(const QuicString& serving_region) {
+    serving_region_ = serving_region;
+  }
+
+ protected:
+  // QuicSession methods(override them with return type of QuicSpdyStream*):
+  QuicCryptoServerStreamBase* GetMutableCryptoStream() override;
+
+  const QuicCryptoServerStreamBase* GetCryptoStream() const override;
+
+  // If an outgoing stream can be created, return true.
+  // Return false when connection is closed or forward secure encryption hasn't
+  // established yet or number of server initiated streams already reaches the
+  // upper limit.
+  bool ShouldCreateOutgoingBidirectionalStream() override;
+  bool ShouldCreateOutgoingUnidirectionalStream() override;
+
+  // If we should create an incoming stream, returns true. Otherwise
+  // does error handling, including communicating the error to the client and
+  // possibly closing the connection, and returns false.
+  bool ShouldCreateIncomingStream(QuicStreamId id) override;
+
+  virtual QuicCryptoServerStreamBase* CreateQuicCryptoServerStream(
+      const QuicCryptoServerConfig* crypto_config,
+      QuicCompressedCertsCache* compressed_certs_cache) = 0;
+
+  const QuicCryptoServerConfig* crypto_config() { return crypto_config_; }
+
+  QuicCryptoServerStream::Helper* stream_helper() { return helper_; }
+
+ private:
+  friend class test::QuicServerSessionBasePeer;
+  friend class test::QuicSimpleServerSessionPeer;
+
+  const QuicCryptoServerConfig* crypto_config_;
+
+  // The cache which contains most recently compressed certs.
+  // Owned by QuicDispatcher.
+  QuicCompressedCertsCache* compressed_certs_cache_;
+
+  std::unique_ptr<QuicCryptoServerStreamBase> crypto_stream_;
+
+  // Pointer to the helper used to create crypto server streams. Must outlive
+  // streams created via CreateQuicCryptoServerStream.
+  QuicCryptoServerStream::Helper* helper_;
+
+  // Whether bandwidth resumption is enabled for this connection.
+  bool bandwidth_resumption_enabled_;
+
+  // The most recent bandwidth estimate sent to the client.
+  QuicBandwidth bandwidth_estimate_sent_to_client_;
+
+  // Text describing server location. Sent to the client as part of the bandwith
+  // estimate in the source-address token. Optional, can be left empty.
+  QuicString serving_region_;
+
+  // Time at which we send the last SCUP to the client.
+  QuicTime last_scup_time_;
+
+  // Number of packets sent to the peer, at the time we last sent a SCUP.
+  QuicPacketNumber last_scup_packet_number_;
+
+  // Converts QuicBandwidth to an int32 bytes/second that can be
+  // stored in CachedNetworkParameters.  TODO(jokulik): This function
+  // should go away once we fix http://b//27897982
+  int32_t BandwidthToCachedParameterBytesPerSecond(
+      const QuicBandwidth& bandwidth);
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_HTTP_QUIC_SERVER_SESSION_BASE_H_
diff --git a/quic/core/http/quic_server_session_base_test.cc b/quic/core/http/quic_server_session_base_test.cc
new file mode 100644
index 0000000..efc2388
--- /dev/null
+++ b/quic/core/http/quic_server_session_base_test.cc
@@ -0,0 +1,740 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/third_party/quiche/src/quic/core/http/quic_server_session_base.h"
+
+#include <cstdint>
+#include <memory>
+
+#include "net/third_party/quiche/src/quic/core/crypto/quic_crypto_server_config.h"
+#include "net/third_party/quiche/src/quic/core/crypto/quic_random.h"
+#include "net/third_party/quiche/src/quic/core/proto/cached_network_parameters.pb.h"
+#include "net/third_party/quiche/src/quic/core/quic_connection.h"
+#include "net/third_party/quiche/src/quic/core/quic_crypto_server_stream.h"
+#include "net/third_party/quiche/src/quic/core/quic_utils.h"
+#include "net/third_party/quiche/src/quic/core/tls_server_handshaker.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_expect_bug.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_flags.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_ptr_util.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_socket_address.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_string.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_test.h"
+#include "net/third_party/quiche/src/quic/test_tools/crypto_test_utils.h"
+#include "net/third_party/quiche/src/quic/test_tools/fake_proof_source.h"
+#include "net/third_party/quiche/src/quic/test_tools/mock_quic_session_visitor.h"
+#include "net/third_party/quiche/src/quic/test_tools/quic_config_peer.h"
+#include "net/third_party/quiche/src/quic/test_tools/quic_connection_peer.h"
+#include "net/third_party/quiche/src/quic/test_tools/quic_crypto_server_config_peer.h"
+#include "net/third_party/quiche/src/quic/test_tools/quic_sent_packet_manager_peer.h"
+#include "net/third_party/quiche/src/quic/test_tools/quic_server_session_base_peer.h"
+#include "net/third_party/quiche/src/quic/test_tools/quic_session_peer.h"
+#include "net/third_party/quiche/src/quic/test_tools/quic_spdy_session_peer.h"
+#include "net/third_party/quiche/src/quic/test_tools/quic_stream_id_manager_peer.h"
+#include "net/third_party/quiche/src/quic/test_tools/quic_stream_peer.h"
+#include "net/third_party/quiche/src/quic/test_tools/quic_sustained_bandwidth_recorder_peer.h"
+#include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h"
+#include "net/third_party/quiche/src/quic/tools/quic_memory_cache_backend.h"
+#include "net/third_party/quiche/src/quic/tools/quic_simple_server_stream.h"
+
+using testing::_;
+using testing::StrictMock;
+
+using testing::AtLeast;
+using testing::Return;
+
+namespace quic {
+namespace test {
+namespace {
+
+class TestServerSession : public QuicServerSessionBase {
+ public:
+  TestServerSession(const QuicConfig& config,
+                    QuicConnection* connection,
+                    QuicSession::Visitor* visitor,
+                    QuicCryptoServerStream::Helper* helper,
+                    const QuicCryptoServerConfig* crypto_config,
+                    QuicCompressedCertsCache* compressed_certs_cache,
+                    QuicSimpleServerBackend* quic_simple_server_backend)
+      : QuicServerSessionBase(config,
+                              CurrentSupportedVersions(),
+                              connection,
+                              visitor,
+                              helper,
+                              crypto_config,
+                              compressed_certs_cache),
+        quic_simple_server_backend_(quic_simple_server_backend) {}
+
+  ~TestServerSession() override { delete connection(); }
+
+ protected:
+  QuicSpdyStream* CreateIncomingStream(QuicStreamId id) override {
+    if (!ShouldCreateIncomingStream(id)) {
+      return nullptr;
+    }
+    QuicSpdyStream* stream = new QuicSimpleServerStream(
+        id, this, BIDIRECTIONAL, quic_simple_server_backend_);
+    ActivateStream(QuicWrapUnique(stream));
+    return stream;
+  }
+
+  QuicSpdyStream* CreateIncomingStream(PendingStream pending) override {
+    QuicSpdyStream* stream = new QuicSimpleServerStream(
+        std::move(pending), this, BIDIRECTIONAL, quic_simple_server_backend_);
+    ActivateStream(QuicWrapUnique(stream));
+    return stream;
+  }
+
+  QuicSpdyStream* CreateOutgoingBidirectionalStream() override {
+    DCHECK(false);
+    return nullptr;
+  }
+
+  QuicSpdyStream* CreateOutgoingUnidirectionalStream() override {
+    if (!ShouldCreateOutgoingUnidirectionalStream()) {
+      return nullptr;
+    }
+
+    QuicSpdyStream* stream = new QuicSimpleServerStream(
+        GetNextOutgoingUnidirectionalStreamId(), this, WRITE_UNIDIRECTIONAL,
+        quic_simple_server_backend_);
+    ActivateStream(QuicWrapUnique(stream));
+    return stream;
+  }
+
+  QuicCryptoServerStreamBase* CreateQuicCryptoServerStream(
+      const QuicCryptoServerConfig* crypto_config,
+      QuicCompressedCertsCache* compressed_certs_cache) override {
+    return new QuicCryptoServerStream(
+        crypto_config, compressed_certs_cache,
+        GetQuicReloadableFlag(enable_quic_stateless_reject_support), this,
+        stream_helper());
+  }
+
+ private:
+  QuicSimpleServerBackend*
+      quic_simple_server_backend_;  // Owned by QuicServerSessionBaseTest
+};
+
+const size_t kMaxStreamsForTest = 10;
+
+class QuicServerSessionBaseTest : public QuicTestWithParam<ParsedQuicVersion> {
+ protected:
+  QuicServerSessionBaseTest()
+      : QuicServerSessionBaseTest(crypto_test_utils::ProofSourceForTesting()) {}
+
+  explicit QuicServerSessionBaseTest(std::unique_ptr<ProofSource> proof_source)
+      : crypto_config_(QuicCryptoServerConfig::TESTING,
+                       QuicRandom::GetInstance(),
+                       std::move(proof_source),
+                       KeyExchangeSource::Default(),
+                       TlsServerHandshaker::CreateSslCtx()),
+        compressed_certs_cache_(
+            QuicCompressedCertsCache::kQuicCompressedCertsCacheSize) {
+    config_.SetMaxIncomingDynamicStreamsToSend(kMaxStreamsForTest);
+    QuicConfigPeer::SetReceivedMaxIncomingDynamicStreams(&config_,
+                                                         kMaxStreamsForTest);
+    config_.SetInitialStreamFlowControlWindowToSend(
+        kInitialStreamFlowControlWindowForTest);
+    config_.SetInitialSessionFlowControlWindowToSend(
+        kInitialSessionFlowControlWindowForTest);
+
+    ParsedQuicVersionVector supported_versions = SupportedVersions(GetParam());
+    connection_ = new StrictMock<MockQuicConnection>(
+        &helper_, &alarm_factory_, Perspective::IS_SERVER, supported_versions);
+    connection_->AdvanceTime(QuicTime::Delta::FromSeconds(1));
+    session_ = QuicMakeUnique<TestServerSession>(
+        config_, connection_, &owner_, &stream_helper_, &crypto_config_,
+        &compressed_certs_cache_, &memory_cache_backend_);
+    MockClock clock;
+    handshake_message_.reset(crypto_config_.AddDefaultConfig(
+        QuicRandom::GetInstance(), &clock,
+        QuicCryptoServerConfig::ConfigOptions()));
+    session_->Initialize();
+    QuicSessionPeer::GetMutableCryptoStream(session_.get())
+        ->OnSuccessfulVersionNegotiation(supported_versions.front());
+    visitor_ = QuicConnectionPeer::GetVisitor(connection_);
+  }
+
+  QuicStreamId GetNthClientInitiatedBidirectionalId(int n) {
+    return GetNthClientInitiatedBidirectionalStreamId(
+        connection_->transport_version(), n);
+  }
+
+  QuicStreamId GetNthServerInitiatedUnidirectionalId(int n) {
+    return quic::test::GetNthServerInitiatedUnidirectionalStreamId(
+        connection_->transport_version(), n);
+  }
+
+  QuicTransportVersion transport_version() const {
+    return connection_->transport_version();
+  }
+
+  // Create and inject a STOP_SENDING frame. In GOOGLE QUIC, receiving a
+  // RST_STREAM frame causes a two-way close. For IETF QUIC, RST_STREAM causes a
+  // one-way close. This method can be used to inject a STOP_SENDING, which
+  // would cause a close in the opposite direction. This allows tests to do the
+  // extra work to get a two-way (full) close where desired. Also sets up
+  // expects needed to ensure that the STOP_SENDING worked as expected.
+  void InjectStopSendingFrame(QuicStreamId stream_id,
+                              QuicRstStreamErrorCode rst_stream_code) {
+    if (transport_version() != QUIC_VERSION_99) {
+      // Only needed for version 99/IETF QUIC. Noop otherwise.
+      return;
+    }
+    QuicStopSendingFrame stop_sending(
+        kInvalidControlFrameId, stream_id,
+        static_cast<QuicApplicationErrorCode>(rst_stream_code));
+    EXPECT_CALL(owner_, OnStopSendingReceived(_)).Times(1);
+    // Expect the RESET_STREAM that is generated in response to receiving a
+    // STOP_SENDING.
+    EXPECT_CALL(*connection_, SendControlFrame(_));
+    EXPECT_CALL(*connection_, OnStreamReset(stream_id, rst_stream_code));
+    session_->OnStopSendingFrame(stop_sending);
+  }
+
+  StrictMock<MockQuicSessionVisitor> owner_;
+  StrictMock<MockQuicCryptoServerStreamHelper> stream_helper_;
+  MockQuicConnectionHelper helper_;
+  MockAlarmFactory alarm_factory_;
+  StrictMock<MockQuicConnection>* connection_;
+  QuicConfig config_;
+  QuicCryptoServerConfig crypto_config_;
+  QuicCompressedCertsCache compressed_certs_cache_;
+  QuicMemoryCacheBackend memory_cache_backend_;
+  std::unique_ptr<TestServerSession> session_;
+  std::unique_ptr<CryptoHandshakeMessage> handshake_message_;
+  QuicConnectionVisitorInterface* visitor_;
+};
+
+// Compares CachedNetworkParameters.
+MATCHER_P(EqualsProto, network_params, "") {
+  CachedNetworkParameters reference(network_params);
+  return (arg->bandwidth_estimate_bytes_per_second() ==
+              reference.bandwidth_estimate_bytes_per_second() &&
+          arg->bandwidth_estimate_bytes_per_second() ==
+              reference.bandwidth_estimate_bytes_per_second() &&
+          arg->max_bandwidth_estimate_bytes_per_second() ==
+              reference.max_bandwidth_estimate_bytes_per_second() &&
+          arg->max_bandwidth_timestamp_seconds() ==
+              reference.max_bandwidth_timestamp_seconds() &&
+          arg->min_rtt_ms() == reference.min_rtt_ms() &&
+          arg->previous_connection_state() ==
+              reference.previous_connection_state());
+}
+
+INSTANTIATE_TEST_SUITE_P(Tests,
+                         QuicServerSessionBaseTest,
+                         ::testing::ValuesIn(AllSupportedVersions()));
+TEST_P(QuicServerSessionBaseTest, CloseStreamDueToReset) {
+  // Open a stream, then reset it.
+  // Send two bytes of payload to open it.
+  QuicStreamFrame data1(GetNthClientInitiatedBidirectionalId(0), false, 0,
+                        QuicStringPiece("HT"));
+  session_->OnStreamFrame(data1);
+  EXPECT_EQ(1u, session_->GetNumOpenIncomingStreams());
+
+  // Send a reset (and expect the peer to send a RST in response).
+  QuicRstStreamFrame rst1(kInvalidControlFrameId,
+                          GetNthClientInitiatedBidirectionalId(0),
+                          QUIC_ERROR_PROCESSING_STREAM, 0);
+  EXPECT_CALL(owner_, OnRstStreamReceived(_)).Times(1);
+  if (transport_version() != QUIC_VERSION_99) {
+    // For non-version 99, the RESET_STREAM will do the full close.
+    // Set up expects accordingly.
+    EXPECT_CALL(*connection_, SendControlFrame(_));
+    EXPECT_CALL(*connection_,
+                OnStreamReset(GetNthClientInitiatedBidirectionalId(0),
+                              QUIC_RST_ACKNOWLEDGEMENT));
+  }
+  visitor_->OnRstStream(rst1);
+
+  // For version-99 will create and receive a stop-sending, completing
+  // the full-close expected by this test.
+  InjectStopSendingFrame(GetNthClientInitiatedBidirectionalId(0),
+                         QUIC_ERROR_PROCESSING_STREAM);
+
+  EXPECT_EQ(0u, session_->GetNumOpenIncomingStreams());
+
+  // Send the same two bytes of payload in a new packet.
+  visitor_->OnStreamFrame(data1);
+
+  // The stream should not be re-opened.
+  EXPECT_EQ(0u, session_->GetNumOpenIncomingStreams());
+  EXPECT_TRUE(connection_->connected());
+}
+
+TEST_P(QuicServerSessionBaseTest, NeverOpenStreamDueToReset) {
+  // Send a reset (and expect the peer to send a RST in response).
+  QuicRstStreamFrame rst1(kInvalidControlFrameId,
+                          GetNthClientInitiatedBidirectionalId(0),
+                          QUIC_ERROR_PROCESSING_STREAM, 0);
+  EXPECT_CALL(owner_, OnRstStreamReceived(_)).Times(1);
+  if (transport_version() != QUIC_VERSION_99) {
+    // For non-version 99, the RESET_STREAM will do the full close.
+    // Set up expects accordingly.
+    EXPECT_CALL(*connection_, SendControlFrame(_));
+    EXPECT_CALL(*connection_,
+                OnStreamReset(GetNthClientInitiatedBidirectionalId(0),
+                              QUIC_RST_ACKNOWLEDGEMENT));
+  }
+  visitor_->OnRstStream(rst1);
+
+  // For version-99 will create and receive a stop-sending, completing
+  // the full-close expected by this test.
+  InjectStopSendingFrame(GetNthClientInitiatedBidirectionalId(0),
+                         QUIC_ERROR_PROCESSING_STREAM);
+
+  EXPECT_EQ(0u, session_->GetNumOpenIncomingStreams());
+
+  // Send two bytes of payload.
+  QuicStreamFrame data1(GetNthClientInitiatedBidirectionalId(0), false, 0,
+                        QuicStringPiece("HT"));
+  visitor_->OnStreamFrame(data1);
+
+  // The stream should never be opened, now that the reset is received.
+  EXPECT_EQ(0u, session_->GetNumOpenIncomingStreams());
+  EXPECT_TRUE(connection_->connected());
+}
+
+TEST_P(QuicServerSessionBaseTest, AcceptClosedStream) {
+  // Send (empty) compressed headers followed by two bytes of data.
+  QuicStreamFrame frame1(GetNthClientInitiatedBidirectionalId(0), false, 0,
+                         QuicStringPiece("\1\0\0\0\0\0\0\0HT"));
+  QuicStreamFrame frame2(GetNthClientInitiatedBidirectionalId(1), false, 0,
+                         QuicStringPiece("\2\0\0\0\0\0\0\0HT"));
+  visitor_->OnStreamFrame(frame1);
+  visitor_->OnStreamFrame(frame2);
+  EXPECT_EQ(2u, session_->GetNumOpenIncomingStreams());
+
+  // Send a reset (and expect the peer to send a RST in response).
+  QuicRstStreamFrame rst(kInvalidControlFrameId,
+                         GetNthClientInitiatedBidirectionalId(0),
+                         QUIC_ERROR_PROCESSING_STREAM, 0);
+  EXPECT_CALL(owner_, OnRstStreamReceived(_)).Times(1);
+  if (transport_version() != QUIC_VERSION_99) {
+    // For non-version 99, the RESET_STREAM will do the full close.
+    // Set up expects accordingly.
+    EXPECT_CALL(*connection_, SendControlFrame(_));
+    EXPECT_CALL(*connection_,
+                OnStreamReset(GetNthClientInitiatedBidirectionalId(0),
+                              QUIC_RST_ACKNOWLEDGEMENT));
+  }
+  visitor_->OnRstStream(rst);
+
+  // For version-99 will create and receive a stop-sending, completing
+  // the full-close expected by this test.
+  InjectStopSendingFrame(GetNthClientInitiatedBidirectionalId(0),
+                         QUIC_ERROR_PROCESSING_STREAM);
+
+  // If we were tracking, we'd probably want to reject this because it's data
+  // past the reset point of stream 3.  As it's a closed stream we just drop the
+  // data on the floor, but accept the packet because it has data for stream 5.
+  QuicStreamFrame frame3(GetNthClientInitiatedBidirectionalId(0), false, 2,
+                         QuicStringPiece("TP"));
+  QuicStreamFrame frame4(GetNthClientInitiatedBidirectionalId(1), false, 2,
+                         QuicStringPiece("TP"));
+  visitor_->OnStreamFrame(frame3);
+  visitor_->OnStreamFrame(frame4);
+  // The stream should never be opened, now that the reset is received.
+  EXPECT_EQ(1u, session_->GetNumOpenIncomingStreams());
+  EXPECT_TRUE(connection_->connected());
+}
+
+TEST_P(QuicServerSessionBaseTest, MaxOpenStreams) {
+  // Test that the server refuses if a client attempts to open too many data
+  // streams.  For versions other than version 99, the server accepts slightly
+  // more than the negotiated stream limit to deal with rare cases where a
+  // client FIN/RST is lost.
+
+  session_->OnConfigNegotiated();
+  if (transport_version() != QUIC_VERSION_99) {
+    // The slightly increased stream limit is set during config negotiation.  It
+    // is either an increase of 10 over negotiated limit, or a fixed percentage
+    // scaling, whichever is larger. Test both before continuing.
+    EXPECT_LT(kMaxStreamsMultiplier * kMaxStreamsForTest,
+              kMaxStreamsForTest + kMaxStreamsMinimumIncrement);
+    EXPECT_EQ(kMaxStreamsForTest + kMaxStreamsMinimumIncrement,
+              session_->max_open_incoming_bidirectional_streams());
+  }
+  EXPECT_EQ(0u, session_->GetNumOpenIncomingStreams());
+  QuicStreamId stream_id = GetNthClientInitiatedBidirectionalId(0);
+  // Open the max configured number of streams, should be no problem.
+  for (size_t i = 0; i < kMaxStreamsForTest; ++i) {
+    EXPECT_TRUE(QuicServerSessionBasePeer::GetOrCreateDynamicStream(
+        session_.get(), stream_id));
+    stream_id += QuicUtils::StreamIdDelta(connection_->transport_version());
+  }
+
+  if (transport_version() != QUIC_VERSION_99) {
+    // Open more streams: server should accept slightly more than the limit.
+    // Excess streams are for non-version-99 only.
+    for (size_t i = 0; i < kMaxStreamsMinimumIncrement; ++i) {
+      EXPECT_TRUE(QuicServerSessionBasePeer::GetOrCreateDynamicStream(
+          session_.get(), stream_id));
+      stream_id += QuicUtils::StreamIdDelta(connection_->transport_version());
+    }
+  }
+  // Now violate the server's internal stream limit.
+  stream_id += QuicUtils::StreamIdDelta(connection_->transport_version());
+
+  if (transport_version() != QUIC_VERSION_99) {
+    // For non-version 99, QUIC responds to an attempt to exceed the stream
+    // limit by resetting the stream.
+    EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(0);
+    EXPECT_CALL(*connection_, SendControlFrame(_));
+    EXPECT_CALL(*connection_, OnStreamReset(stream_id, QUIC_REFUSED_STREAM));
+  } else {
+    // In version 99 QUIC responds to an attempt to exceed the stream limit by
+    // closing the connection.
+    EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(1);
+  }
+  // Even if the connection remains open, the stream creation should fail.
+  EXPECT_FALSE(QuicServerSessionBasePeer::GetOrCreateDynamicStream(
+      session_.get(), stream_id));
+}
+
+TEST_P(QuicServerSessionBaseTest, MaxAvailableBidirectionalStreams) {
+  // Test that the server closes the connection if a client makes too many data
+  // streams available.  The server accepts slightly more than the negotiated
+  // stream limit to deal with rare cases where a client FIN/RST is lost.
+
+  session_->OnConfigNegotiated();
+  const size_t kAvailableStreamLimit =
+      session_->MaxAvailableBidirectionalStreams();
+
+  EXPECT_EQ(0u, session_->GetNumOpenIncomingStreams());
+  EXPECT_TRUE(QuicServerSessionBasePeer::GetOrCreateDynamicStream(
+      session_.get(), GetNthClientInitiatedBidirectionalId(0)));
+
+  // Establish available streams up to the server's limit.
+  QuicStreamId next_id =
+      QuicUtils::StreamIdDelta(connection_->transport_version());
+  const int kLimitingStreamId =
+      GetNthClientInitiatedBidirectionalId(kAvailableStreamLimit + 1);
+  if (transport_version() != QUIC_VERSION_99) {
+    // This exceeds the stream limit. In versions other than 99
+    // this is allowed. Version 99 hews to the IETF spec and does
+    // not allow it.
+    EXPECT_TRUE(QuicServerSessionBasePeer::GetOrCreateDynamicStream(
+        session_.get(), kLimitingStreamId));
+    // A further available stream will result in connection close.
+    EXPECT_CALL(*connection_,
+                CloseConnection(QUIC_TOO_MANY_AVAILABLE_STREAMS, _, _));
+  } else {
+    // A further available stream will result in connection close.
+    EXPECT_CALL(*connection_, CloseConnection(QUIC_INVALID_STREAM_ID, _, _));
+  }
+
+  // This forces stream kLimitingStreamId + 2 to become available, which
+  // violates the quota.
+  EXPECT_FALSE(QuicServerSessionBasePeer::GetOrCreateDynamicStream(
+      session_.get(), kLimitingStreamId + 2 * next_id));
+}
+
+TEST_P(QuicServerSessionBaseTest, GetEvenIncomingError) {
+  // Incoming streams on the server session must be odd.
+  EXPECT_CALL(*connection_, CloseConnection(QUIC_INVALID_STREAM_ID, _, _));
+  EXPECT_EQ(nullptr,
+            QuicServerSessionBasePeer::GetOrCreateDynamicStream(
+                session_.get(), GetNthServerInitiatedUnidirectionalId(0)));
+}
+
+TEST_P(QuicServerSessionBaseTest, GetStreamDisconnected) {
+  // EXPECT_QUIC_BUG tests are expensive so only run one instance of them.
+  if (GetParam() != AllSupportedVersions()[0]) {
+    return;
+  }
+
+  // Don't create new streams if the connection is disconnected.
+  QuicConnectionPeer::TearDownLocalConnectionState(connection_);
+  EXPECT_QUIC_BUG(QuicServerSessionBasePeer::GetOrCreateDynamicStream(
+                      session_.get(), GetNthClientInitiatedBidirectionalId(0)),
+                  "ShouldCreateIncomingStream called when disconnected");
+}
+
+class MockQuicCryptoServerStream : public QuicCryptoServerStream {
+ public:
+  explicit MockQuicCryptoServerStream(
+      const QuicCryptoServerConfig* crypto_config,
+      QuicCompressedCertsCache* compressed_certs_cache,
+      QuicServerSessionBase* session,
+      QuicCryptoServerStream::Helper* helper)
+      : QuicCryptoServerStream(
+            crypto_config,
+            compressed_certs_cache,
+            GetQuicReloadableFlag(enable_quic_stateless_reject_support),
+            session,
+            helper) {}
+  MockQuicCryptoServerStream(const MockQuicCryptoServerStream&) = delete;
+  MockQuicCryptoServerStream& operator=(const MockQuicCryptoServerStream&) =
+      delete;
+  ~MockQuicCryptoServerStream() override {}
+
+  MOCK_METHOD1(SendServerConfigUpdate,
+               void(const CachedNetworkParameters* cached_network_parameters));
+};
+
+TEST_P(QuicServerSessionBaseTest, BandwidthEstimates) {
+  // Test that bandwidth estimate updates are sent to the client, only when
+  // bandwidth resumption is enabled, the bandwidth estimate has changed
+  // sufficiently, enough time has passed,
+  // and we don't have any other data to write.
+
+  // Client has sent kBWRE connection option to trigger bandwidth resumption.
+  QuicTagVector copt;
+  copt.push_back(kBWRE);
+  QuicConfigPeer::SetReceivedConnectionOptions(session_->config(), copt);
+  session_->OnConfigNegotiated();
+  EXPECT_TRUE(
+      QuicServerSessionBasePeer::IsBandwidthResumptionEnabled(session_.get()));
+
+  int32_t bandwidth_estimate_kbytes_per_second = 123;
+  int32_t max_bandwidth_estimate_kbytes_per_second = 134;
+  int32_t max_bandwidth_estimate_timestamp = 1122334455;
+  const QuicString serving_region = "not a real region";
+  session_->set_serving_region(serving_region);
+
+  session_->UnregisterStreamPriority(
+      QuicUtils::GetHeadersStreamId(connection_->transport_version()),
+      /*is_static=*/true);
+  QuicServerSessionBasePeer::SetCryptoStream(session_.get(), nullptr);
+  MockQuicCryptoServerStream* crypto_stream =
+      new MockQuicCryptoServerStream(&crypto_config_, &compressed_certs_cache_,
+                                     session_.get(), &stream_helper_);
+  QuicServerSessionBasePeer::SetCryptoStream(session_.get(), crypto_stream);
+  session_->RegisterStreamPriority(
+      QuicUtils::GetHeadersStreamId(connection_->transport_version()),
+      /*is_static=*/true, QuicStream::kDefaultPriority);
+
+  // Set some initial bandwidth values.
+  QuicSentPacketManager* sent_packet_manager =
+      QuicConnectionPeer::GetSentPacketManager(session_->connection());
+  QuicSustainedBandwidthRecorder& bandwidth_recorder =
+      QuicSentPacketManagerPeer::GetBandwidthRecorder(sent_packet_manager);
+  // Seed an rtt measurement equal to the initial default rtt.
+  RttStats* rtt_stats =
+      const_cast<RttStats*>(sent_packet_manager->GetRttStats());
+  rtt_stats->UpdateRtt(rtt_stats->initial_rtt(), QuicTime::Delta::Zero(),
+                       QuicTime::Zero());
+  QuicSustainedBandwidthRecorderPeer::SetBandwidthEstimate(
+      &bandwidth_recorder, bandwidth_estimate_kbytes_per_second);
+  QuicSustainedBandwidthRecorderPeer::SetMaxBandwidthEstimate(
+      &bandwidth_recorder, max_bandwidth_estimate_kbytes_per_second,
+      max_bandwidth_estimate_timestamp);
+  // Queue up some pending data.
+  session_->MarkConnectionLevelWriteBlocked(QuicUtils::GetCryptoStreamId(
+      session_->connection()->transport_version()));
+  EXPECT_TRUE(session_->HasDataToWrite());
+
+  // There will be no update sent yet - not enough time has passed.
+  QuicTime now = QuicTime::Zero();
+  session_->OnCongestionWindowChange(now);
+
+  // Bandwidth estimate has now changed sufficiently but not enough time has
+  // passed to send a Server Config Update.
+  bandwidth_estimate_kbytes_per_second =
+      bandwidth_estimate_kbytes_per_second * 1.6;
+  session_->OnCongestionWindowChange(now);
+
+  // Bandwidth estimate has now changed sufficiently and enough time has passed,
+  // but not enough packets have been sent.
+  int64_t srtt_ms =
+      sent_packet_manager->GetRttStats()->smoothed_rtt().ToMilliseconds();
+  now = now + QuicTime::Delta::FromMilliseconds(
+                  kMinIntervalBetweenServerConfigUpdatesRTTs * srtt_ms);
+  session_->OnCongestionWindowChange(now);
+
+  // The connection no longer has pending data to be written.
+  session_->OnCanWrite();
+  EXPECT_FALSE(session_->HasDataToWrite());
+  session_->OnCongestionWindowChange(now);
+
+  // Bandwidth estimate has now changed sufficiently, enough time has passed,
+  // and enough packets have been sent.
+  SerializedPacket packet(
+      QuicPacketNumber(1) + kMinPacketsBetweenServerConfigUpdates,
+      PACKET_4BYTE_PACKET_NUMBER, nullptr, 1000, false, false);
+  sent_packet_manager->OnPacketSent(&packet, QuicPacketNumber(), now,
+                                    NOT_RETRANSMISSION,
+                                    HAS_RETRANSMITTABLE_DATA);
+
+  // Verify that the proto has exactly the values we expect.
+  CachedNetworkParameters expected_network_params;
+  expected_network_params.set_bandwidth_estimate_bytes_per_second(
+      bandwidth_recorder.BandwidthEstimate().ToBytesPerSecond());
+  expected_network_params.set_max_bandwidth_estimate_bytes_per_second(
+      bandwidth_recorder.MaxBandwidthEstimate().ToBytesPerSecond());
+  expected_network_params.set_max_bandwidth_timestamp_seconds(
+      bandwidth_recorder.MaxBandwidthTimestamp());
+  expected_network_params.set_min_rtt_ms(session_->connection()
+                                             ->sent_packet_manager()
+                                             .GetRttStats()
+                                             ->min_rtt()
+                                             .ToMilliseconds());
+  expected_network_params.set_previous_connection_state(
+      CachedNetworkParameters::CONGESTION_AVOIDANCE);
+  expected_network_params.set_timestamp(
+      session_->connection()->clock()->WallNow().ToUNIXSeconds());
+  expected_network_params.set_serving_region(serving_region);
+
+  EXPECT_CALL(*crypto_stream,
+              SendServerConfigUpdate(EqualsProto(expected_network_params)))
+      .Times(1);
+  EXPECT_CALL(*connection_, OnSendConnectionState(_)).Times(1);
+  session_->OnCongestionWindowChange(now);
+}
+
+TEST_P(QuicServerSessionBaseTest, BandwidthResumptionExperiment) {
+  if (GetParam().handshake_protocol == PROTOCOL_TLS1_3) {
+    // This test relies on resumption, which is not currently supported by the
+    // TLS handshake.
+    // TODO(nharper): Add support for resumption to the TLS handshake.
+    return;
+  }
+  // Test that if a client provides a CachedNetworkParameters with the same
+  // serving region as the current server, and which was made within an hour of
+  // now, that this data is passed down to the send algorithm.
+
+  // Client has sent kBWRE connection option to trigger bandwidth resumption.
+  QuicTagVector copt;
+  copt.push_back(kBWRE);
+  QuicConfigPeer::SetReceivedConnectionOptions(session_->config(), copt);
+
+  const QuicString kTestServingRegion = "a serving region";
+  session_->set_serving_region(kTestServingRegion);
+
+  // Set the time to be one hour + one second from the 0 baseline.
+  connection_->AdvanceTime(
+      QuicTime::Delta::FromSeconds(kNumSecondsPerHour + 1));
+
+  QuicCryptoServerStream* crypto_stream = static_cast<QuicCryptoServerStream*>(
+      QuicSessionPeer::GetMutableCryptoStream(session_.get()));
+
+  // No effect if no CachedNetworkParameters provided.
+  EXPECT_CALL(*connection_, ResumeConnectionState(_, _)).Times(0);
+  session_->OnConfigNegotiated();
+
+  // No effect if CachedNetworkParameters provided, but different serving
+  // regions.
+  CachedNetworkParameters cached_network_params;
+  cached_network_params.set_bandwidth_estimate_bytes_per_second(1);
+  cached_network_params.set_serving_region("different serving region");
+  crypto_stream->SetPreviousCachedNetworkParams(cached_network_params);
+  EXPECT_CALL(*connection_, ResumeConnectionState(_, _)).Times(0);
+  session_->OnConfigNegotiated();
+
+  // Same serving region, but timestamp is too old, should have no effect.
+  cached_network_params.set_serving_region(kTestServingRegion);
+  cached_network_params.set_timestamp(0);
+  crypto_stream->SetPreviousCachedNetworkParams(cached_network_params);
+  EXPECT_CALL(*connection_, ResumeConnectionState(_, _)).Times(0);
+  session_->OnConfigNegotiated();
+
+  // Same serving region, and timestamp is recent: estimate is stored.
+  cached_network_params.set_timestamp(
+      connection_->clock()->WallNow().ToUNIXSeconds());
+  crypto_stream->SetPreviousCachedNetworkParams(cached_network_params);
+  EXPECT_CALL(*connection_, ResumeConnectionState(_, _)).Times(1);
+  session_->OnConfigNegotiated();
+}
+
+TEST_P(QuicServerSessionBaseTest, BandwidthMaxEnablesResumption) {
+  EXPECT_FALSE(
+      QuicServerSessionBasePeer::IsBandwidthResumptionEnabled(session_.get()));
+
+  // Client has sent kBWMX connection option to trigger bandwidth resumption.
+  QuicTagVector copt;
+  copt.push_back(kBWMX);
+  QuicConfigPeer::SetReceivedConnectionOptions(session_->config(), copt);
+  session_->OnConfigNegotiated();
+  EXPECT_TRUE(
+      QuicServerSessionBasePeer::IsBandwidthResumptionEnabled(session_.get()));
+}
+
+TEST_P(QuicServerSessionBaseTest, NoBandwidthResumptionByDefault) {
+  EXPECT_FALSE(
+      QuicServerSessionBasePeer::IsBandwidthResumptionEnabled(session_.get()));
+  session_->OnConfigNegotiated();
+  EXPECT_FALSE(
+      QuicServerSessionBasePeer::IsBandwidthResumptionEnabled(session_.get()));
+}
+
+// Tests which check the lifetime management of data members of
+// QuicCryptoServerStream objects when async GetProof is in use.
+class StreamMemberLifetimeTest : public QuicServerSessionBaseTest {
+ public:
+  StreamMemberLifetimeTest()
+      : QuicServerSessionBaseTest(
+            std::unique_ptr<FakeProofSource>(new FakeProofSource())),
+        crypto_config_peer_(&crypto_config_) {
+    GetFakeProofSource()->Activate();
+  }
+
+  FakeProofSource* GetFakeProofSource() const {
+    return static_cast<FakeProofSource*>(crypto_config_peer_.GetProofSource());
+  }
+
+ private:
+  QuicCryptoServerConfigPeer crypto_config_peer_;
+};
+
+INSTANTIATE_TEST_SUITE_P(StreamMemberLifetimeTests,
+                         StreamMemberLifetimeTest,
+                         ::testing::ValuesIn(AllSupportedVersions()));
+
+// Trigger an operation which causes an async invocation of
+// ProofSource::GetProof.  Delay the completion of the operation until after the
+// stream has been destroyed, and verify that there are no memory bugs.
+TEST_P(StreamMemberLifetimeTest, Basic) {
+  if (GetParam().handshake_protocol == PROTOCOL_TLS1_3) {
+    // This test depends on the QUIC crypto protocol, so it is disabled for the
+    // TLS handshake.
+    // TODO(nharper): Fix this test so it doesn't rely on QUIC crypto.
+    return;
+  }
+  SetQuicReloadableFlag(enable_quic_stateless_reject_support, true);
+  SetQuicReloadableFlag(quic_use_cheap_stateless_rejects, true);
+
+  const QuicClock* clock = helper_.GetClock();
+  CryptoHandshakeMessage chlo = crypto_test_utils::GenerateDefaultInchoateCHLO(
+      clock, GetParam().transport_version, &crypto_config_);
+  chlo.SetVector(kCOPT, QuicTagVector{kSREJ});
+  std::vector<ParsedQuicVersion> packet_version_list = {GetParam()};
+  std::unique_ptr<QuicEncryptedPacket> packet(ConstructEncryptedPacket(
+      TestConnectionId(1), EmptyQuicConnectionId(), true, false, 1,
+      QuicString(chlo.GetSerialized().AsStringPiece()), CONNECTION_ID_PRESENT,
+      CONNECTION_ID_ABSENT, PACKET_4BYTE_PACKET_NUMBER, &packet_version_list));
+
+  EXPECT_CALL(stream_helper_, CanAcceptClientHello(_, _, _, _, _))
+      .WillOnce(testing::Return(true));
+  EXPECT_CALL(stream_helper_, GenerateConnectionIdForReject(_, _))
+      .WillOnce(testing::Return(TestConnectionId(12345)));
+
+  // Set the current packet
+  QuicConnectionPeer::SetCurrentPacket(session_->connection(),
+                                       packet->AsStringPiece());
+
+  // Yes, this is horrible.  But it's the easiest way to trigger the behavior we
+  // need to exercise.
+  QuicCryptoServerStreamBase* crypto_stream =
+      const_cast<QuicCryptoServerStreamBase*>(session_->crypto_stream());
+
+  // Feed the CHLO into the crypto stream, which will trigger a call to
+  // ProofSource::GetProof
+  crypto_test_utils::SendHandshakeMessageToStream(crypto_stream, chlo,
+                                                  Perspective::IS_CLIENT);
+  ASSERT_EQ(GetFakeProofSource()->NumPendingCallbacks(), 1);
+
+  // Destroy the stream
+  session_.reset();
+
+  // Allow the async ProofSource::GetProof call to complete.  Verify (under
+  // memory access checkers) that this does not result in accesses to any
+  // freed memory from the session or its subobjects.
+  GetFakeProofSource()->InvokePendingCallback(0);
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quic/core/http/quic_spdy_client_session.cc b/quic/core/http/quic_spdy_client_session.cc
new file mode 100644
index 0000000..9e8170b
--- /dev/null
+++ b/quic/core/http/quic_spdy_client_session.cc
@@ -0,0 +1,182 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/third_party/quiche/src/quic/core/http/quic_spdy_client_session.h"
+
+#include "net/third_party/quiche/src/quic/core/crypto/crypto_protocol.h"
+#include "net/third_party/quiche/src/quic/core/http/quic_spdy_client_stream.h"
+#include "net/third_party/quiche/src/quic/core/http/spdy_utils.h"
+#include "net/third_party/quiche/src/quic/core/quic_server_id.h"
+#include "net/third_party/quiche/src/quic/core/quic_utils.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_bug_tracker.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_flag_utils.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_flags.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_logging.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_ptr_util.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_string.h"
+
+namespace quic {
+
+QuicSpdyClientSession::QuicSpdyClientSession(
+    const QuicConfig& config,
+    const ParsedQuicVersionVector& supported_versions,
+    QuicConnection* connection,
+    const QuicServerId& server_id,
+    QuicCryptoClientConfig* crypto_config,
+    QuicClientPushPromiseIndex* push_promise_index)
+    : QuicSpdyClientSessionBase(connection,
+                                push_promise_index,
+                                config,
+                                supported_versions),
+      server_id_(server_id),
+      crypto_config_(crypto_config),
+      respect_goaway_(true) {}
+
+QuicSpdyClientSession::~QuicSpdyClientSession() = default;
+
+void QuicSpdyClientSession::Initialize() {
+  crypto_stream_ = CreateQuicCryptoStream();
+  QuicSpdyClientSessionBase::Initialize();
+}
+
+void QuicSpdyClientSession::OnProofValid(
+    const QuicCryptoClientConfig::CachedState& /*cached*/) {}
+
+void QuicSpdyClientSession::OnProofVerifyDetailsAvailable(
+    const ProofVerifyDetails& /*verify_details*/) {}
+
+bool QuicSpdyClientSession::ShouldCreateOutgoingBidirectionalStream() {
+  if (!crypto_stream_->encryption_established()) {
+    QUIC_DLOG(INFO) << "Encryption not active so no outgoing stream created.";
+    return false;
+  }
+  if (!GetQuicReloadableFlag(quic_use_common_stream_check) &&
+      connection()->transport_version() != QUIC_VERSION_99) {
+    if (GetNumOpenOutgoingStreams() >=
+        stream_id_manager().max_open_outgoing_streams()) {
+      QUIC_DLOG(INFO) << "Failed to create a new outgoing stream. "
+                      << "Already " << GetNumOpenOutgoingStreams() << " open.";
+      return false;
+    }
+    if (goaway_received() && respect_goaway_) {
+      QUIC_DLOG(INFO) << "Failed to create a new outgoing stream. "
+                      << "Already received goaway.";
+      return false;
+    }
+    return true;
+  }
+  if (goaway_received() && respect_goaway_) {
+    QUIC_DLOG(INFO) << "Failed to create a new outgoing stream. "
+                    << "Already received goaway.";
+    return false;
+  }
+  QUIC_RELOADABLE_FLAG_COUNT_N(quic_use_common_stream_check, 1, 2);
+  return CanOpenNextOutgoingBidirectionalStream();
+}
+
+bool QuicSpdyClientSession::ShouldCreateOutgoingUnidirectionalStream() {
+  QUIC_BUG << "Try to create outgoing unidirectional client data streams";
+  return false;
+}
+
+QuicSpdyClientStream*
+QuicSpdyClientSession::CreateOutgoingBidirectionalStream() {
+  if (!ShouldCreateOutgoingBidirectionalStream()) {
+    return nullptr;
+  }
+  std::unique_ptr<QuicSpdyClientStream> stream = CreateClientStream();
+  QuicSpdyClientStream* stream_ptr = stream.get();
+  ActivateStream(std::move(stream));
+  return stream_ptr;
+}
+
+QuicSpdyClientStream*
+QuicSpdyClientSession::CreateOutgoingUnidirectionalStream() {
+  QUIC_BUG << "Try to create outgoing unidirectional client data streams";
+  return nullptr;
+}
+
+std::unique_ptr<QuicSpdyClientStream>
+QuicSpdyClientSession::CreateClientStream() {
+  return QuicMakeUnique<QuicSpdyClientStream>(
+      GetNextOutgoingBidirectionalStreamId(), this, BIDIRECTIONAL);
+}
+
+QuicCryptoClientStreamBase* QuicSpdyClientSession::GetMutableCryptoStream() {
+  return crypto_stream_.get();
+}
+
+const QuicCryptoClientStreamBase* QuicSpdyClientSession::GetCryptoStream()
+    const {
+  return crypto_stream_.get();
+}
+
+void QuicSpdyClientSession::CryptoConnect() {
+  DCHECK(flow_controller());
+  crypto_stream_->CryptoConnect();
+}
+
+int QuicSpdyClientSession::GetNumSentClientHellos() const {
+  return crypto_stream_->num_sent_client_hellos();
+}
+
+int QuicSpdyClientSession::GetNumReceivedServerConfigUpdates() const {
+  return crypto_stream_->num_scup_messages_received();
+}
+
+bool QuicSpdyClientSession::ShouldCreateIncomingStream(QuicStreamId id) {
+  if (!connection()->connected()) {
+    QUIC_BUG << "ShouldCreateIncomingStream called when disconnected";
+    return false;
+  }
+  if (goaway_received() && respect_goaway_) {
+    QUIC_DLOG(INFO) << "Failed to create a new outgoing stream. "
+                    << "Already received goaway.";
+    return false;
+  }
+  if (QuicUtils::IsClientInitiatedStreamId(connection()->transport_version(),
+                                           id) ||
+      (connection()->transport_version() == QUIC_VERSION_99 &&
+       QuicUtils::IsBidirectionalStreamId(id))) {
+    QUIC_LOG(WARNING) << "Received invalid push stream id " << id;
+    connection()->CloseConnection(
+        QUIC_INVALID_STREAM_ID,
+        "Server created non write unidirectional stream",
+        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+    return false;
+  }
+  return true;
+}
+
+QuicSpdyStream* QuicSpdyClientSession::CreateIncomingStream(
+    PendingStream pending) {
+  QuicSpdyStream* stream =
+      new QuicSpdyClientStream(std::move(pending), this, READ_UNIDIRECTIONAL);
+  ActivateStream(QuicWrapUnique(stream));
+  return stream;
+}
+
+QuicSpdyStream* QuicSpdyClientSession::CreateIncomingStream(QuicStreamId id) {
+  if (!ShouldCreateIncomingStream(id)) {
+    return nullptr;
+  }
+  QuicSpdyStream* stream =
+      new QuicSpdyClientStream(id, this, READ_UNIDIRECTIONAL);
+  ActivateStream(QuicWrapUnique(stream));
+  return stream;
+}
+
+std::unique_ptr<QuicCryptoClientStreamBase>
+QuicSpdyClientSession::CreateQuicCryptoStream() {
+  return QuicMakeUnique<QuicCryptoClientStream>(
+      server_id_, this,
+      crypto_config_->proof_verifier()->CreateDefaultContext(), crypto_config_,
+      this);
+}
+
+bool QuicSpdyClientSession::IsAuthorized(const QuicString& authority) {
+  return true;
+}
+
+}  // namespace quic
diff --git a/quic/core/http/quic_spdy_client_session.h b/quic/core/http/quic_spdy_client_session.h
new file mode 100644
index 0000000..c92753b
--- /dev/null
+++ b/quic/core/http/quic_spdy_client_session.h
@@ -0,0 +1,104 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// A client specific QuicSession subclass.
+
+#ifndef QUICHE_QUIC_CORE_HTTP_QUIC_SPDY_CLIENT_SESSION_H_
+#define QUICHE_QUIC_CORE_HTTP_QUIC_SPDY_CLIENT_SESSION_H_
+
+#include <memory>
+
+#include "base/macros.h"
+#include "net/third_party/quiche/src/quic/core/http/quic_spdy_client_session_base.h"
+#include "net/third_party/quiche/src/quic/core/http/quic_spdy_client_stream.h"
+#include "net/third_party/quiche/src/quic/core/quic_crypto_client_stream.h"
+#include "net/third_party/quiche/src/quic/core/quic_packets.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_string.h"
+
+namespace quic {
+
+class QuicConnection;
+class QuicServerId;
+
+class QuicSpdyClientSession : public QuicSpdyClientSessionBase {
+ public:
+  // Takes ownership of |connection|. Caller retains ownership of
+  // |promised_by_url|.
+  QuicSpdyClientSession(const QuicConfig& config,
+                        const ParsedQuicVersionVector& supported_versions,
+                        QuicConnection* connection,
+                        const QuicServerId& server_id,
+                        QuicCryptoClientConfig* crypto_config,
+                        QuicClientPushPromiseIndex* push_promise_index);
+  QuicSpdyClientSession(const QuicSpdyClientSession&) = delete;
+  QuicSpdyClientSession& operator=(const QuicSpdyClientSession&) = delete;
+  ~QuicSpdyClientSession() override;
+  // Set up the QuicSpdyClientSession. Must be called prior to use.
+  void Initialize() override;
+
+  // QuicSession methods:
+  QuicSpdyClientStream* CreateOutgoingBidirectionalStream() override;
+  QuicSpdyClientStream* CreateOutgoingUnidirectionalStream() override;
+  QuicCryptoClientStreamBase* GetMutableCryptoStream() override;
+  const QuicCryptoClientStreamBase* GetCryptoStream() const override;
+
+  bool IsAuthorized(const QuicString& authority) override;
+
+  // QuicSpdyClientSessionBase methods:
+  void OnProofValid(const QuicCryptoClientConfig::CachedState& cached) override;
+  void OnProofVerifyDetailsAvailable(
+      const ProofVerifyDetails& verify_details) override;
+
+  // Performs a crypto handshake with the server.
+  virtual void CryptoConnect();
+
+  // Returns the number of client hello messages that have been sent on the
+  // crypto stream. If the handshake has completed then this is one greater
+  // than the number of round-trips needed for the handshake.
+  int GetNumSentClientHellos() const;
+
+  int GetNumReceivedServerConfigUpdates() const;
+
+  void set_respect_goaway(bool respect_goaway) {
+    respect_goaway_ = respect_goaway;
+  }
+
+ protected:
+  // QuicSession methods:
+  QuicSpdyStream* CreateIncomingStream(QuicStreamId id) override;
+  QuicSpdyStream* CreateIncomingStream(PendingStream pending) override;
+  // If an outgoing stream can be created, return true.
+  bool ShouldCreateOutgoingBidirectionalStream() override;
+  bool ShouldCreateOutgoingUnidirectionalStream() override;
+
+  // If an incoming stream can be created, return true.
+  // TODO(fayang): move this up to QuicSpdyClientSessionBase.
+  bool ShouldCreateIncomingStream(QuicStreamId id) override;
+
+  // Create the crypto stream. Called by Initialize().
+  virtual std::unique_ptr<QuicCryptoClientStreamBase> CreateQuicCryptoStream();
+
+  // Unlike CreateOutgoingBidirectionalStream, which applies a bunch of
+  // sanity checks, this simply returns a new QuicSpdyClientStream. This may be
+  // used by subclasses which want to use a subclass of QuicSpdyClientStream for
+  // streams but wish to use the sanity checks in
+  // CreateOutgoingBidirectionalStream.
+  virtual std::unique_ptr<QuicSpdyClientStream> CreateClientStream();
+
+  const QuicServerId& server_id() { return server_id_; }
+  QuicCryptoClientConfig* crypto_config() { return crypto_config_; }
+
+ private:
+  std::unique_ptr<QuicCryptoClientStreamBase> crypto_stream_;
+  QuicServerId server_id_;
+  QuicCryptoClientConfig* crypto_config_;
+
+  // If this is set to false, the client will ignore server GOAWAYs and allow
+  // the creation of streams regardless of the high chance they will fail.
+  bool respect_goaway_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_HTTP_QUIC_SPDY_CLIENT_SESSION_H_
diff --git a/quic/core/http/quic_spdy_client_session_base.cc b/quic/core/http/quic_spdy_client_session_base.cc
new file mode 100644
index 0000000..5a8fe8d
--- /dev/null
+++ b/quic/core/http/quic_spdy_client_session_base.cc
@@ -0,0 +1,209 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/third_party/quiche/src/quic/core/http/quic_spdy_client_session_base.h"
+
+#include "net/third_party/quiche/src/quic/core/http/quic_client_promised_info.h"
+#include "net/third_party/quiche/src/quic/core/http/spdy_utils.h"
+#include "net/third_party/quiche/src/quic/core/quic_utils.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_flags.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_logging.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_string.h"
+
+using spdy::SpdyHeaderBlock;
+
+namespace quic {
+
+QuicSpdyClientSessionBase::QuicSpdyClientSessionBase(
+    QuicConnection* connection,
+    QuicClientPushPromiseIndex* push_promise_index,
+    const QuicConfig& config,
+    const ParsedQuicVersionVector& supported_versions)
+    : QuicSpdySession(connection, nullptr, config, supported_versions),
+      push_promise_index_(push_promise_index),
+      largest_promised_stream_id_(
+          QuicUtils::GetInvalidStreamId(connection->transport_version())) {}
+
+QuicSpdyClientSessionBase::~QuicSpdyClientSessionBase() {
+  //  all promised streams for this session
+  for (auto& it : promised_by_id_) {
+    QUIC_DVLOG(1) << "erase stream " << it.first << " url " << it.second->url();
+    push_promise_index_->promised_by_url()->erase(it.second->url());
+  }
+  delete connection();
+}
+
+void QuicSpdyClientSessionBase::OnConfigNegotiated() {
+  QuicSpdySession::OnConfigNegotiated();
+}
+
+void QuicSpdyClientSessionBase::OnCryptoHandshakeEvent(
+    CryptoHandshakeEvent event) {
+  QuicSpdySession::OnCryptoHandshakeEvent(event);
+}
+
+void QuicSpdyClientSessionBase::OnInitialHeadersComplete(
+    QuicStreamId stream_id,
+    const SpdyHeaderBlock& response_headers) {
+  // Note that the strong ordering of the headers stream means that
+  // QuicSpdyClientStream::OnPromiseHeadersComplete must have already
+  // been called (on the associated stream) if this is a promised
+  // stream. However, this stream may not have existed at this time,
+  // hence the need to query the session.
+  QuicClientPromisedInfo* promised = GetPromisedById(stream_id);
+  if (!promised)
+    return;
+
+  promised->OnResponseHeaders(response_headers);
+}
+
+void QuicSpdyClientSessionBase::OnPromiseHeaderList(
+    QuicStreamId stream_id,
+    QuicStreamId promised_stream_id,
+    size_t frame_len,
+    const QuicHeaderList& header_list) {
+  if (QuicContainsKey(static_streams(), stream_id)) {
+    connection()->CloseConnection(
+        QUIC_INVALID_HEADERS_STREAM_DATA, "stream is static",
+        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+    return;
+  }
+  if (promised_stream_id !=
+          QuicUtils::GetInvalidStreamId(connection()->transport_version()) &&
+      largest_promised_stream_id_ !=
+          QuicUtils::GetInvalidStreamId(connection()->transport_version()) &&
+      promised_stream_id <= largest_promised_stream_id_) {
+    connection()->CloseConnection(
+        QUIC_INVALID_STREAM_ID,
+        "Received push stream id lesser or equal to the"
+        " last accepted before",
+        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+    return;
+  }
+  if (!IsIncomingStream(promised_stream_id)) {
+    connection()->CloseConnection(
+        QUIC_INVALID_STREAM_ID, "Received push stream id for outgoing stream.",
+        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+    return;
+  }
+  largest_promised_stream_id_ = promised_stream_id;
+
+  QuicSpdyStream* stream = GetSpdyDataStream(stream_id);
+  if (!stream) {
+    // It's quite possible to receive headers after a stream has been reset.
+    return;
+  }
+  stream->OnPromiseHeaderList(promised_stream_id, frame_len, header_list);
+}
+
+bool QuicSpdyClientSessionBase::HandlePromised(QuicStreamId /* associated_id */,
+                                               QuicStreamId promised_id,
+                                               const SpdyHeaderBlock& headers) {
+  // Due to pathalogical packet re-ordering, it is possible that
+  // frames for the promised stream have already arrived, and the
+  // promised stream could be active or closed.
+  if (IsClosedStream(promised_id)) {
+    // There was a RST on the data stream already, perhaps
+    // QUIC_REFUSED_STREAM?
+    QUIC_DVLOG(1) << "Promise ignored for stream " << promised_id
+                  << " that is already closed";
+    return false;
+  }
+
+  if (push_promise_index_->promised_by_url()->size() >= get_max_promises()) {
+    QUIC_DVLOG(1) << "Too many promises, rejecting promise for stream "
+                  << promised_id;
+    ResetPromised(promised_id, QUIC_REFUSED_STREAM);
+    return false;
+  }
+
+  const QuicString url = SpdyUtils::GetPromisedUrlFromHeaders(headers);
+  QuicClientPromisedInfo* old_promised = GetPromisedByUrl(url);
+  if (old_promised) {
+    QUIC_DVLOG(1) << "Promise for stream " << promised_id
+                  << " is duplicate URL " << url
+                  << " of previous promise for stream " << old_promised->id();
+    ResetPromised(promised_id, QUIC_DUPLICATE_PROMISE_URL);
+    return false;
+  }
+
+  if (GetPromisedById(promised_id)) {
+    // OnPromiseHeadersComplete() would have closed the connection if
+    // promised id is a duplicate.
+    QUIC_BUG << "Duplicate promise for id " << promised_id;
+    return false;
+  }
+
+  QuicClientPromisedInfo* promised =
+      new QuicClientPromisedInfo(this, promised_id, url);
+  std::unique_ptr<QuicClientPromisedInfo> promised_owner(promised);
+  promised->Init();
+  QUIC_DVLOG(1) << "stream " << promised_id << " emplace url " << url;
+  (*push_promise_index_->promised_by_url())[url] = promised;
+  promised_by_id_[promised_id] = std::move(promised_owner);
+  bool result = promised->OnPromiseHeaders(headers);
+  if (result) {
+    DCHECK(promised_by_id_.find(promised_id) != promised_by_id_.end());
+  }
+  return result;
+}
+
+QuicClientPromisedInfo* QuicSpdyClientSessionBase::GetPromisedByUrl(
+    const QuicString& url) {
+  auto it = push_promise_index_->promised_by_url()->find(url);
+  if (it != push_promise_index_->promised_by_url()->end()) {
+    return it->second;
+  }
+  return nullptr;
+}
+
+QuicClientPromisedInfo* QuicSpdyClientSessionBase::GetPromisedById(
+    const QuicStreamId id) {
+  auto it = promised_by_id_.find(id);
+  if (it != promised_by_id_.end()) {
+    return it->second.get();
+  }
+  return nullptr;
+}
+
+QuicSpdyStream* QuicSpdyClientSessionBase::GetPromisedStream(
+    const QuicStreamId id) {
+  DynamicStreamMap::iterator it = dynamic_streams().find(id);
+  if (it != dynamic_streams().end()) {
+    return static_cast<QuicSpdyStream*>(it->second.get());
+  }
+  return nullptr;
+}
+
+void QuicSpdyClientSessionBase::DeletePromised(
+    QuicClientPromisedInfo* promised) {
+  push_promise_index_->promised_by_url()->erase(promised->url());
+  // Since promised_by_id_ contains the unique_ptr, this will destroy
+  // promised.
+  promised_by_id_.erase(promised->id());
+  headers_stream()->MaybeReleaseSequencerBuffer();
+}
+
+void QuicSpdyClientSessionBase::OnPushStreamTimedOut(QuicStreamId stream_id) {}
+
+void QuicSpdyClientSessionBase::ResetPromised(
+    QuicStreamId id,
+    QuicRstStreamErrorCode error_code) {
+  SendRstStream(id, error_code, 0);
+  if (!IsOpenStream(id)) {
+    MaybeIncreaseLargestPeerStreamId(id);
+  }
+}
+
+void QuicSpdyClientSessionBase::CloseStreamInner(QuicStreamId stream_id,
+                                                 bool locally_reset) {
+  QuicSpdySession::CloseStreamInner(stream_id, locally_reset);
+  headers_stream()->MaybeReleaseSequencerBuffer();
+}
+
+bool QuicSpdyClientSessionBase::ShouldReleaseHeadersStreamSequencerBuffer() {
+  return num_active_requests() == 0 && promised_by_id_.empty();
+}
+
+}  // namespace quic
diff --git a/quic/core/http/quic_spdy_client_session_base.h b/quic/core/http/quic_spdy_client_session_base.h
new file mode 100644
index 0000000..f27708c
--- /dev/null
+++ b/quic/core/http/quic_spdy_client_session_base.h
@@ -0,0 +1,141 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_HTTP_QUIC_SPDY_CLIENT_SESSION_BASE_H_
+#define QUICHE_QUIC_CORE_HTTP_QUIC_SPDY_CLIENT_SESSION_BASE_H_
+
+#include "base/macros.h"
+#include "net/third_party/quiche/src/quic/core/quic_crypto_client_stream.h"
+#include "net/third_party/quiche/src/quic/core/http/quic_spdy_session.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_containers.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_export.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_string.h"
+
+namespace quic {
+
+class QuicClientPromisedInfo;
+class QuicClientPushPromiseIndex;
+class QuicSpdyClientStream;
+
+// For client/http layer code. Lookup promised streams based on
+// matching promised request url. The same map can be shared across
+// multiple sessions, since cross-origin pushes are allowed (subject
+// to authority constraints).  Clients should use this map to enforce
+// session affinity for requests corresponding to cross-origin push
+// promised streams.
+using QuicPromisedByUrlMap =
+    QuicUnorderedMap<QuicString, QuicClientPromisedInfo*>;
+
+// The maximum time a promises stream can be reserved without being
+// claimed by a client request.
+const int64_t kPushPromiseTimeoutSecs = 60;
+
+// Base class for all client-specific QuicSession subclasses.
+class QUIC_EXPORT_PRIVATE QuicSpdyClientSessionBase
+    : public QuicSpdySession,
+      public QuicCryptoClientStream::ProofHandler {
+ public:
+  // Takes ownership of |connection|. Caller retains ownership of
+  // |promised_by_url|.
+  QuicSpdyClientSessionBase(QuicConnection* connection,
+                            QuicClientPushPromiseIndex* push_promise_index,
+                            const QuicConfig& config,
+                            const ParsedQuicVersionVector& supported_versions);
+  QuicSpdyClientSessionBase(const QuicSpdyClientSessionBase&) = delete;
+  QuicSpdyClientSessionBase& operator=(const QuicSpdyClientSessionBase&) =
+      delete;
+
+  ~QuicSpdyClientSessionBase() override;
+
+  void OnConfigNegotiated() override;
+
+  // Override base class to set FEC policy before any data is sent by client.
+  void OnCryptoHandshakeEvent(CryptoHandshakeEvent event) override;
+
+  // Called by |headers_stream_| when push promise headers have been
+  // completely received.
+  void OnPromiseHeaderList(QuicStreamId stream_id,
+                           QuicStreamId promised_stream_id,
+                           size_t frame_len,
+                           const QuicHeaderList& header_list) override;
+
+  // Called by |QuicSpdyClientStream| on receipt of response headers,
+  // needed to detect promised server push streams, as part of
+  // client-request to push-stream rendezvous.
+  void OnInitialHeadersComplete(QuicStreamId stream_id,
+                                const spdy::SpdyHeaderBlock& response_headers);
+
+  // Called by |QuicSpdyClientStream| on receipt of PUSH_PROMISE, does
+  // some session level validation and creates the
+  // |QuicClientPromisedInfo| inserting into maps by (promised) id and
+  // url. Returns true if a new push promise is accepted. Resets the promised
+  // stream and returns false otherwise.
+  virtual bool HandlePromised(QuicStreamId associated_id,
+                              QuicStreamId promised_id,
+                              const spdy::SpdyHeaderBlock& headers);
+
+  // For cross-origin server push, this should verify the server is
+  // authoritative per [RFC2818], Section 3.  Roughly, subjectAltName
+  // list in the certificate should contain a matching DNS name, or IP
+  // address.  |hostname| is derived from the ":authority" header field of
+  // the PUSH_PROMISE frame, port if present there will be dropped.
+  virtual bool IsAuthorized(const QuicString& hostname) = 0;
+
+  // Session retains ownership.
+  QuicClientPromisedInfo* GetPromisedByUrl(const QuicString& url);
+  // Session retains ownership.
+  QuicClientPromisedInfo* GetPromisedById(const QuicStreamId id);
+
+  //
+  QuicSpdyStream* GetPromisedStream(const QuicStreamId id);
+
+  // Removes |promised| from the maps by url.
+  void ErasePromisedByUrl(QuicClientPromisedInfo* promised);
+
+  // Removes |promised| from the maps by url and id and destroys
+  // promised.
+  virtual void DeletePromised(QuicClientPromisedInfo* promised);
+
+  virtual void OnPushStreamTimedOut(QuicStreamId stream_id);
+
+  // Sends Rst for the stream, and makes sure that future calls to
+  // IsClosedStream(id) return true, which ensures that any subsequent
+  // frames related to this stream will be ignored (modulo flow
+  // control accounting).
+  void ResetPromised(QuicStreamId id, QuicRstStreamErrorCode error_code);
+
+  // Release headers stream's sequencer buffer if it's empty.
+  void CloseStreamInner(QuicStreamId stream_id, bool locally_reset) override;
+
+  // Returns true if there are no active requests and no promised streams.
+  bool ShouldReleaseHeadersStreamSequencerBuffer() override;
+
+  size_t get_max_promises() const {
+    return max_open_incoming_unidirectional_streams() *
+           kMaxPromisedStreamsMultiplier;
+  }
+
+  QuicClientPushPromiseIndex* push_promise_index() {
+    return push_promise_index_;
+  }
+
+ private:
+  // For QuicSpdyClientStream to detect that a response corresponds to a
+  // promise.
+  using QuicPromisedByIdMap =
+      QuicUnorderedMap<QuicStreamId, std::unique_ptr<QuicClientPromisedInfo>>;
+
+  // As per rfc7540, section 10.5: track promise streams in "reserved
+  // (remote)".  The primary key is URL from the promise request
+  // headers.  The promised stream id is a secondary key used to get
+  // promise info when the response headers of the promised stream
+  // arrive.
+  QuicClientPushPromiseIndex* push_promise_index_;
+  QuicPromisedByIdMap promised_by_id_;
+  QuicStreamId largest_promised_stream_id_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_HTTP_QUIC_SPDY_CLIENT_SESSION_BASE_H_
diff --git a/quic/core/http/quic_spdy_client_session_test.cc b/quic/core/http/quic_spdy_client_session_test.cc
new file mode 100644
index 0000000..3a40043
--- /dev/null
+++ b/quic/core/http/quic_spdy_client_session_test.cc
@@ -0,0 +1,788 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/third_party/quiche/src/quic/core/http/quic_spdy_client_session.h"
+
+#include <memory>
+#include <vector>
+
+#include "net/third_party/quiche/src/quic/core/crypto/aes_128_gcm_12_encrypter.h"
+#include "net/third_party/quiche/src/quic/core/http/quic_spdy_client_stream.h"
+#include "net/third_party/quiche/src/quic/core/http/spdy_utils.h"
+#include "net/third_party/quiche/src/quic/core/quic_utils.h"
+#include "net/third_party/quiche/src/quic/core/tls_client_handshaker.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_arraysize.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_ptr_util.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_socket_address.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_str_cat.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_string.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_test.h"
+#include "net/third_party/quiche/src/quic/test_tools/crypto_test_utils.h"
+#include "net/third_party/quiche/src/quic/test_tools/mock_quic_spdy_client_stream.h"
+#include "net/third_party/quiche/src/quic/test_tools/quic_config_peer.h"
+#include "net/third_party/quiche/src/quic/test_tools/quic_connection_peer.h"
+#include "net/third_party/quiche/src/quic/test_tools/quic_framer_peer.h"
+#include "net/third_party/quiche/src/quic/test_tools/quic_packet_creator_peer.h"
+#include "net/third_party/quiche/src/quic/test_tools/quic_session_peer.h"
+#include "net/third_party/quiche/src/quic/test_tools/quic_spdy_session_peer.h"
+#include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h"
+
+using spdy::SpdyHeaderBlock;
+using testing::_;
+using testing::AnyNumber;
+using testing::Invoke;
+using testing::Truly;
+
+namespace quic {
+namespace test {
+namespace {
+
+const char kServerHostname[] = "test.example.com";
+const uint16_t kPort = 443;
+
+class TestQuicSpdyClientSession : public QuicSpdyClientSession {
+ public:
+  explicit TestQuicSpdyClientSession(
+      const QuicConfig& config,
+      const ParsedQuicVersionVector& supported_versions,
+      QuicConnection* connection,
+      const QuicServerId& server_id,
+      QuicCryptoClientConfig* crypto_config,
+      QuicClientPushPromiseIndex* push_promise_index)
+      : QuicSpdyClientSession(config,
+                              supported_versions,
+                              connection,
+                              server_id,
+                              crypto_config,
+                              push_promise_index) {}
+
+  std::unique_ptr<QuicSpdyClientStream> CreateClientStream() override {
+    return QuicMakeUnique<MockQuicSpdyClientStream>(
+        GetNextOutgoingBidirectionalStreamId(), this, BIDIRECTIONAL);
+  }
+
+  MockQuicSpdyClientStream* CreateIncomingStream(QuicStreamId id) override {
+    if (!ShouldCreateIncomingStream(id)) {
+      return nullptr;
+    }
+    MockQuicSpdyClientStream* stream =
+        new MockQuicSpdyClientStream(id, this, READ_UNIDIRECTIONAL);
+    ActivateStream(QuicWrapUnique(stream));
+    return stream;
+  }
+};
+
+class QuicSpdyClientSessionTest : public QuicTestWithParam<ParsedQuicVersion> {
+ protected:
+  QuicSpdyClientSessionTest()
+      : crypto_config_(crypto_test_utils::ProofVerifierForTesting(),
+                       TlsClientHandshaker::CreateSslCtx()),
+        promised_stream_id_(
+            QuicUtils::GetInvalidStreamId(GetParam().transport_version)),
+        associated_stream_id_(
+            QuicUtils::GetInvalidStreamId(GetParam().transport_version)) {
+    Initialize();
+    // Advance the time, because timers do not like uninitialized times.
+    connection_->AdvanceTime(QuicTime::Delta::FromSeconds(1));
+  }
+
+  ~QuicSpdyClientSessionTest() override {
+    // Session must be destroyed before promised_by_url_
+    session_.reset(nullptr);
+  }
+
+  void Initialize() {
+    session_.reset();
+    connection_ = new PacketSavingConnection(&helper_, &alarm_factory_,
+                                             Perspective::IS_CLIENT,
+                                             SupportedVersions(GetParam()));
+    session_ = QuicMakeUnique<TestQuicSpdyClientSession>(
+        DefaultQuicConfig(), SupportedVersions(GetParam()), connection_,
+        QuicServerId(kServerHostname, kPort, false), &crypto_config_,
+        &push_promise_index_);
+    session_->Initialize();
+    push_promise_[":path"] = "/bar";
+    push_promise_[":authority"] = "www.google.com";
+    push_promise_[":version"] = "HTTP/1.1";
+    push_promise_[":method"] = "GET";
+    push_promise_[":scheme"] = "https";
+    promise_url_ = SpdyUtils::GetPromisedUrlFromHeaders(push_promise_);
+    promised_stream_id_ = GetNthServerInitiatedUnidirectionalStreamId(
+        connection_->transport_version(), 0);
+    associated_stream_id_ = GetNthClientInitiatedBidirectionalStreamId(
+        connection_->transport_version(), 0);
+  }
+
+  // The function ensures that A) the max stream id frames get properly deleted
+  // (since the test uses a 'did we leak memory' check ... if we just lose the
+  // frame, the test fails) and B) returns true (instead of the default, false)
+  // which ensures that the rest of the system thinks that the frame actually
+  // was transmitted.
+  bool ClearMaxStreamIdControlFrame(const QuicFrame& frame) {
+    if (frame.type == MAX_STREAM_ID_FRAME) {
+      DeleteFrame(&const_cast<QuicFrame&>(frame));
+      return true;
+    }
+    return false;
+  }
+
+ public:
+  bool ClearStreamIdBlockedControlFrame(const QuicFrame& frame) {
+    if (frame.type == STREAM_ID_BLOCKED_FRAME) {
+      DeleteFrame(&const_cast<QuicFrame&>(frame));
+      return true;
+    }
+    return false;
+  }
+
+ protected:
+  void CompleteCryptoHandshake() {
+    CompleteCryptoHandshake(kDefaultMaxStreamsPerConnection);
+  }
+
+  void CompleteCryptoHandshake(uint32_t server_max_incoming_streams) {
+    if (connection_->transport_version() == QUIC_VERSION_99) {
+      EXPECT_CALL(*connection_, SendControlFrame(_))
+          .Times(testing::AnyNumber())
+          .WillRepeatedly(Invoke(
+              this, &QuicSpdyClientSessionTest::ClearMaxStreamIdControlFrame));
+    }
+    session_->CryptoConnect();
+    QuicCryptoClientStream* stream = static_cast<QuicCryptoClientStream*>(
+        session_->GetMutableCryptoStream());
+    crypto_test_utils::FakeServerOptions options;
+    QuicConfig config = DefaultQuicConfig();
+    config.SetMaxIncomingDynamicStreamsToSend(server_max_incoming_streams);
+    crypto_test_utils::HandshakeWithFakeServer(
+        &config, &helper_, &alarm_factory_, connection_, stream, options);
+  }
+
+  QuicCryptoClientConfig crypto_config_;
+  MockQuicConnectionHelper helper_;
+  MockAlarmFactory alarm_factory_;
+  PacketSavingConnection* connection_;
+  std::unique_ptr<TestQuicSpdyClientSession> session_;
+  QuicClientPushPromiseIndex push_promise_index_;
+  SpdyHeaderBlock push_promise_;
+  QuicString promise_url_;
+  QuicStreamId promised_stream_id_;
+  QuicStreamId associated_stream_id_;
+};
+
+INSTANTIATE_TEST_SUITE_P(Tests,
+                         QuicSpdyClientSessionTest,
+                         ::testing::ValuesIn(AllSupportedVersions()));
+
+TEST_P(QuicSpdyClientSessionTest, CryptoConnect) {
+  CompleteCryptoHandshake();
+}
+
+TEST_P(QuicSpdyClientSessionTest, NoEncryptionAfterInitialEncryption) {
+  if (GetParam().handshake_protocol == PROTOCOL_TLS1_3) {
+    // This test relies on resumption and is QUIC crypto specific, so it is
+    // disabled for TLS.
+    // TODO(nharper): Add support for resumption to the TLS handshake, and fix
+    // this test to not rely on QUIC crypto.
+    return;
+  }
+  // Complete a handshake in order to prime the crypto config for 0-RTT.
+  CompleteCryptoHandshake();
+
+  // Now create a second session using the same crypto config.
+  Initialize();
+
+  EXPECT_CALL(*connection_, OnCanWrite());
+  // Starting the handshake should move immediately to encryption
+  // established and will allow streams to be created.
+  session_->CryptoConnect();
+  EXPECT_TRUE(session_->IsEncryptionEstablished());
+  QuicSpdyClientStream* stream = session_->CreateOutgoingBidirectionalStream();
+  ASSERT_TRUE(stream != nullptr);
+  EXPECT_NE(QuicUtils::GetCryptoStreamId(connection_->transport_version()),
+            stream->id());
+
+  // Process an "inchoate" REJ from the server which will cause
+  // an inchoate CHLO to be sent and will leave the encryption level
+  // at NONE.
+  CryptoHandshakeMessage rej;
+  crypto_test_utils::FillInDummyReject(&rej, /* stateless */ false);
+  EXPECT_TRUE(session_->IsEncryptionEstablished());
+  crypto_test_utils::SendHandshakeMessageToStream(
+      session_->GetMutableCryptoStream(), rej, Perspective::IS_CLIENT);
+  EXPECT_FALSE(session_->IsEncryptionEstablished());
+  EXPECT_EQ(ENCRYPTION_NONE,
+            QuicPacketCreatorPeer::GetEncryptionLevel(
+                QuicConnectionPeer::GetPacketCreator(connection_)));
+  // Verify that no new streams may be created.
+  EXPECT_TRUE(session_->CreateOutgoingBidirectionalStream() == nullptr);
+  // Verify that no data may be send on existing streams.
+  char data[] = "hello world";
+  QuicConsumedData consumed = session_->WritevData(
+      stream, stream->id(), QUIC_ARRAYSIZE(data), 0, NO_FIN);
+  EXPECT_FALSE(consumed.fin_consumed);
+  EXPECT_EQ(0u, consumed.bytes_consumed);
+}
+
+TEST_P(QuicSpdyClientSessionTest, MaxNumStreamsWithNoFinOrRst) {
+  if (GetParam().handshake_protocol == PROTOCOL_TLS1_3) {
+    // This test relies on the MIDS transport parameter, which is not yet
+    // supported in TLS 1.3.
+    // TODO(nharper): Add support for Transport Parameters in the TLS handshake.
+    return;
+  }
+  EXPECT_CALL(*connection_, SendControlFrame(_)).Times(AnyNumber());
+  EXPECT_CALL(*connection_, OnStreamReset(_, _)).Times(AnyNumber());
+
+  const uint32_t kServerMaxIncomingStreams = 1;
+  CompleteCryptoHandshake(kServerMaxIncomingStreams);
+
+  QuicSpdyClientStream* stream = session_->CreateOutgoingBidirectionalStream();
+  ASSERT_TRUE(stream);
+  EXPECT_FALSE(session_->CreateOutgoingBidirectionalStream());
+
+  // Close the stream, but without having received a FIN or a RST_STREAM
+  // or MAX_STREAM_ID (V99) and check that a new one can not be created.
+  session_->CloseStream(stream->id());
+  EXPECT_EQ(1u, session_->GetNumOpenOutgoingStreams());
+
+  stream = session_->CreateOutgoingBidirectionalStream();
+  EXPECT_FALSE(stream);
+}
+
+TEST_P(QuicSpdyClientSessionTest, MaxNumStreamsWithRst) {
+  if (GetParam().handshake_protocol == PROTOCOL_TLS1_3) {
+    // This test relies on the MIDS transport parameter, which is not yet
+    // supported in TLS 1.3.
+    // TODO(nharper): Add support for Transport Parameters in the TLS handshake.
+    return;
+  }
+  EXPECT_CALL(*connection_, SendControlFrame(_)).Times(AnyNumber());
+  EXPECT_CALL(*connection_, OnStreamReset(_, _)).Times(AnyNumber());
+
+  const uint32_t kServerMaxIncomingStreams = 1;
+  CompleteCryptoHandshake(kServerMaxIncomingStreams);
+
+  QuicSpdyClientStream* stream = session_->CreateOutgoingBidirectionalStream();
+  ASSERT_NE(nullptr, stream);
+  EXPECT_EQ(nullptr, session_->CreateOutgoingBidirectionalStream());
+
+  // Close the stream and receive an RST frame to remove the unfinished stream
+  session_->CloseStream(stream->id());
+  session_->OnRstStream(QuicRstStreamFrame(kInvalidControlFrameId, stream->id(),
+                                           QUIC_RST_ACKNOWLEDGEMENT, 0));
+  // Check that a new one can be created.
+  EXPECT_EQ(0u, session_->GetNumOpenOutgoingStreams());
+  if (GetParam().transport_version == QUIC_VERSION_99) {
+    // In V99 the stream limit increases only if we get a MAX_STREAM_ID
+    // frame; pretend we got one.
+
+    // Note that this is to be the second stream created, but GetNth... starts
+    // numbering at 0 (the first stream is 0, second is 1...)
+    QuicMaxStreamIdFrame frame(0, GetNthClientInitiatedBidirectionalStreamId(
+                                      connection_->transport_version(), 1));
+    session_->OnMaxStreamIdFrame(frame);
+  }
+  stream = session_->CreateOutgoingBidirectionalStream();
+  EXPECT_NE(nullptr, stream);
+}
+
+TEST_P(QuicSpdyClientSessionTest, ResetAndTrailers) {
+  if (GetParam().handshake_protocol == PROTOCOL_TLS1_3) {
+    // This test relies on the MIDS transport parameter, which is not yet
+    // supported in TLS 1.3.
+    // TODO(nharper): Add support for Transport Parameters in the TLS handshake.
+    return;
+  }
+  // Tests the situation in which the client sends a RST at the same time that
+  // the server sends trailing headers (trailers). Receipt of the trailers by
+  // the client should result in all outstanding stream state being tidied up
+  // (including flow control, and number of available outgoing streams).
+  const uint32_t kServerMaxIncomingStreams = 1;
+  CompleteCryptoHandshake(kServerMaxIncomingStreams);
+
+  QuicSpdyClientStream* stream = session_->CreateOutgoingBidirectionalStream();
+  ASSERT_NE(nullptr, stream);
+
+  if (GetParam().transport_version == QUIC_VERSION_99) {
+    // For v99, trying to open a stream and failing due to lack
+    // of stream ids will result in a STREAM_ID_BLOCKED. Make
+    // sure we get one. Also clear out the frame because if it's
+    // left sitting, the later SendRstStream will not actually
+    // transmit the RST_STREAM because the connection will be in write-blocked
+    // state. This means that the SendControlFrame that is expected w.r.t. the
+    // RST_STREAM, below, will not be satisfied.
+    EXPECT_CALL(*connection_, SendControlFrame(_))
+        .WillOnce(Invoke(
+            this,
+            &QuicSpdyClientSessionTest::ClearStreamIdBlockedControlFrame));
+  }
+
+  EXPECT_EQ(nullptr, session_->CreateOutgoingBidirectionalStream());
+
+  QuicStreamId stream_id = stream->id();
+
+  EXPECT_CALL(*connection_, SendControlFrame(_)).Times(1);
+  EXPECT_CALL(*connection_, OnStreamReset(_, _)).Times(1);
+  session_->SendRstStream(stream_id, QUIC_STREAM_PEER_GOING_AWAY, 0);
+
+  // A new stream cannot be created as the reset stream still counts as an open
+  // outgoing stream until closed by the server.
+  EXPECT_EQ(1u, session_->GetNumOpenOutgoingStreams());
+  stream = session_->CreateOutgoingBidirectionalStream();
+  EXPECT_EQ(nullptr, stream);
+
+  // The stream receives trailers with final byte offset: this is one of three
+  // ways that a peer can signal the end of a stream (the others being RST,
+  // stream data + FIN).
+  QuicHeaderList trailers;
+  trailers.OnHeaderBlockStart();
+  trailers.OnHeader(kFinalOffsetHeaderKey, "0");
+  trailers.OnHeaderBlockEnd(0, 0);
+  session_->OnStreamHeaderList(stream_id, /*fin=*/false, 0, trailers);
+
+  // The stream is now complete from the client's perspective, and it should
+  // be able to create a new outgoing stream.
+  EXPECT_EQ(0u, session_->GetNumOpenOutgoingStreams());
+  if (GetParam().transport_version == QUIC_VERSION_99) {
+    // Note that this is to be the second stream created, but GetNth... starts
+    // numbering at 0 (the first stream is 0, second is 1...)
+    QuicMaxStreamIdFrame frame(0, GetNthClientInitiatedBidirectionalStreamId(
+                                      connection_->transport_version(), 1));
+    session_->OnMaxStreamIdFrame(frame);
+  }
+  stream = session_->CreateOutgoingBidirectionalStream();
+  EXPECT_NE(nullptr, stream);
+}
+
+TEST_P(QuicSpdyClientSessionTest, ReceivedMalformedTrailersAfterSendingRst) {
+  // Tests the situation where the client has sent a RST to the server, and has
+  // received trailing headers with a malformed final byte offset value.
+  CompleteCryptoHandshake();
+
+  QuicSpdyClientStream* stream = session_->CreateOutgoingBidirectionalStream();
+  ASSERT_NE(nullptr, stream);
+
+  // Send the RST, which results in the stream being closed locally (but some
+  // state remains while the client waits for a response from the server).
+  QuicStreamId stream_id = stream->id();
+  EXPECT_CALL(*connection_, SendControlFrame(_)).Times(1);
+  EXPECT_CALL(*connection_, OnStreamReset(_, _)).Times(1);
+  session_->SendRstStream(stream_id, QUIC_STREAM_PEER_GOING_AWAY, 0);
+
+  // The stream receives trailers with final byte offset, but the header value
+  // is non-numeric and should be treated as malformed.
+  QuicHeaderList trailers;
+  trailers.OnHeaderBlockStart();
+  trailers.OnHeader(kFinalOffsetHeaderKey, "invalid non-numeric value");
+  trailers.OnHeaderBlockEnd(0, 0);
+
+  EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(1);
+  session_->OnStreamHeaderList(stream_id, /*fin=*/false, 0, trailers);
+}
+
+TEST_P(QuicSpdyClientSessionTest, OnStreamHeaderListWithStaticStream) {
+  // Test situation where OnStreamHeaderList is called by stream with static id.
+  CompleteCryptoHandshake();
+
+  QuicHeaderList trailers;
+  trailers.OnHeaderBlockStart();
+  trailers.OnHeader(kFinalOffsetHeaderKey, "0");
+  trailers.OnHeaderBlockEnd(0, 0);
+
+  EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(1);
+  session_->OnStreamHeaderList(
+      QuicUtils::GetCryptoStreamId(connection_->transport_version()),
+      /*fin=*/false, 0, trailers);
+}
+
+TEST_P(QuicSpdyClientSessionTest, OnPromiseHeaderListWithStaticStream) {
+  // Test situation where OnPromiseHeaderList is called by stream with static
+  // id.
+  CompleteCryptoHandshake();
+
+  QuicHeaderList trailers;
+  trailers.OnHeaderBlockStart();
+  trailers.OnHeader(kFinalOffsetHeaderKey, "0");
+  trailers.OnHeaderBlockEnd(0, 0);
+
+  EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(1);
+  session_->OnPromiseHeaderList(
+      QuicUtils::GetCryptoStreamId(connection_->transport_version()),
+      promised_stream_id_, 0, trailers);
+}
+
+TEST_P(QuicSpdyClientSessionTest, GoAwayReceived) {
+  CompleteCryptoHandshake();
+
+  // After receiving a GoAway, I should no longer be able to create outgoing
+  // streams.
+  session_->connection()->OnGoAwayFrame(QuicGoAwayFrame(
+      kInvalidControlFrameId, QUIC_PEER_GOING_AWAY, 1u, "Going away."));
+  EXPECT_EQ(nullptr, session_->CreateOutgoingBidirectionalStream());
+}
+
+static bool CheckForDecryptionError(QuicFramer* framer) {
+  return framer->error() == QUIC_DECRYPTION_FAILURE;
+}
+
+// Various sorts of invalid packets that should not cause a connection
+// to be closed.
+TEST_P(QuicSpdyClientSessionTest, InvalidPacketReceived) {
+  QuicSocketAddress server_address(TestPeerIPAddress(), kTestPort);
+  QuicSocketAddress client_address(TestPeerIPAddress(), kTestPort);
+
+  EXPECT_CALL(*connection_, ProcessUdpPacket(server_address, client_address, _))
+      .WillRepeatedly(Invoke(static_cast<MockQuicConnection*>(connection_),
+                             &MockQuicConnection::ReallyProcessUdpPacket));
+  EXPECT_CALL(*connection_, OnCanWrite()).Times(AnyNumber());
+  EXPECT_CALL(*connection_, OnError(_)).Times(1);
+
+  // Verify that empty packets don't close the connection.
+  QuicReceivedPacket zero_length_packet(nullptr, 0, QuicTime::Zero(), false);
+  EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(0);
+  session_->ProcessUdpPacket(client_address, server_address,
+                             zero_length_packet);
+
+  // Verifiy that small, invalid packets don't close the connection.
+  char buf[2] = {0x00, 0x01};
+  QuicConnectionId connection_id = session_->connection()->connection_id();
+  QuicReceivedPacket valid_packet(buf, 2, QuicTime::Zero(), false);
+  // Close connection shouldn't be called.
+  EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(0);
+  if (connection_->transport_version() > QUIC_VERSION_44) {
+    // Illegal fixed bit value.
+    EXPECT_CALL(*connection_, OnError(_)).Times(1);
+  }
+  session_->ProcessUdpPacket(client_address, server_address, valid_packet);
+
+  // Verify that a non-decryptable packet doesn't close the connection.
+  QuicFramerPeer::SetLastSerializedConnectionId(
+      QuicConnectionPeer::GetFramer(connection_), connection_id);
+  ParsedQuicVersionVector versions = SupportedVersions(GetParam());
+  std::unique_ptr<QuicEncryptedPacket> packet(ConstructEncryptedPacket(
+      connection_id, EmptyQuicConnectionId(), false, false, 100, "data",
+      CONNECTION_ID_ABSENT, CONNECTION_ID_ABSENT, PACKET_4BYTE_PACKET_NUMBER,
+      &versions, Perspective::IS_SERVER));
+  std::unique_ptr<QuicReceivedPacket> received(
+      ConstructReceivedPacket(*packet, QuicTime::Zero()));
+  // Change the last byte of the encrypted data.
+  *(const_cast<char*>(received->data() + received->length() - 1)) += 1;
+  EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(0);
+  EXPECT_CALL(*connection_, OnError(Truly(CheckForDecryptionError))).Times(1);
+  session_->ProcessUdpPacket(client_address, server_address, *received);
+}
+
+// A packet with invalid framing should cause a connection to be closed.
+TEST_P(QuicSpdyClientSessionTest, InvalidFramedPacketReceived) {
+  QuicSocketAddress server_address(TestPeerIPAddress(), kTestPort);
+  QuicSocketAddress client_address(TestPeerIPAddress(), kTestPort);
+
+  EXPECT_CALL(*connection_, ProcessUdpPacket(server_address, client_address, _))
+      .WillRepeatedly(Invoke(static_cast<MockQuicConnection*>(connection_),
+                             &MockQuicConnection::ReallyProcessUdpPacket));
+  EXPECT_CALL(*connection_, OnError(_)).Times(1);
+
+  // Verify that a decryptable packet with bad frames does close the connection.
+  QuicConnectionId connection_id = session_->connection()->connection_id();
+  QuicFramerPeer::SetLastSerializedConnectionId(
+      QuicConnectionPeer::GetFramer(connection_), connection_id);
+  ParsedQuicVersionVector versions = {GetParam()};
+  std::unique_ptr<QuicEncryptedPacket> packet(ConstructMisFramedEncryptedPacket(
+      connection_id, EmptyQuicConnectionId(), false, false, 100, "data",
+      CONNECTION_ID_ABSENT, CONNECTION_ID_ABSENT, PACKET_4BYTE_PACKET_NUMBER,
+      &versions, Perspective::IS_SERVER));
+  std::unique_ptr<QuicReceivedPacket> received(
+      ConstructReceivedPacket(*packet, QuicTime::Zero()));
+  EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(1);
+  session_->ProcessUdpPacket(client_address, server_address, *received);
+}
+
+TEST_P(QuicSpdyClientSessionTest, PushPromiseOnPromiseHeaders) {
+  // Initialize crypto before the client session will create a stream.
+  CompleteCryptoHandshake();
+
+  MockQuicSpdyClientStream* stream = static_cast<MockQuicSpdyClientStream*>(
+      session_->CreateOutgoingBidirectionalStream());
+
+  EXPECT_CALL(*stream, OnPromiseHeaderList(_, _, _));
+  session_->OnPromiseHeaderList(associated_stream_id_, promised_stream_id_, 0,
+                                QuicHeaderList());
+}
+
+TEST_P(QuicSpdyClientSessionTest, PushPromiseOnPromiseHeadersAlreadyClosed) {
+  // Initialize crypto before the client session will create a stream.
+  CompleteCryptoHandshake();
+
+  session_->CreateOutgoingBidirectionalStream();
+
+  EXPECT_CALL(*connection_, SendControlFrame(_));
+  EXPECT_CALL(*connection_,
+              OnStreamReset(associated_stream_id_, QUIC_REFUSED_STREAM));
+  session_->ResetPromised(associated_stream_id_, QUIC_REFUSED_STREAM);
+
+  session_->OnPromiseHeaderList(associated_stream_id_, promised_stream_id_, 0,
+                                QuicHeaderList());
+}
+
+TEST_P(QuicSpdyClientSessionTest, PushPromiseOutOfOrder) {
+  // Initialize crypto before the client session will create a stream.
+  CompleteCryptoHandshake();
+
+  MockQuicSpdyClientStream* stream = static_cast<MockQuicSpdyClientStream*>(
+      session_->CreateOutgoingBidirectionalStream());
+
+  EXPECT_CALL(*stream, OnPromiseHeaderList(promised_stream_id_, _, _));
+  session_->OnPromiseHeaderList(associated_stream_id_, promised_stream_id_, 0,
+                                QuicHeaderList());
+  associated_stream_id_ +=
+      QuicUtils::StreamIdDelta(connection_->transport_version());
+  EXPECT_CALL(*connection_,
+              CloseConnection(QUIC_INVALID_STREAM_ID,
+                              "Received push stream id lesser or equal to the"
+                              " last accepted before",
+                              _));
+  session_->OnPromiseHeaderList(associated_stream_id_, promised_stream_id_, 0,
+                                QuicHeaderList());
+}
+
+TEST_P(QuicSpdyClientSessionTest, PushPromiseOutgoingStreamId) {
+  // Initialize crypto before the client session will create a stream.
+  CompleteCryptoHandshake();
+
+  MockQuicSpdyClientStream* stream = static_cast<MockQuicSpdyClientStream*>(
+      session_->CreateOutgoingBidirectionalStream());
+
+  // Promise an illegal (outgoing) stream id.
+  promised_stream_id_ = GetNthClientInitiatedBidirectionalStreamId(
+      connection_->transport_version(), 0);
+  EXPECT_CALL(
+      *connection_,
+      CloseConnection(QUIC_INVALID_STREAM_ID,
+                      "Received push stream id for outgoing stream.", _));
+
+  session_->OnPromiseHeaderList(stream->id(), promised_stream_id_, 0,
+                                QuicHeaderList());
+}
+
+TEST_P(QuicSpdyClientSessionTest, PushPromiseHandlePromise) {
+  // Initialize crypto before the client session will create a stream.
+  CompleteCryptoHandshake();
+
+  session_->CreateOutgoingBidirectionalStream();
+
+  EXPECT_TRUE(session_->HandlePromised(associated_stream_id_,
+                                       promised_stream_id_, push_promise_));
+
+  EXPECT_NE(session_->GetPromisedById(promised_stream_id_), nullptr);
+  EXPECT_NE(session_->GetPromisedByUrl(promise_url_), nullptr);
+}
+
+TEST_P(QuicSpdyClientSessionTest, PushPromiseAlreadyClosed) {
+  // Initialize crypto before the client session will create a stream.
+  CompleteCryptoHandshake();
+
+  session_->CreateOutgoingBidirectionalStream();
+  session_->GetOrCreateStream(promised_stream_id_);
+
+  EXPECT_CALL(*connection_, SendControlFrame(_));
+  EXPECT_CALL(*connection_,
+              OnStreamReset(promised_stream_id_, QUIC_REFUSED_STREAM));
+
+  session_->ResetPromised(promised_stream_id_, QUIC_REFUSED_STREAM);
+  SpdyHeaderBlock promise_headers;
+  EXPECT_FALSE(session_->HandlePromised(associated_stream_id_,
+                                        promised_stream_id_, promise_headers));
+
+  // Verify that the promise was not created.
+  EXPECT_EQ(session_->GetPromisedById(promised_stream_id_), nullptr);
+  EXPECT_EQ(session_->GetPromisedByUrl(promise_url_), nullptr);
+}
+
+TEST_P(QuicSpdyClientSessionTest, PushPromiseDuplicateUrl) {
+  // Initialize crypto before the client session will create a stream.
+  CompleteCryptoHandshake();
+
+  session_->CreateOutgoingBidirectionalStream();
+
+  EXPECT_TRUE(session_->HandlePromised(associated_stream_id_,
+                                       promised_stream_id_, push_promise_));
+
+  EXPECT_NE(session_->GetPromisedById(promised_stream_id_), nullptr);
+  EXPECT_NE(session_->GetPromisedByUrl(promise_url_), nullptr);
+
+  promised_stream_id_ +=
+      QuicUtils::StreamIdDelta(connection_->transport_version());
+  EXPECT_CALL(*connection_, SendControlFrame(_));
+  EXPECT_CALL(*connection_,
+              OnStreamReset(promised_stream_id_, QUIC_DUPLICATE_PROMISE_URL));
+
+  EXPECT_FALSE(session_->HandlePromised(associated_stream_id_,
+                                        promised_stream_id_, push_promise_));
+
+  // Verify that the promise was not created.
+  EXPECT_EQ(session_->GetPromisedById(promised_stream_id_), nullptr);
+}
+
+TEST_P(QuicSpdyClientSessionTest, ReceivingPromiseEnhanceYourCalm) {
+  for (size_t i = 0u; i < session_->get_max_promises(); i++) {
+    push_promise_[":path"] = QuicStringPrintf("/bar%zu", i);
+
+    QuicStreamId id =
+        promised_stream_id_ +
+        i * QuicUtils::StreamIdDelta(connection_->transport_version());
+
+    EXPECT_TRUE(
+        session_->HandlePromised(associated_stream_id_, id, push_promise_));
+
+    // Verify that the promise is in the unclaimed streams map.
+    QuicString promise_url(SpdyUtils::GetPromisedUrlFromHeaders(push_promise_));
+    EXPECT_NE(session_->GetPromisedByUrl(promise_url), nullptr);
+    EXPECT_NE(session_->GetPromisedById(id), nullptr);
+  }
+
+  // One more promise, this should be refused.
+  int i = session_->get_max_promises();
+  push_promise_[":path"] = QuicStringPrintf("/bar%d", i);
+
+  QuicStreamId id =
+      promised_stream_id_ +
+      i * QuicUtils::StreamIdDelta(connection_->transport_version());
+  EXPECT_CALL(*connection_, SendControlFrame(_));
+  EXPECT_CALL(*connection_, OnStreamReset(id, QUIC_REFUSED_STREAM));
+  EXPECT_FALSE(
+      session_->HandlePromised(associated_stream_id_, id, push_promise_));
+
+  // Verify that the promise was not created.
+  QuicString promise_url(SpdyUtils::GetPromisedUrlFromHeaders(push_promise_));
+  EXPECT_EQ(session_->GetPromisedById(id), nullptr);
+  EXPECT_EQ(session_->GetPromisedByUrl(promise_url), nullptr);
+}
+
+TEST_P(QuicSpdyClientSessionTest, IsClosedTrueAfterResetPromisedAlreadyOpen) {
+  // Initialize crypto before the client session will create a stream.
+  CompleteCryptoHandshake();
+
+  session_->GetOrCreateStream(promised_stream_id_);
+  EXPECT_CALL(*connection_, SendControlFrame(_));
+  EXPECT_CALL(*connection_,
+              OnStreamReset(promised_stream_id_, QUIC_REFUSED_STREAM));
+  session_->ResetPromised(promised_stream_id_, QUIC_REFUSED_STREAM);
+  EXPECT_TRUE(session_->IsClosedStream(promised_stream_id_));
+}
+
+TEST_P(QuicSpdyClientSessionTest, IsClosedTrueAfterResetPromisedNonexistant) {
+  // Initialize crypto before the client session will create a stream.
+  CompleteCryptoHandshake();
+
+  EXPECT_CALL(*connection_, SendControlFrame(_));
+  EXPECT_CALL(*connection_,
+              OnStreamReset(promised_stream_id_, QUIC_REFUSED_STREAM));
+  session_->ResetPromised(promised_stream_id_, QUIC_REFUSED_STREAM);
+  EXPECT_TRUE(session_->IsClosedStream(promised_stream_id_));
+}
+
+TEST_P(QuicSpdyClientSessionTest, OnInitialHeadersCompleteIsPush) {
+  // Initialize crypto before the client session will create a stream.
+  CompleteCryptoHandshake();
+  session_->GetOrCreateStream(promised_stream_id_);
+  EXPECT_TRUE(session_->HandlePromised(associated_stream_id_,
+                                       promised_stream_id_, push_promise_));
+  EXPECT_NE(session_->GetPromisedById(promised_stream_id_), nullptr);
+  EXPECT_NE(session_->GetPromisedStream(promised_stream_id_), nullptr);
+  EXPECT_NE(session_->GetPromisedByUrl(promise_url_), nullptr);
+
+  session_->OnInitialHeadersComplete(promised_stream_id_, SpdyHeaderBlock());
+}
+
+TEST_P(QuicSpdyClientSessionTest, OnInitialHeadersCompleteIsNotPush) {
+  // Initialize crypto before the client session will create a stream.
+  CompleteCryptoHandshake();
+  session_->CreateOutgoingBidirectionalStream();
+  session_->OnInitialHeadersComplete(promised_stream_id_, SpdyHeaderBlock());
+}
+
+TEST_P(QuicSpdyClientSessionTest, DeletePromised) {
+  // Initialize crypto before the client session will create a stream.
+  CompleteCryptoHandshake();
+  session_->GetOrCreateStream(promised_stream_id_);
+  EXPECT_TRUE(session_->HandlePromised(associated_stream_id_,
+                                       promised_stream_id_, push_promise_));
+  QuicClientPromisedInfo* promised =
+      session_->GetPromisedById(promised_stream_id_);
+  EXPECT_NE(promised, nullptr);
+  EXPECT_NE(session_->GetPromisedStream(promised_stream_id_), nullptr);
+  EXPECT_NE(session_->GetPromisedByUrl(promise_url_), nullptr);
+
+  session_->DeletePromised(promised);
+  EXPECT_EQ(session_->GetPromisedById(promised_stream_id_), nullptr);
+  EXPECT_EQ(session_->GetPromisedByUrl(promise_url_), nullptr);
+}
+
+TEST_P(QuicSpdyClientSessionTest, ResetPromised) {
+  // Initialize crypto before the client session will create a stream.
+  CompleteCryptoHandshake();
+  session_->GetOrCreateStream(promised_stream_id_);
+  EXPECT_TRUE(session_->HandlePromised(associated_stream_id_,
+                                       promised_stream_id_, push_promise_));
+  EXPECT_CALL(*connection_, SendControlFrame(_));
+  EXPECT_CALL(*connection_,
+              OnStreamReset(promised_stream_id_, QUIC_STREAM_PEER_GOING_AWAY));
+  session_->SendRstStream(promised_stream_id_, QUIC_STREAM_PEER_GOING_AWAY, 0);
+  QuicClientPromisedInfo* promised =
+      session_->GetPromisedById(promised_stream_id_);
+  EXPECT_NE(promised, nullptr);
+  EXPECT_NE(session_->GetPromisedByUrl(promise_url_), nullptr);
+  EXPECT_EQ(session_->GetPromisedStream(promised_stream_id_), nullptr);
+}
+
+TEST_P(QuicSpdyClientSessionTest, PushPromiseInvalidMethod) {
+  // Initialize crypto before the client session will create a stream.
+  CompleteCryptoHandshake();
+
+  session_->CreateOutgoingBidirectionalStream();
+
+  EXPECT_CALL(*connection_, SendControlFrame(_));
+  EXPECT_CALL(*connection_,
+              OnStreamReset(promised_stream_id_, QUIC_INVALID_PROMISE_METHOD));
+
+  push_promise_[":method"] = "POST";
+  EXPECT_FALSE(session_->HandlePromised(associated_stream_id_,
+                                        promised_stream_id_, push_promise_));
+
+  EXPECT_EQ(session_->GetPromisedById(promised_stream_id_), nullptr);
+  EXPECT_EQ(session_->GetPromisedByUrl(promise_url_), nullptr);
+}
+
+TEST_P(QuicSpdyClientSessionTest, PushPromiseInvalidHost) {
+  // Initialize crypto before the client session will create a stream.
+  CompleteCryptoHandshake();
+
+  session_->CreateOutgoingBidirectionalStream();
+
+  EXPECT_CALL(*connection_, SendControlFrame(_));
+  EXPECT_CALL(*connection_,
+              OnStreamReset(promised_stream_id_, QUIC_INVALID_PROMISE_URL));
+
+  push_promise_[":authority"] = "";
+  EXPECT_FALSE(session_->HandlePromised(associated_stream_id_,
+                                        promised_stream_id_, push_promise_));
+
+  EXPECT_EQ(session_->GetPromisedById(promised_stream_id_), nullptr);
+  EXPECT_EQ(session_->GetPromisedByUrl(promise_url_), nullptr);
+}
+
+TEST_P(QuicSpdyClientSessionTest,
+       TryToCreateServerInitiatedBidirectionalStream) {
+  if (connection_->transport_version() == QUIC_VERSION_99) {
+    EXPECT_CALL(*connection_, CloseConnection(QUIC_INVALID_STREAM_ID, _, _));
+  } else {
+    EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(0);
+  }
+  session_->GetOrCreateStream(GetNthServerInitiatedBidirectionalStreamId(
+      connection_->transport_version(), 0));
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quic/core/http/quic_spdy_client_stream.cc b/quic/core/http/quic_spdy_client_stream.cc
new file mode 100644
index 0000000..d4e8a69
--- /dev/null
+++ b/quic/core/http/quic_spdy_client_stream.cc
@@ -0,0 +1,160 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/third_party/quiche/src/quic/core/http/quic_spdy_client_stream.h"
+
+#include <utility>
+
+#include "net/third_party/quiche/src/quic/core/http/quic_client_promised_info.h"
+#include "net/third_party/quiche/src/quic/core/http/quic_spdy_client_session.h"
+#include "net/third_party/quiche/src/quic/core/http/spdy_utils.h"
+#include "net/third_party/quiche/src/quic/core/quic_alarm.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_logging.h"
+#include "net/third_party/quiche/src/spdy/core/spdy_protocol.h"
+
+using spdy::SpdyHeaderBlock;
+
+namespace quic {
+
+QuicSpdyClientStream::QuicSpdyClientStream(QuicStreamId id,
+                                           QuicSpdyClientSession* session,
+                                           StreamType type)
+    : QuicSpdyStream(id, session, type),
+      content_length_(-1),
+      response_code_(0),
+      header_bytes_read_(0),
+      header_bytes_written_(0),
+      session_(session),
+      has_preliminary_headers_(false) {}
+
+QuicSpdyClientStream::QuicSpdyClientStream(PendingStream pending,
+                                           QuicSpdyClientSession* session,
+                                           StreamType type)
+    : QuicSpdyStream(std::move(pending), session, type),
+      content_length_(-1),
+      response_code_(0),
+      header_bytes_read_(0),
+      header_bytes_written_(0),
+      session_(session),
+      has_preliminary_headers_(false) {}
+
+QuicSpdyClientStream::~QuicSpdyClientStream() = default;
+
+void QuicSpdyClientStream::OnInitialHeadersComplete(
+    bool fin,
+    size_t frame_len,
+    const QuicHeaderList& header_list) {
+  QuicSpdyStream::OnInitialHeadersComplete(fin, frame_len, header_list);
+
+  DCHECK(headers_decompressed());
+  header_bytes_read_ += frame_len;
+  if (!SpdyUtils::CopyAndValidateHeaders(header_list, &content_length_,
+                                         &response_headers_)) {
+    QUIC_DLOG(ERROR) << "Failed to parse header list: "
+                     << header_list.DebugString();
+    Reset(QUIC_BAD_APPLICATION_PAYLOAD);
+    return;
+  }
+
+  if (!ParseHeaderStatusCode(response_headers_, &response_code_)) {
+    QUIC_DLOG(ERROR) << "Received invalid response code: "
+                     << response_headers_[":status"].as_string();
+    Reset(QUIC_BAD_APPLICATION_PAYLOAD);
+    return;
+  }
+
+  if (response_code_ == 100 && !has_preliminary_headers_) {
+    // These are preliminary 100 Continue headers, not the actual response
+    // headers.
+    set_headers_decompressed(false);
+    has_preliminary_headers_ = true;
+    preliminary_headers_ = std::move(response_headers_);
+  }
+
+  ConsumeHeaderList();
+  QUIC_DVLOG(1) << "headers complete for stream " << id();
+
+  session_->OnInitialHeadersComplete(id(), response_headers_);
+}
+
+void QuicSpdyClientStream::OnTrailingHeadersComplete(
+    bool fin,
+    size_t frame_len,
+    const QuicHeaderList& header_list) {
+  QuicSpdyStream::OnTrailingHeadersComplete(fin, frame_len, header_list);
+  MarkTrailersConsumed();
+}
+
+void QuicSpdyClientStream::OnPromiseHeaderList(
+    QuicStreamId promised_id,
+    size_t frame_len,
+    const QuicHeaderList& header_list) {
+  header_bytes_read_ += frame_len;
+  int64_t content_length = -1;
+  SpdyHeaderBlock promise_headers;
+  if (!SpdyUtils::CopyAndValidateHeaders(header_list, &content_length,
+                                         &promise_headers)) {
+    QUIC_DLOG(ERROR) << "Failed to parse promise headers: "
+                     << header_list.DebugString();
+    Reset(QUIC_BAD_APPLICATION_PAYLOAD);
+    return;
+  }
+
+  session_->HandlePromised(id(), promised_id, promise_headers);
+  if (visitor() != nullptr) {
+    visitor()->OnPromiseHeadersComplete(promised_id, frame_len);
+  }
+}
+
+void QuicSpdyClientStream::OnBodyAvailable() {
+  // For push streams, visitor will not be set until the rendezvous
+  // between server promise and client request is complete.
+  if (visitor() == nullptr)
+    return;
+
+  while (HasBytesToRead()) {
+    struct iovec iov;
+    if (GetReadableRegions(&iov, 1) == 0) {
+      // No more data to read.
+      break;
+    }
+    QUIC_DVLOG(1) << "Client processed " << iov.iov_len << " bytes for stream "
+                  << id();
+    data_.append(static_cast<char*>(iov.iov_base), iov.iov_len);
+
+    if (content_length_ >= 0 &&
+        data_.size() > static_cast<uint64_t>(content_length_)) {
+      QUIC_DLOG(ERROR) << "Invalid content length (" << content_length_
+                       << ") with data of size " << data_.size();
+      Reset(QUIC_BAD_APPLICATION_PAYLOAD);
+      return;
+    }
+    MarkConsumed(iov.iov_len);
+  }
+  if (sequencer()->IsClosed()) {
+    OnFinRead();
+  } else {
+    sequencer()->SetUnblocked();
+  }
+}
+
+size_t QuicSpdyClientStream::SendRequest(SpdyHeaderBlock headers,
+                                         QuicStringPiece body,
+                                         bool fin) {
+  QuicConnection::ScopedPacketFlusher flusher(
+      session_->connection(), QuicConnection::SEND_ACK_IF_QUEUED);
+  bool send_fin_with_headers = fin && body.empty();
+  size_t bytes_sent = body.size();
+  header_bytes_written_ =
+      WriteHeaders(std::move(headers), send_fin_with_headers, nullptr);
+  bytes_sent += header_bytes_written_;
+
+  if (!body.empty()) {
+    WriteOrBufferBody(body, fin);
+  }
+
+  return bytes_sent;
+}
+
+}  // namespace quic
diff --git a/quic/core/http/quic_spdy_client_stream.h b/quic/core/http/quic_spdy_client_stream.h
new file mode 100644
index 0000000..8a66740
--- /dev/null
+++ b/quic/core/http/quic_spdy_client_stream.h
@@ -0,0 +1,101 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_HTTP_QUIC_SPDY_CLIENT_STREAM_H_
+#define QUICHE_QUIC_CORE_HTTP_QUIC_SPDY_CLIENT_STREAM_H_
+
+#include <cstddef>
+
+#include "base/macros.h"
+#include "net/third_party/quiche/src/quic/core/http/quic_spdy_stream.h"
+#include "net/third_party/quiche/src/quic/core/quic_packets.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_string.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_string_piece.h"
+#include "net/third_party/quiche/src/spdy/core/spdy_framer.h"
+
+namespace quic {
+
+class QuicSpdyClientSession;
+
+// All this does right now is send an SPDY request, and aggregate the
+// SPDY response.
+class QuicSpdyClientStream : public QuicSpdyStream {
+ public:
+  QuicSpdyClientStream(QuicStreamId id,
+                       QuicSpdyClientSession* session,
+                       StreamType type);
+  QuicSpdyClientStream(PendingStream pending,
+                       QuicSpdyClientSession* spdy_session,
+                       StreamType type);
+  QuicSpdyClientStream(const QuicSpdyClientStream&) = delete;
+  QuicSpdyClientStream& operator=(const QuicSpdyClientStream&) = delete;
+  ~QuicSpdyClientStream() override;
+
+  // Override the base class to parse and store headers.
+  void OnInitialHeadersComplete(bool fin,
+                                size_t frame_len,
+                                const QuicHeaderList& header_list) override;
+
+  // Override the base class to parse and store trailers.
+  void OnTrailingHeadersComplete(bool fin,
+                                 size_t frame_len,
+                                 const QuicHeaderList& header_list) override;
+
+  // Override the base class to handle creation of the push stream.
+  void OnPromiseHeaderList(QuicStreamId promised_id,
+                           size_t frame_len,
+                           const QuicHeaderList& header_list) override;
+
+  // QuicStream implementation called by the session when there's data for us.
+  void OnBodyAvailable() override;
+
+  // Serializes the headers and body, sends it to the server, and
+  // returns the number of bytes sent.
+  size_t SendRequest(spdy::SpdyHeaderBlock headers,
+                     QuicStringPiece body,
+                     bool fin);
+
+  // Returns the response data.
+  const QuicString& data() { return data_; }
+
+  // Returns whatever headers have been received for this stream.
+  const spdy::SpdyHeaderBlock& response_headers() { return response_headers_; }
+
+  const spdy::SpdyHeaderBlock& preliminary_headers() {
+    return preliminary_headers_;
+  }
+
+  size_t header_bytes_read() const { return header_bytes_read_; }
+
+  size_t header_bytes_written() const { return header_bytes_written_; }
+
+  int response_code() const { return response_code_; }
+
+  // While the server's SetPriority shouldn't be called externally, the creator
+  // of client-side streams should be able to set the priority.
+  using QuicSpdyStream::SetPriority;
+
+ private:
+  // The parsed headers received from the server.
+  spdy::SpdyHeaderBlock response_headers_;
+
+  // The parsed content-length, or -1 if none is specified.
+  int64_t content_length_;
+  int response_code_;
+  QuicString data_;
+  size_t header_bytes_read_;
+  size_t header_bytes_written_;
+
+  QuicSpdyClientSession* session_;
+
+  // These preliminary headers are used for the 100 Continue headers
+  // that may arrive before the response headers when the request has
+  // Expect: 100-continue.
+  bool has_preliminary_headers_;
+  spdy::SpdyHeaderBlock preliminary_headers_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_HTTP_QUIC_SPDY_CLIENT_STREAM_H_
diff --git a/quic/core/http/quic_spdy_client_stream_test.cc b/quic/core/http/quic_spdy_client_stream_test.cc
new file mode 100644
index 0000000..0b2c157
--- /dev/null
+++ b/quic/core/http/quic_spdy_client_stream_test.cc
@@ -0,0 +1,233 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/third_party/quiche/src/quic/core/http/quic_spdy_client_stream.h"
+
+#include <memory>
+
+#include "base/macros.h"
+#include "net/third_party/quiche/src/quic/core/http/quic_spdy_client_session.h"
+#include "net/third_party/quiche/src/quic/core/http/spdy_utils.h"
+#include "net/third_party/quiche/src/quic/core/quic_utils.h"
+#include "net/third_party/quiche/src/quic/core/tls_client_handshaker.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_logging.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_ptr_util.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_socket_address.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_string.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_test.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_text_utils.h"
+#include "net/third_party/quiche/src/quic/test_tools/crypto_test_utils.h"
+#include "net/third_party/quiche/src/quic/test_tools/quic_spdy_session_peer.h"
+#include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h"
+
+using spdy::SpdyHeaderBlock;
+using testing::_;
+using testing::StrictMock;
+
+namespace quic {
+namespace test {
+
+namespace {
+
+class MockQuicSpdyClientSession : public QuicSpdyClientSession {
+ public:
+  explicit MockQuicSpdyClientSession(
+      const ParsedQuicVersionVector& supported_versions,
+      QuicConnection* connection,
+      QuicClientPushPromiseIndex* push_promise_index)
+      : QuicSpdyClientSession(DefaultQuicConfig(),
+                              supported_versions,
+                              connection,
+                              QuicServerId("example.com", 443, false),
+                              &crypto_config_,
+                              push_promise_index),
+        crypto_config_(crypto_test_utils::ProofVerifierForTesting(),
+                       TlsClientHandshaker::CreateSslCtx()) {}
+  MockQuicSpdyClientSession(const MockQuicSpdyClientSession&) = delete;
+  MockQuicSpdyClientSession& operator=(const MockQuicSpdyClientSession&) =
+      delete;
+  ~MockQuicSpdyClientSession() override = default;
+
+  MOCK_METHOD1(CloseStream, void(QuicStreamId stream_id));
+
+ private:
+  QuicCryptoClientConfig crypto_config_;
+};
+
+class QuicSpdyClientStreamTest : public QuicTestWithParam<ParsedQuicVersion> {
+ public:
+  class StreamVisitor;
+
+  QuicSpdyClientStreamTest()
+      : connection_(
+            new StrictMock<MockQuicConnection>(&helper_,
+                                               &alarm_factory_,
+                                               Perspective::IS_CLIENT,
+                                               SupportedVersions(GetParam()))),
+        session_(connection_->supported_versions(),
+                 connection_,
+                 &push_promise_index_),
+        body_("hello world") {
+    session_.Initialize();
+
+    headers_[":status"] = "200";
+    headers_["content-length"] = "11";
+
+    stream_ = QuicMakeUnique<QuicSpdyClientStream>(
+        GetNthClientInitiatedBidirectionalStreamId(
+            connection_->transport_version(), 0),
+        &session_, BIDIRECTIONAL);
+    stream_visitor_ = QuicMakeUnique<StreamVisitor>();
+    stream_->set_visitor(stream_visitor_.get());
+  }
+
+  class StreamVisitor : public QuicSpdyClientStream::Visitor {
+    void OnClose(QuicSpdyStream* stream) override {
+      QUIC_DVLOG(1) << "stream " << stream->id();
+    }
+  };
+
+  MockQuicConnectionHelper helper_;
+  MockAlarmFactory alarm_factory_;
+  StrictMock<MockQuicConnection>* connection_;
+  QuicClientPushPromiseIndex push_promise_index_;
+
+  MockQuicSpdyClientSession session_;
+  std::unique_ptr<QuicSpdyClientStream> stream_;
+  std::unique_ptr<StreamVisitor> stream_visitor_;
+  SpdyHeaderBlock headers_;
+  QuicString body_;
+  HttpEncoder encoder_;
+};
+
+INSTANTIATE_TEST_SUITE_P(Tests,
+                         QuicSpdyClientStreamTest,
+                         ::testing::ValuesIn(AllSupportedVersions()));
+
+TEST_P(QuicSpdyClientStreamTest, TestReceivingIllegalResponseStatusCode) {
+  headers_[":status"] = "200 ok";
+
+  EXPECT_CALL(*connection_, SendControlFrame(_));
+  EXPECT_CALL(*connection_,
+              OnStreamReset(stream_->id(), QUIC_BAD_APPLICATION_PAYLOAD));
+  auto headers = AsHeaderList(headers_);
+  stream_->OnStreamHeaderList(false, headers.uncompressed_header_bytes(),
+                              headers);
+  EXPECT_EQ(QUIC_BAD_APPLICATION_PAYLOAD, stream_->stream_error());
+}
+
+TEST_P(QuicSpdyClientStreamTest, TestFraming) {
+  auto headers = AsHeaderList(headers_);
+  stream_->OnStreamHeaderList(false, headers.uncompressed_header_bytes(),
+                              headers);
+  std::unique_ptr<char[]> buffer;
+  QuicByteCount header_length =
+      encoder_.SerializeDataFrameHeader(body_.length(), &buffer);
+  QuicString header = QuicString(buffer.get(), header_length);
+  QuicString data = VersionHasDataFrameHeader(connection_->transport_version())
+                        ? header + body_
+                        : body_;
+  stream_->OnStreamFrame(
+      QuicStreamFrame(stream_->id(), /*fin=*/false, /*offset=*/0, data));
+  EXPECT_EQ("200", stream_->response_headers().find(":status")->second);
+  EXPECT_EQ(200, stream_->response_code());
+  EXPECT_EQ(body_, stream_->data());
+}
+
+TEST_P(QuicSpdyClientStreamTest, TestFraming100Continue) {
+  headers_[":status"] = "100";
+  auto headers = AsHeaderList(headers_);
+  stream_->OnStreamHeaderList(false, headers.uncompressed_header_bytes(),
+                              headers);
+  stream_->OnStreamFrame(
+      QuicStreamFrame(stream_->id(), /*fin=*/false, /*offset=*/0, body_));
+  EXPECT_EQ("100", stream_->preliminary_headers().find(":status")->second);
+  EXPECT_EQ(0u, stream_->response_headers().size());
+  EXPECT_EQ(100, stream_->response_code());
+  EXPECT_EQ("", stream_->data());
+}
+
+TEST_P(QuicSpdyClientStreamTest, TestFramingOnePacket) {
+  auto headers = AsHeaderList(headers_);
+  stream_->OnStreamHeaderList(false, headers.uncompressed_header_bytes(),
+                              headers);
+  std::unique_ptr<char[]> buffer;
+  QuicByteCount header_length =
+      encoder_.SerializeDataFrameHeader(body_.length(), &buffer);
+  QuicString header = QuicString(buffer.get(), header_length);
+  QuicString data = VersionHasDataFrameHeader(connection_->transport_version())
+                        ? header + body_
+                        : body_;
+  stream_->OnStreamFrame(
+      QuicStreamFrame(stream_->id(), /*fin=*/false, /*offset=*/0, data));
+  EXPECT_EQ("200", stream_->response_headers().find(":status")->second);
+  EXPECT_EQ(200, stream_->response_code());
+  EXPECT_EQ(body_, stream_->data());
+}
+
+TEST_P(QuicSpdyClientStreamTest,
+       QUIC_TEST_DISABLED_IN_CHROME(TestFramingExtraData)) {
+  QuicString large_body = "hello world!!!!!!";
+
+  auto headers = AsHeaderList(headers_);
+  stream_->OnStreamHeaderList(false, headers.uncompressed_header_bytes(),
+                              headers);
+  // The headers should parse successfully.
+  EXPECT_EQ(QUIC_STREAM_NO_ERROR, stream_->stream_error());
+  EXPECT_EQ("200", stream_->response_headers().find(":status")->second);
+  EXPECT_EQ(200, stream_->response_code());
+  std::unique_ptr<char[]> buffer;
+  QuicByteCount header_length =
+      encoder_.SerializeDataFrameHeader(large_body.length(), &buffer);
+  QuicString header = QuicString(buffer.get(), header_length);
+  QuicString data = VersionHasDataFrameHeader(connection_->transport_version())
+                        ? header + large_body
+                        : large_body;
+  EXPECT_CALL(*connection_, SendControlFrame(_));
+  EXPECT_CALL(*connection_,
+              OnStreamReset(stream_->id(), QUIC_BAD_APPLICATION_PAYLOAD));
+
+  stream_->OnStreamFrame(
+      QuicStreamFrame(stream_->id(), /*fin=*/false, /*offset=*/0, data));
+
+  EXPECT_NE(QUIC_STREAM_NO_ERROR, stream_->stream_error());
+}
+
+TEST_P(QuicSpdyClientStreamTest, ReceivingTrailers) {
+  // Test that receiving trailing headers, containing a final offset, results in
+  // the stream being closed at that byte offset.
+
+  // Send headers as usual.
+  auto headers = AsHeaderList(headers_);
+  stream_->OnStreamHeaderList(false, headers.uncompressed_header_bytes(),
+                              headers);
+
+  // Send trailers before sending the body. Even though a FIN has been received
+  // the stream should not be closed, as it does not yet have all the data bytes
+  // promised by the final offset field.
+  SpdyHeaderBlock trailer_block;
+  trailer_block["trailer key"] = "trailer value";
+  trailer_block[kFinalOffsetHeaderKey] =
+      QuicTextUtils::Uint64ToString(body_.size());
+  auto trailers = AsHeaderList(trailer_block);
+  stream_->OnStreamHeaderList(true, trailers.uncompressed_header_bytes(),
+                              trailers);
+
+  // Now send the body, which should close the stream as the FIN has been
+  // received, as well as all data.
+  std::unique_ptr<char[]> buffer;
+  QuicByteCount header_length =
+      encoder_.SerializeDataFrameHeader(body_.length(), &buffer);
+  QuicString header = QuicString(buffer.get(), header_length);
+  QuicString data = VersionHasDataFrameHeader(connection_->transport_version())
+                        ? header + body_
+                        : body_;
+  stream_->OnStreamFrame(
+      QuicStreamFrame(stream_->id(), /*fin=*/false, /*offset=*/0, data));
+  EXPECT_TRUE(stream_->reading_stopped());
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quic/core/http/quic_spdy_server_stream_base.cc b/quic/core/http/quic_spdy_server_stream_base.cc
new file mode 100644
index 0000000..cbe479e
--- /dev/null
+++ b/quic/core/http/quic_spdy_server_stream_base.cc
@@ -0,0 +1,48 @@
+// Copyright (c) 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/third_party/quiche/src/quic/core/http/quic_spdy_server_stream_base.h"
+
+#include "net/third_party/quiche/src/quic/core/quic_error_codes.h"
+#include "net/third_party/quiche/src/quic/core/quic_session.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_logging.h"
+
+namespace quic {
+
+QuicSpdyServerStreamBase::QuicSpdyServerStreamBase(QuicStreamId id,
+                                                   QuicSpdySession* session,
+                                                   StreamType type)
+    : QuicSpdyStream(id, session, type) {}
+
+QuicSpdyServerStreamBase::QuicSpdyServerStreamBase(PendingStream pending,
+                                                   QuicSpdySession* session,
+                                                   StreamType type)
+    : QuicSpdyStream(std::move(pending), session, type) {}
+
+void QuicSpdyServerStreamBase::CloseWriteSide() {
+  if (!fin_received() && !rst_received() && sequencer()->ignore_read_data() &&
+      !rst_sent()) {
+    // Early cancel the stream if it has stopped reading before receiving FIN
+    // or RST.
+    DCHECK(fin_sent() || !session()->connection()->connected());
+    // Tell the peer to stop sending further data.
+    QUIC_DVLOG(1) << " Server: Send QUIC_STREAM_NO_ERROR on stream " << id();
+    Reset(QUIC_STREAM_NO_ERROR);
+  }
+
+  QuicSpdyStream::CloseWriteSide();
+}
+
+void QuicSpdyServerStreamBase::StopReading() {
+  if (!fin_received() && !rst_received() && write_side_closed() &&
+      !rst_sent()) {
+    DCHECK(fin_sent());
+    // Tell the peer to stop sending further data.
+    QUIC_DVLOG(1) << " Server: Send QUIC_STREAM_NO_ERROR on stream " << id();
+    Reset(QUIC_STREAM_NO_ERROR);
+  }
+  QuicSpdyStream::StopReading();
+}
+
+}  // namespace quic
diff --git a/quic/core/http/quic_spdy_server_stream_base.h b/quic/core/http/quic_spdy_server_stream_base.h
new file mode 100644
index 0000000..438d152
--- /dev/null
+++ b/quic/core/http/quic_spdy_server_stream_base.h
@@ -0,0 +1,31 @@
+// Copyright (c) 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_HTTP_QUIC_SPDY_SERVER_STREAM_BASE_H_
+#define QUICHE_QUIC_CORE_HTTP_QUIC_SPDY_SERVER_STREAM_BASE_H_
+
+#include "net/third_party/quiche/src/quic/core/http/quic_spdy_stream.h"
+
+namespace quic {
+
+class QuicSpdyServerStreamBase : public QuicSpdyStream {
+ public:
+  QuicSpdyServerStreamBase(QuicStreamId id,
+                           QuicSpdySession* session,
+                           StreamType type);
+  QuicSpdyServerStreamBase(PendingStream pending,
+                           QuicSpdySession* session,
+                           StreamType type);
+  QuicSpdyServerStreamBase(const QuicSpdyServerStreamBase&) = delete;
+  QuicSpdyServerStreamBase& operator=(const QuicSpdyServerStreamBase&) = delete;
+
+  // Override the base class to send QUIC_STREAM_NO_ERROR to the peer
+  // when the stream has not received all the data.
+  void CloseWriteSide() override;
+  void StopReading() override;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_HTTP_QUIC_SPDY_SERVER_STREAM_BASE_H_
diff --git a/quic/core/http/quic_spdy_server_stream_base_test.cc b/quic/core/http/quic_spdy_server_stream_base_test.cc
new file mode 100644
index 0000000..4e1aa1b
--- /dev/null
+++ b/quic/core/http/quic_spdy_server_stream_base_test.cc
@@ -0,0 +1,94 @@
+// Copyright (c) 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/third_party/quiche/src/quic/core/http/quic_spdy_server_stream_base.h"
+
+#include "net/third_party/quiche/src/quic/platform/api/quic_ptr_util.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_test.h"
+#include "net/third_party/quiche/src/quic/test_tools/quic_spdy_session_peer.h"
+#include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h"
+
+using testing::_;
+
+namespace quic {
+namespace test {
+namespace {
+
+class TestQuicSpdyServerStream : public QuicSpdyServerStreamBase {
+ public:
+  TestQuicSpdyServerStream(QuicStreamId id,
+                           QuicSpdySession* session,
+                           StreamType type)
+      : QuicSpdyServerStreamBase(id, session, type) {}
+
+  void OnBodyAvailable() override {}
+};
+
+class QuicSpdyServerStreamBaseTest : public QuicTest {
+ protected:
+  QuicSpdyServerStreamBaseTest()
+      : session_(new MockQuicConnection(&helper_,
+                                        &alarm_factory_,
+                                        Perspective::IS_SERVER)) {
+    stream_ = new TestQuicSpdyServerStream(
+        GetNthClientInitiatedBidirectionalStreamId(
+            session_.connection()->transport_version(), 0),
+        &session_, BIDIRECTIONAL);
+    session_.ActivateStream(QuicWrapUnique(stream_));
+    helper_.AdvanceTime(QuicTime::Delta::FromSeconds(1));
+  }
+
+  QuicSpdyServerStreamBase* stream_ = nullptr;
+  MockQuicConnectionHelper helper_;
+  MockAlarmFactory alarm_factory_;
+  MockQuicSpdySession session_;
+};
+
+TEST_F(QuicSpdyServerStreamBaseTest,
+       SendQuicRstStreamNoErrorWithEarlyResponse) {
+  stream_->StopReading();
+  EXPECT_CALL(session_, SendRstStream(_, QUIC_STREAM_NO_ERROR, _)).Times(1);
+  stream_->set_fin_sent(true);
+  stream_->CloseWriteSide();
+}
+
+TEST_F(QuicSpdyServerStreamBaseTest,
+       DoNotSendQuicRstStreamNoErrorWithRstReceived) {
+  EXPECT_FALSE(stream_->reading_stopped());
+
+  EXPECT_CALL(session_, SendRstStream(_, QUIC_STREAM_NO_ERROR, _)).Times(0);
+
+  if (session_.connection()->transport_version() != QUIC_VERSION_99) {
+    EXPECT_CALL(session_, SendRstStream(_, QUIC_RST_ACKNOWLEDGEMENT, _))
+        .Times(1);
+  } else {
+    // Intercept & check that the call to the QuicConnection's OnStreamReast
+    // has correct stream ID and error code -- for V99/IETF Quic, it should
+    // have the STREAM_CANCELLED error code, not RST_ACK... Capture
+    // OnStreamReset (rather than SendRstStream) because the V99 path bypasses
+    // SendRstStream, calling SendRstStreamInner directly. Mocking
+    // SendRstStreamInner is problematic since the test relies on it to perform
+    // the closing operations and getting the stream in the correct state.
+    EXPECT_CALL(*(static_cast<MockQuicConnection*>(session_.connection())),
+                OnStreamReset(stream_->id(), QUIC_STREAM_CANCELLED));
+  }
+  QuicRstStreamFrame rst_frame(kInvalidControlFrameId, stream_->id(),
+                               QUIC_STREAM_CANCELLED, 1234);
+  stream_->OnStreamReset(rst_frame);
+  if (session_.connection()->transport_version() == QUIC_VERSION_99) {
+    // Create and inject a STOP SENDING frame to complete the close
+    // of the stream. This is only needed for version 99/IETF QUIC.
+    QuicStopSendingFrame stop_sending(
+        kInvalidControlFrameId, stream_->id(),
+        static_cast<QuicApplicationErrorCode>(QUIC_STREAM_CANCELLED));
+    session_.OnStopSendingFrame(stop_sending);
+  }
+
+  EXPECT_TRUE(stream_->reading_stopped());
+  EXPECT_TRUE(stream_->write_side_closed());
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quic/core/http/quic_spdy_session.cc b/quic/core/http/quic_spdy_session.cc
new file mode 100644
index 0000000..01e630d
--- /dev/null
+++ b/quic/core/http/quic_spdy_session.cc
@@ -0,0 +1,696 @@
+// Copyright (c) 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/third_party/quiche/src/quic/core/http/quic_spdy_session.h"
+
+#include <algorithm>
+#include <cstdint>
+#include <utility>
+
+#include "net/third_party/quiche/src/quic/core/http/quic_headers_stream.h"
+#include "net/third_party/quiche/src/quic/core/quic_utils.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_bug_tracker.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_fallthrough.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_flag_utils.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_flags.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_logging.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_ptr_util.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_str_cat.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_string.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_text_utils.h"
+#include "net/third_party/quiche/src/spdy/core/http2_frame_decoder_adapter.h"
+
+using http2::Http2DecoderAdapter;
+using spdy::HpackEntry;
+using spdy::HpackHeaderTable;
+using spdy::Http2WeightToSpdy3Priority;
+using spdy::SETTINGS_ENABLE_PUSH;
+using spdy::SETTINGS_HEADER_TABLE_SIZE;
+using spdy::SETTINGS_MAX_HEADER_LIST_SIZE;
+using spdy::Spdy3PriorityToHttp2Weight;
+using spdy::SpdyErrorCode;
+using spdy::SpdyFramer;
+using spdy::SpdyFramerDebugVisitorInterface;
+using spdy::SpdyFramerVisitorInterface;
+using spdy::SpdyFrameType;
+using spdy::SpdyHeaderBlock;
+using spdy::SpdyHeadersHandlerInterface;
+using spdy::SpdyHeadersIR;
+using spdy::SpdyKnownSettingsId;
+using spdy::SpdyPingId;
+using spdy::SpdyPriority;
+using spdy::SpdyPriorityIR;
+using spdy::SpdyPushPromiseIR;
+using spdy::SpdySerializedFrame;
+using spdy::SpdySettingsId;
+using spdy::SpdySettingsIR;
+using spdy::SpdyStreamId;
+
+namespace quic {
+
+namespace {
+
+class HeaderTableDebugVisitor : public HpackHeaderTable::DebugVisitorInterface {
+ public:
+  HeaderTableDebugVisitor(const QuicClock* clock,
+                          std::unique_ptr<QuicHpackDebugVisitor> visitor)
+      : clock_(clock), headers_stream_hpack_visitor_(std::move(visitor)) {}
+  HeaderTableDebugVisitor(const HeaderTableDebugVisitor&) = delete;
+  HeaderTableDebugVisitor& operator=(const HeaderTableDebugVisitor&) = delete;
+
+  int64_t OnNewEntry(const HpackEntry& entry) override {
+    QUIC_DVLOG(1) << entry.GetDebugString();
+    return (clock_->ApproximateNow() - QuicTime::Zero()).ToMicroseconds();
+  }
+
+  void OnUseEntry(const HpackEntry& entry) override {
+    const QuicTime::Delta elapsed(
+        clock_->ApproximateNow() -
+        QuicTime::Delta::FromMicroseconds(entry.time_added()) -
+        QuicTime::Zero());
+    QUIC_DVLOG(1) << entry.GetDebugString() << " " << elapsed.ToMilliseconds()
+                  << " ms";
+    headers_stream_hpack_visitor_->OnUseEntry(elapsed);
+  }
+
+ private:
+  const QuicClock* clock_;
+  std::unique_ptr<QuicHpackDebugVisitor> headers_stream_hpack_visitor_;
+};
+
+}  // namespace
+
+// A SpdyFramerVisitor that passes HEADERS frames to the QuicSpdyStream, and
+// closes the connection if any unexpected frames are received.
+class QuicSpdySession::SpdyFramerVisitor
+    : public SpdyFramerVisitorInterface,
+      public SpdyFramerDebugVisitorInterface {
+ public:
+  explicit SpdyFramerVisitor(QuicSpdySession* session) : session_(session) {}
+  SpdyFramerVisitor(const SpdyFramerVisitor&) = delete;
+  SpdyFramerVisitor& operator=(const SpdyFramerVisitor&) = delete;
+
+  SpdyHeadersHandlerInterface* OnHeaderFrameStart(
+      SpdyStreamId /* stream_id */) override {
+    return &header_list_;
+  }
+
+  void OnHeaderFrameEnd(SpdyStreamId /* stream_id */) override {
+    if (session_->IsConnected()) {
+      session_->OnHeaderList(header_list_);
+    }
+    header_list_.Clear();
+  }
+
+  void OnStreamFrameData(SpdyStreamId stream_id,
+                         const char* data,
+                         size_t len) override {
+    CloseConnection("SPDY DATA frame received.",
+                    QUIC_INVALID_HEADERS_STREAM_DATA);
+  }
+
+  void OnStreamEnd(SpdyStreamId stream_id) override {
+    // The framer invokes OnStreamEnd after processing a frame that had the fin
+    // bit set.
+  }
+
+  void OnStreamPadding(SpdyStreamId stream_id, size_t len) override {
+    CloseConnection("SPDY frame padding received.",
+                    QUIC_INVALID_HEADERS_STREAM_DATA);
+  }
+
+  void OnError(Http2DecoderAdapter::SpdyFramerError error) override {
+    QuicErrorCode code = QUIC_INVALID_HEADERS_STREAM_DATA;
+    switch (error) {
+      case Http2DecoderAdapter::SpdyFramerError::SPDY_DECOMPRESS_FAILURE:
+        code = QUIC_HEADERS_STREAM_DATA_DECOMPRESS_FAILURE;
+        break;
+      default:
+        break;
+    }
+    CloseConnection(
+        QuicStrCat("SPDY framing error: ",
+                   Http2DecoderAdapter::SpdyFramerErrorToString(error)),
+        code);
+  }
+
+  void OnDataFrameHeader(SpdyStreamId stream_id,
+                         size_t length,
+                         bool fin) override {
+    CloseConnection("SPDY DATA frame received.",
+                    QUIC_INVALID_HEADERS_STREAM_DATA);
+  }
+
+  void OnRstStream(SpdyStreamId stream_id, SpdyErrorCode error_code) override {
+    CloseConnection("SPDY RST_STREAM frame received.",
+                    QUIC_INVALID_HEADERS_STREAM_DATA);
+  }
+
+  void OnSetting(SpdySettingsId id, uint32_t value) override {
+    switch (id) {
+      case SETTINGS_HEADER_TABLE_SIZE:
+        session_->UpdateHeaderEncoderTableSize(value);
+        break;
+      case SETTINGS_ENABLE_PUSH:
+        if (session_->perspective() == Perspective::IS_SERVER) {
+          // See rfc7540, Section 6.5.2.
+          if (value > 1) {
+            CloseConnection(
+                QuicStrCat("Invalid value for SETTINGS_ENABLE_PUSH: ", value),
+                QUIC_INVALID_HEADERS_STREAM_DATA);
+            return;
+          }
+          session_->UpdateEnableServerPush(value > 0);
+          break;
+        } else {
+          CloseConnection(
+              QuicStrCat("Unsupported field of HTTP/2 SETTINGS frame: ", id),
+              QUIC_INVALID_HEADERS_STREAM_DATA);
+        }
+        break;
+      // TODO(fayang): Need to support SETTINGS_MAX_HEADER_LIST_SIZE when
+      // clients are actually sending it.
+      case SETTINGS_MAX_HEADER_LIST_SIZE:
+        break;
+      default:
+        CloseConnection(
+            QuicStrCat("Unsupported field of HTTP/2 SETTINGS frame: ", id),
+            QUIC_INVALID_HEADERS_STREAM_DATA);
+    }
+  }
+
+  void OnSettingsEnd() override {}
+
+  void OnPing(SpdyPingId unique_id, bool is_ack) override {
+    CloseConnection("SPDY PING frame received.",
+                    QUIC_INVALID_HEADERS_STREAM_DATA);
+  }
+
+  void OnGoAway(SpdyStreamId last_accepted_stream_id,
+                SpdyErrorCode error_code) override {
+    CloseConnection("SPDY GOAWAY frame received.",
+                    QUIC_INVALID_HEADERS_STREAM_DATA);
+  }
+
+  void OnHeaders(SpdyStreamId stream_id,
+                 bool has_priority,
+                 int weight,
+                 SpdyStreamId /*parent_stream_id*/,
+                 bool /*exclusive*/,
+                 bool fin,
+                 bool end) override {
+    if (!session_->IsConnected()) {
+      return;
+    }
+
+    // TODO(mpw): avoid down-conversion and plumb SpdyStreamPrecedence through
+    // QuicHeadersStream.
+    SpdyPriority priority =
+        has_priority ? Http2WeightToSpdy3Priority(weight) : 0;
+    session_->OnHeaders(stream_id, has_priority, priority, fin);
+  }
+
+  void OnWindowUpdate(SpdyStreamId stream_id, int delta_window_size) override {
+    CloseConnection("SPDY WINDOW_UPDATE frame received.",
+                    QUIC_INVALID_HEADERS_STREAM_DATA);
+  }
+
+  void OnPushPromise(SpdyStreamId stream_id,
+                     SpdyStreamId promised_stream_id,
+                     bool end) override {
+    if (!session_->supports_push_promise()) {
+      CloseConnection("PUSH_PROMISE not supported.",
+                      QUIC_INVALID_HEADERS_STREAM_DATA);
+      return;
+    }
+    if (!session_->IsConnected()) {
+      return;
+    }
+    session_->OnPushPromise(stream_id, promised_stream_id, end);
+  }
+
+  void OnContinuation(SpdyStreamId stream_id, bool end) override {}
+
+  void OnPriority(SpdyStreamId stream_id,
+                  SpdyStreamId parent_id,
+                  int weight,
+                  bool exclusive) override {
+    if (session_->connection()->transport_version() <= QUIC_VERSION_39) {
+      CloseConnection("SPDY PRIORITY frame received.",
+                      QUIC_INVALID_HEADERS_STREAM_DATA);
+      return;
+    }
+    if (!session_->IsConnected()) {
+      return;
+    }
+    // TODO (wangyix): implement real HTTP/2 weights and dependencies instead of
+    // converting to SpdyPriority.
+    SpdyPriority priority = Http2WeightToSpdy3Priority(weight);
+    session_->OnPriority(stream_id, priority);
+  }
+
+  bool OnUnknownFrame(SpdyStreamId stream_id, uint8_t frame_type) override {
+    CloseConnection("Unknown frame type received.",
+                    QUIC_INVALID_HEADERS_STREAM_DATA);
+    return false;
+  }
+
+  // SpdyFramerDebugVisitorInterface implementation
+  void OnSendCompressedFrame(SpdyStreamId stream_id,
+                             SpdyFrameType type,
+                             size_t payload_len,
+                             size_t frame_len) override {
+    if (payload_len == 0) {
+      QUIC_BUG << "Zero payload length.";
+      return;
+    }
+    int compression_pct = 100 - (100 * frame_len) / payload_len;
+    QUIC_DVLOG(1) << "Net.QuicHpackCompressionPercentage: " << compression_pct;
+  }
+
+  void OnReceiveCompressedFrame(SpdyStreamId stream_id,
+                                SpdyFrameType type,
+                                size_t frame_len) override {
+    if (session_->IsConnected()) {
+      session_->OnCompressedFrameSize(frame_len);
+    }
+  }
+
+  void set_max_uncompressed_header_bytes(
+      size_t set_max_uncompressed_header_bytes) {
+    header_list_.set_max_header_list_size(set_max_uncompressed_header_bytes);
+  }
+
+ private:
+  void CloseConnection(const QuicString& details, QuicErrorCode code) {
+    if (session_->IsConnected()) {
+      session_->CloseConnectionWithDetails(code, details);
+    }
+  }
+
+ private:
+  QuicSpdySession* session_;
+  QuicHeaderList header_list_;
+};
+
+QuicHpackDebugVisitor::QuicHpackDebugVisitor() {}
+
+QuicHpackDebugVisitor::~QuicHpackDebugVisitor() {}
+
+QuicSpdySession::QuicSpdySession(
+    QuicConnection* connection,
+    QuicSession::Visitor* visitor,
+    const QuicConfig& config,
+    const ParsedQuicVersionVector& supported_versions)
+    : QuicSession(connection, visitor, config, supported_versions),
+      max_inbound_header_list_size_(kDefaultMaxUncompressedHeaderSize),
+      server_push_enabled_(true),
+      stream_id_(
+          QuicUtils::GetInvalidStreamId(connection->transport_version())),
+      promised_stream_id_(
+          QuicUtils::GetInvalidStreamId(connection->transport_version())),
+      fin_(false),
+      frame_len_(0),
+      uncompressed_frame_len_(0),
+      supports_push_promise_(perspective() == Perspective::IS_CLIENT),
+      spdy_framer_(SpdyFramer::ENABLE_COMPRESSION),
+      spdy_framer_visitor_(new SpdyFramerVisitor(this)) {
+  h2_deframer_.set_visitor(spdy_framer_visitor_.get());
+  h2_deframer_.set_debug_visitor(spdy_framer_visitor_.get());
+  spdy_framer_.set_debug_visitor(spdy_framer_visitor_.get());
+}
+
+QuicSpdySession::~QuicSpdySession() {
+  // Set the streams' session pointers in closed and dynamic stream lists
+  // to null to avoid subsequent use of this session.
+  for (auto& stream : *closed_streams()) {
+    static_cast<QuicSpdyStream*>(stream.get())->ClearSession();
+  }
+  for (auto const& kv : zombie_streams()) {
+    static_cast<QuicSpdyStream*>(kv.second.get())->ClearSession();
+  }
+  for (auto const& kv : dynamic_streams()) {
+    static_cast<QuicSpdyStream*>(kv.second.get())->ClearSession();
+  }
+}
+
+void QuicSpdySession::Initialize() {
+  QuicSession::Initialize();
+
+  if (perspective() == Perspective::IS_SERVER) {
+    set_largest_peer_created_stream_id(
+        QuicUtils::GetHeadersStreamId(connection()->transport_version()));
+  } else {
+    QuicStreamId headers_stream_id = GetNextOutgoingBidirectionalStreamId();
+    DCHECK_EQ(headers_stream_id,
+              QuicUtils::GetHeadersStreamId(connection()->transport_version()));
+  }
+
+  if (VersionUsesQpack(connection()->transport_version())) {
+    qpack_encoder_ = QuicMakeUnique<QpackEncoder>(this, this);
+    qpack_decoder_ = QuicMakeUnique<QpackDecoder>(this, this);
+  }
+
+  headers_stream_ = QuicMakeUnique<QuicHeadersStream>((this));
+  DCHECK_EQ(QuicUtils::GetHeadersStreamId(connection()->transport_version()),
+            headers_stream_->id());
+  RegisterStaticStream(
+      QuicUtils::GetHeadersStreamId(connection()->transport_version()),
+      headers_stream_.get());
+
+  set_max_uncompressed_header_bytes(max_inbound_header_list_size_);
+
+  // Limit HPACK buffering to 2x header list size limit.
+  set_max_decode_buffer_size_bytes(2 * max_inbound_header_list_size_);
+}
+
+void QuicSpdySession::OnDecoderStreamError(QuicStringPiece error_message) {
+  DCHECK(VersionUsesQpack(connection()->transport_version()));
+
+  // TODO(112770235): Signal connection error on decoder stream errors.
+  QUIC_NOTREACHED();
+}
+
+void QuicSpdySession::WriteEncoderStreamData(QuicStringPiece data) {
+  DCHECK(VersionUsesQpack(connection()->transport_version()));
+
+  // TODO(112770235): Send encoder stream data on encoder stream.
+  QUIC_NOTREACHED();
+}
+
+void QuicSpdySession::OnEncoderStreamError(QuicStringPiece error_message) {
+  DCHECK(VersionUsesQpack(connection()->transport_version()));
+
+  // TODO(112770235): Signal connection error on encoder stream errors.
+  QUIC_NOTREACHED();
+}
+
+void QuicSpdySession::WriteDecoderStreamData(QuicStringPiece data) {
+  DCHECK(VersionUsesQpack(connection()->transport_version()));
+
+  // TODO(112770235): Send decoder stream data on decoder stream.
+  QUIC_NOTREACHED();
+}
+
+void QuicSpdySession::OnStreamHeadersPriority(QuicStreamId stream_id,
+                                              SpdyPriority priority) {
+  QuicSpdyStream* stream = GetSpdyDataStream(stream_id);
+  if (!stream) {
+    // It's quite possible to receive headers after a stream has been reset.
+    return;
+  }
+  stream->OnStreamHeadersPriority(priority);
+}
+
+void QuicSpdySession::OnStreamHeaderList(QuicStreamId stream_id,
+                                         bool fin,
+                                         size_t frame_len,
+                                         const QuicHeaderList& header_list) {
+  if (QuicContainsKey(static_streams(), stream_id)) {
+    connection()->CloseConnection(
+        QUIC_INVALID_HEADERS_STREAM_DATA, "stream is static",
+        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+    return;
+  }
+  QuicSpdyStream* stream = GetSpdyDataStream(stream_id);
+  if (stream == nullptr) {
+    // The stream no longer exists, but trailing headers may contain the final
+    // byte offset necessary for flow control and open stream accounting.
+    size_t final_byte_offset = 0;
+    for (const auto& header : header_list) {
+      const QuicString& header_key = header.first;
+      const QuicString& header_value = header.second;
+      if (header_key == kFinalOffsetHeaderKey) {
+        if (!QuicTextUtils::StringToSizeT(header_value, &final_byte_offset)) {
+          connection()->CloseConnection(
+              QUIC_INVALID_HEADERS_STREAM_DATA,
+              "Trailers are malformed (no final offset)",
+              ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+          return;
+        }
+        DVLOG(1) << "Received final byte offset in trailers for stream "
+                 << stream_id << ", which no longer exists.";
+        OnFinalByteOffsetReceived(stream_id, final_byte_offset);
+      }
+    }
+
+    // It's quite possible to receive headers after a stream has been reset.
+    return;
+  }
+  stream->OnStreamHeaderList(fin, frame_len, header_list);
+}
+
+void QuicSpdySession::OnPriorityFrame(QuicStreamId stream_id,
+                                      SpdyPriority priority) {
+  QuicSpdyStream* stream = GetSpdyDataStream(stream_id);
+  if (!stream) {
+    // It's quite possible to receive a PRIORITY frame after a stream has been
+    // reset.
+    return;
+  }
+  stream->OnPriorityFrame(priority);
+}
+
+size_t QuicSpdySession::ProcessHeaderData(const struct iovec& iov) {
+  return h2_deframer_.ProcessInput(static_cast<char*>(iov.iov_base),
+                                   iov.iov_len);
+}
+
+size_t QuicSpdySession::WriteHeadersOnHeadersStream(
+    QuicStreamId id,
+    SpdyHeaderBlock headers,
+    bool fin,
+    SpdyPriority priority,
+    QuicReferenceCountedPointer<QuicAckListenerInterface> ack_listener) {
+  return WriteHeadersOnHeadersStreamImpl(
+      id, std::move(headers), fin,
+      /* parent_stream_id = */ 0, Spdy3PriorityToHttp2Weight(priority),
+      /* exclusive = */ false, std::move(ack_listener));
+}
+
+size_t QuicSpdySession::WritePriority(QuicStreamId id,
+                                      QuicStreamId parent_stream_id,
+                                      int weight,
+                                      bool exclusive) {
+  if (connection()->transport_version() <= QUIC_VERSION_39) {
+    return 0;
+  }
+  SpdyPriorityIR priority_frame(id, parent_stream_id, weight, exclusive);
+  SpdySerializedFrame frame(spdy_framer_.SerializeFrame(priority_frame));
+  headers_stream_->WriteOrBufferData(
+      QuicStringPiece(frame.data(), frame.size()), false, nullptr);
+  return frame.size();
+}
+
+size_t QuicSpdySession::WritePushPromise(QuicStreamId original_stream_id,
+                                         QuicStreamId promised_stream_id,
+                                         SpdyHeaderBlock headers) {
+  if (perspective() == Perspective::IS_CLIENT) {
+    QUIC_BUG << "Client shouldn't send PUSH_PROMISE";
+    return 0;
+  }
+
+  SpdyPushPromiseIR push_promise(original_stream_id, promised_stream_id,
+                                 std::move(headers));
+  // PUSH_PROMISE must not be the last frame sent out, at least followed by
+  // response headers.
+  push_promise.set_fin(false);
+
+  SpdySerializedFrame frame(spdy_framer_.SerializeFrame(push_promise));
+  headers_stream_->WriteOrBufferData(
+      QuicStringPiece(frame.data(), frame.size()), false, nullptr);
+  return frame.size();
+}
+
+size_t QuicSpdySession::SendMaxHeaderListSize(size_t value) {
+  SpdySettingsIR settings_frame;
+  settings_frame.AddSetting(SETTINGS_MAX_HEADER_LIST_SIZE, value);
+
+  SpdySerializedFrame frame(spdy_framer_.SerializeFrame(settings_frame));
+  headers_stream_->WriteOrBufferData(
+      QuicStringPiece(frame.data(), frame.size()), false, nullptr);
+  return frame.size();
+}
+
+QpackEncoder* QuicSpdySession::qpack_encoder() {
+  DCHECK(VersionUsesQpack(connection()->transport_version()));
+
+  return qpack_encoder_.get();
+}
+
+QpackDecoder* QuicSpdySession::qpack_decoder() {
+  DCHECK(VersionUsesQpack(connection()->transport_version()));
+
+  return qpack_decoder_.get();
+}
+
+QuicSpdyStream* QuicSpdySession::GetSpdyDataStream(
+    const QuicStreamId stream_id) {
+  return static_cast<QuicSpdyStream*>(GetOrCreateDynamicStream(stream_id));
+}
+
+void QuicSpdySession::OnCryptoHandshakeEvent(CryptoHandshakeEvent event) {
+  QuicSession::OnCryptoHandshakeEvent(event);
+  if (event == HANDSHAKE_CONFIRMED && config()->SupportMaxHeaderListSize()) {
+    SendMaxHeaderListSize(max_inbound_header_list_size_);
+  }
+}
+
+// True if there are open HTTP requests.
+bool QuicSpdySession::ShouldKeepConnectionAlive() const {
+  // Change to check if there are open HTTP requests.
+  // When IETF QUIC control and QPACK streams are used, those will need to be
+  // subtracted from this count to ensure only request streams are counted.
+  return GetNumOpenDynamicStreams() > 0;
+}
+
+bool QuicSpdySession::ShouldBufferIncomingStream(QuicStreamId id) const {
+  DCHECK_EQ(QUIC_VERSION_99, connection()->transport_version());
+  return !QuicUtils::IsBidirectionalStreamId(id);
+}
+
+size_t QuicSpdySession::WriteHeadersOnHeadersStreamImpl(
+    QuicStreamId id,
+    spdy::SpdyHeaderBlock headers,
+    bool fin,
+    QuicStreamId parent_stream_id,
+    int weight,
+    bool exclusive,
+    QuicReferenceCountedPointer<QuicAckListenerInterface> ack_listener) {
+  SpdyHeadersIR headers_frame(id, std::move(headers));
+  headers_frame.set_fin(fin);
+  if (perspective() == Perspective::IS_CLIENT) {
+    headers_frame.set_has_priority(true);
+    headers_frame.set_parent_stream_id(parent_stream_id);
+    headers_frame.set_weight(weight);
+    headers_frame.set_exclusive(exclusive);
+  }
+  SpdySerializedFrame frame(spdy_framer_.SerializeFrame(headers_frame));
+  headers_stream_->WriteOrBufferData(
+      QuicStringPiece(frame.data(), frame.size()), false,
+      std::move(ack_listener));
+  return frame.size();
+}
+
+void QuicSpdySession::OnPromiseHeaderList(QuicStreamId stream_id,
+                                          QuicStreamId promised_stream_id,
+                                          size_t frame_len,
+                                          const QuicHeaderList& header_list) {
+  QuicString error = "OnPromiseHeaderList should be overridden in client code.";
+  QUIC_BUG << error;
+  connection()->CloseConnection(QUIC_INTERNAL_ERROR, error,
+                                ConnectionCloseBehavior::SILENT_CLOSE);
+}
+
+bool QuicSpdySession::ShouldReleaseHeadersStreamSequencerBuffer() {
+  return false;
+}
+
+void QuicSpdySession::OnHeaders(SpdyStreamId stream_id,
+                                bool has_priority,
+                                SpdyPriority priority,
+                                bool fin) {
+  if (has_priority) {
+    if (perspective() == Perspective::IS_CLIENT) {
+      CloseConnectionWithDetails(QUIC_INVALID_HEADERS_STREAM_DATA,
+                                 "Server must not send priorities.");
+      return;
+    }
+    OnStreamHeadersPriority(stream_id, priority);
+  } else {
+    if (perspective() == Perspective::IS_SERVER) {
+      CloseConnectionWithDetails(QUIC_INVALID_HEADERS_STREAM_DATA,
+                                 "Client must send priorities.");
+      return;
+    }
+  }
+  DCHECK_EQ(QuicUtils::GetInvalidStreamId(connection()->transport_version()),
+            stream_id_);
+  DCHECK_EQ(QuicUtils::GetInvalidStreamId(connection()->transport_version()),
+            promised_stream_id_);
+  stream_id_ = stream_id;
+  fin_ = fin;
+}
+
+void QuicSpdySession::OnPushPromise(SpdyStreamId stream_id,
+                                    SpdyStreamId promised_stream_id,
+                                    bool end) {
+  DCHECK_EQ(QuicUtils::GetInvalidStreamId(connection()->transport_version()),
+            stream_id_);
+  DCHECK_EQ(QuicUtils::GetInvalidStreamId(connection()->transport_version()),
+            promised_stream_id_);
+  stream_id_ = stream_id;
+  promised_stream_id_ = promised_stream_id;
+}
+
+// TODO (wangyix): Why is SpdyStreamId used instead of QuicStreamId?
+// This occurs in many places in this file.
+void QuicSpdySession::OnPriority(SpdyStreamId stream_id,
+                                 SpdyPriority priority) {
+  if (perspective() == Perspective::IS_CLIENT) {
+    CloseConnectionWithDetails(QUIC_INVALID_HEADERS_STREAM_DATA,
+                               "Server must not send PRIORITY frames.");
+    return;
+  }
+  OnPriorityFrame(stream_id, priority);
+}
+
+void QuicSpdySession::OnHeaderList(const QuicHeaderList& header_list) {
+  QUIC_DVLOG(1) << "Received header list for stream " << stream_id_ << ": "
+                << header_list.DebugString();
+  if (promised_stream_id_ ==
+      QuicUtils::GetInvalidStreamId(connection()->transport_version())) {
+    OnStreamHeaderList(stream_id_, fin_, frame_len_, header_list);
+  } else {
+    OnPromiseHeaderList(stream_id_, promised_stream_id_, frame_len_,
+                        header_list);
+  }
+  // Reset state for the next frame.
+  promised_stream_id_ =
+      QuicUtils::GetInvalidStreamId(connection()->transport_version());
+  stream_id_ = QuicUtils::GetInvalidStreamId(connection()->transport_version());
+  fin_ = false;
+  frame_len_ = 0;
+  uncompressed_frame_len_ = 0;
+}
+
+void QuicSpdySession::OnCompressedFrameSize(size_t frame_len) {
+  frame_len_ += frame_len;
+}
+
+void QuicSpdySession::SetHpackEncoderDebugVisitor(
+    std::unique_ptr<QuicHpackDebugVisitor> visitor) {
+  spdy_framer_.SetEncoderHeaderTableDebugVisitor(
+      std::unique_ptr<HeaderTableDebugVisitor>(new HeaderTableDebugVisitor(
+          connection()->helper()->GetClock(), std::move(visitor))));
+}
+
+void QuicSpdySession::SetHpackDecoderDebugVisitor(
+    std::unique_ptr<QuicHpackDebugVisitor> visitor) {
+  h2_deframer_.SetDecoderHeaderTableDebugVisitor(
+      QuicMakeUnique<HeaderTableDebugVisitor>(
+          connection()->helper()->GetClock(), std::move(visitor)));
+}
+
+void QuicSpdySession::UpdateHeaderEncoderTableSize(uint32_t value) {
+  spdy_framer_.UpdateHeaderEncoderTableSize(value);
+}
+
+void QuicSpdySession::UpdateEnableServerPush(bool value) {
+  set_server_push_enabled(value);
+}
+
+void QuicSpdySession::set_max_uncompressed_header_bytes(
+    size_t set_max_uncompressed_header_bytes) {
+  spdy_framer_visitor_->set_max_uncompressed_header_bytes(
+      set_max_uncompressed_header_bytes);
+}
+
+void QuicSpdySession::CloseConnectionWithDetails(QuicErrorCode error,
+                                                 const QuicString& details) {
+  connection()->CloseConnection(
+      error, details, ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+}
+
+}  // namespace quic
diff --git a/quic/core/http/quic_spdy_session.h b/quic/core/http/quic_spdy_session.h
new file mode 100644
index 0000000..00f241e
--- /dev/null
+++ b/quic/core/http/quic_spdy_session.h
@@ -0,0 +1,283 @@
+// Copyright (c) 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_HTTP_QUIC_SPDY_SESSION_H_
+#define QUICHE_QUIC_CORE_HTTP_QUIC_SPDY_SESSION_H_
+
+#include <cstddef>
+#include <memory>
+
+#include "base/macros.h"
+#include "net/third_party/quiche/src/quic/core/http/quic_header_list.h"
+#include "net/third_party/quiche/src/quic/core/http/quic_headers_stream.h"
+#include "net/third_party/quiche/src/quic/core/http/quic_spdy_stream.h"
+#include "net/third_party/quiche/src/quic/core/qpack/qpack_decoder.h"
+#include "net/third_party/quiche/src/quic/core/qpack/qpack_decoder_stream_sender.h"
+#include "net/third_party/quiche/src/quic/core/qpack/qpack_encoder.h"
+#include "net/third_party/quiche/src/quic/core/qpack/qpack_encoder_stream_sender.h"
+#include "net/third_party/quiche/src/quic/core/quic_session.h"
+#include "net/third_party/quiche/src/quic/core/quic_versions.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_export.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_string.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_string_piece.h"
+#include "net/third_party/quiche/src/spdy/core/http2_frame_decoder_adapter.h"
+
+namespace quic {
+
+namespace test {
+class QuicSpdySessionPeer;
+}  // namespace test
+
+// QuicHpackDebugVisitor gathers data used for understanding HPACK HoL
+// dynamics.  Specifically, it is to help predict the compression
+// penalty of avoiding HoL by chagning how the dynamic table is used.
+// In chromium, the concrete instance populates an UMA
+// histogram with the data.
+class QUIC_EXPORT_PRIVATE QuicHpackDebugVisitor {
+ public:
+  QuicHpackDebugVisitor();
+  QuicHpackDebugVisitor(const QuicHpackDebugVisitor&) = delete;
+  QuicHpackDebugVisitor& operator=(const QuicHpackDebugVisitor&) = delete;
+
+  virtual ~QuicHpackDebugVisitor();
+
+  // For each HPACK indexed representation processed, |elapsed| is
+  // the time since the corresponding entry was added to the dynamic
+  // table.
+  virtual void OnUseEntry(QuicTime::Delta elapsed) = 0;
+};
+
+// A QUIC session with a headers stream.
+class QUIC_EXPORT_PRIVATE QuicSpdySession
+    : public QuicSession,
+      public QpackEncoder::DecoderStreamErrorDelegate,
+      public QpackEncoderStreamSender::Delegate,
+      public QpackDecoder::EncoderStreamErrorDelegate,
+      public QpackDecoderStreamSender::Delegate {
+ public:
+  // Does not take ownership of |connection| or |visitor|.
+  QuicSpdySession(QuicConnection* connection,
+                  QuicSession::Visitor* visitor,
+                  const QuicConfig& config,
+                  const ParsedQuicVersionVector& supported_versions);
+  QuicSpdySession(const QuicSpdySession&) = delete;
+  QuicSpdySession& operator=(const QuicSpdySession&) = delete;
+
+  ~QuicSpdySession() override;
+
+  void Initialize() override;
+
+  // QpackEncoder::DecoderStreamErrorDelegate implementation.
+  void OnDecoderStreamError(QuicStringPiece error_message) override;
+
+  // QpackEncoderStreamSender::Delegate implemenation.
+  void WriteEncoderStreamData(QuicStringPiece data) override;
+
+  // QpackDecoder::EncoderStreamErrorDelegate implementation.
+  void OnEncoderStreamError(QuicStringPiece error_message) override;
+
+  // QpackDecoderStreamSender::Delegate implementation.
+  void WriteDecoderStreamData(QuicStringPiece data) override;
+
+  // Called by |headers_stream_| when headers with a priority have been
+  // received for a stream.  This method will only be called for server streams.
+  virtual void OnStreamHeadersPriority(QuicStreamId stream_id,
+                                       spdy::SpdyPriority priority);
+
+  // Called by |headers_stream_| when headers have been completely received
+  // for a stream.  |fin| will be true if the fin flag was set in the headers
+  // frame.
+  virtual void OnStreamHeaderList(QuicStreamId stream_id,
+                                  bool fin,
+                                  size_t frame_len,
+                                  const QuicHeaderList& header_list);
+
+  // Called by |headers_stream_| when push promise headers have been
+  // completely received.  |fin| will be true if the fin flag was set
+  // in the headers.
+  virtual void OnPromiseHeaderList(QuicStreamId stream_id,
+                                   QuicStreamId promised_stream_id,
+                                   size_t frame_len,
+                                   const QuicHeaderList& header_list);
+
+  // Called by |headers_stream_| when a PRIORITY frame has been received for a
+  // stream. This method will only be called for server streams.
+  virtual void OnPriorityFrame(QuicStreamId stream_id,
+                               spdy::SpdyPriority priority);
+
+  // Sends contents of |iov| to h2_deframer_, returns number of bytes processed.
+  size_t ProcessHeaderData(const struct iovec& iov);
+
+  // Writes |headers| for the stream |id| to the dedicated headers stream.
+  // If |fin| is true, then no more data will be sent for the stream |id|.
+  // If provided, |ack_notifier_delegate| will be registered to be notified when
+  // we have seen ACKs for all packets resulting from this call.
+  virtual size_t WriteHeadersOnHeadersStream(
+      QuicStreamId id,
+      spdy::SpdyHeaderBlock headers,
+      bool fin,
+      spdy::SpdyPriority priority,
+      QuicReferenceCountedPointer<QuicAckListenerInterface> ack_listener);
+
+  // Writes a PRIORITY frame the to peer. Returns the size in bytes of the
+  // resulting PRIORITY frame for QUIC_VERSION_43 and above. Otherwise, does
+  // nothing and returns 0.
+  size_t WritePriority(QuicStreamId id,
+                       QuicStreamId parent_stream_id,
+                       int weight,
+                       bool exclusive);
+
+  // Write |headers| for |promised_stream_id| on |original_stream_id| in a
+  // PUSH_PROMISE frame to peer.
+  // Return the size, in bytes, of the resulting PUSH_PROMISE frame.
+  virtual size_t WritePushPromise(QuicStreamId original_stream_id,
+                                  QuicStreamId promised_stream_id,
+                                  spdy::SpdyHeaderBlock headers);
+
+  // Sends SETTINGS_MAX_HEADER_LIST_SIZE SETTINGS frame.
+  size_t SendMaxHeaderListSize(size_t value);
+
+  QpackEncoder* qpack_encoder();
+  QpackDecoder* qpack_decoder();
+  QuicHeadersStream* headers_stream() { return headers_stream_.get(); }
+
+  bool server_push_enabled() const { return server_push_enabled_; }
+
+  // Called by |QuicHeadersStream::UpdateEnableServerPush()| with
+  // value from SETTINGS_ENABLE_PUSH.
+  void set_server_push_enabled(bool enable) { server_push_enabled_ = enable; }
+
+  // Return true if this session wants to release headers stream's buffer
+  // aggressively.
+  virtual bool ShouldReleaseHeadersStreamSequencerBuffer();
+
+  void CloseConnectionWithDetails(QuicErrorCode error,
+                                  const QuicString& details);
+
+  void set_max_inbound_header_list_size(size_t max_inbound_header_list_size) {
+    max_inbound_header_list_size_ = max_inbound_header_list_size;
+  }
+
+ protected:
+  // Override CreateIncomingStream(), CreateOutgoingBidirectionalStream() and
+  // CreateOutgoingUnidirectionalStream() with QuicSpdyStream return type to
+  // make sure that all data streams are QuicSpdyStreams.
+  QuicSpdyStream* CreateIncomingStream(QuicStreamId id) override = 0;
+  QuicSpdyStream* CreateIncomingStream(PendingStream pending) override = 0;
+  virtual QuicSpdyStream* CreateOutgoingBidirectionalStream() = 0;
+  virtual QuicSpdyStream* CreateOutgoingUnidirectionalStream() = 0;
+
+  QuicSpdyStream* GetSpdyDataStream(const QuicStreamId stream_id);
+
+  // If an incoming stream can be created, return true.
+  virtual bool ShouldCreateIncomingStream(QuicStreamId id) = 0;
+
+  // If an outgoing bidirectional/unidirectional stream can be created, return
+  // true.
+  virtual bool ShouldCreateOutgoingBidirectionalStream() = 0;
+  virtual bool ShouldCreateOutgoingUnidirectionalStream() = 0;
+
+  // Returns true if there are open HTTP requests.
+  bool ShouldKeepConnectionAlive() const override;
+
+  // Overridden to buffer incoming streams for version 99.
+  bool ShouldBufferIncomingStream(QuicStreamId id) const override;
+
+  size_t WriteHeadersOnHeadersStreamImpl(
+      QuicStreamId id,
+      spdy::SpdyHeaderBlock headers,
+      bool fin,
+      QuicStreamId parent_stream_id,
+      int weight,
+      bool exclusive,
+      QuicReferenceCountedPointer<QuicAckListenerInterface> ack_listener);
+
+  void OnCryptoHandshakeEvent(CryptoHandshakeEvent event) override;
+
+  bool supports_push_promise() { return supports_push_promise_; }
+
+  // Optional, enables instrumentation related to go/quic-hpack.
+  void SetHpackEncoderDebugVisitor(
+      std::unique_ptr<QuicHpackDebugVisitor> visitor);
+  void SetHpackDecoderDebugVisitor(
+      std::unique_ptr<QuicHpackDebugVisitor> visitor);
+
+  // Sets the maximum size of the header compression table spdy_framer_ is
+  // willing to use to encode header blocks.
+  void UpdateHeaderEncoderTableSize(uint32_t value);
+
+  // Called when SETTINGS_ENABLE_PUSH is received, only supported on
+  // server side.
+  void UpdateEnableServerPush(bool value);
+
+  bool IsConnected() { return connection()->connected(); }
+
+  // Sets how much encoded data the hpack decoder of h2_deframer_ is willing to
+  // buffer.
+  void set_max_decode_buffer_size_bytes(size_t max_decode_buffer_size_bytes) {
+    h2_deframer_.GetHpackDecoder()->set_max_decode_buffer_size_bytes(
+        max_decode_buffer_size_bytes);
+  }
+
+  void set_max_uncompressed_header_bytes(
+      size_t set_max_uncompressed_header_bytes);
+
+ private:
+  friend class test::QuicSpdySessionPeer;
+
+  class SpdyFramerVisitor;
+
+  // The following methods are called by the SimpleVisitor.
+
+  // Called when a HEADERS frame has been received.
+  void OnHeaders(spdy::SpdyStreamId stream_id,
+                 bool has_priority,
+                 spdy::SpdyPriority priority,
+                 bool fin);
+
+  // Called when a PUSH_PROMISE frame has been received.
+  void OnPushPromise(spdy::SpdyStreamId stream_id,
+                     spdy::SpdyStreamId promised_stream_id,
+                     bool end);
+
+  // Called when a PRIORITY frame has been received.
+  void OnPriority(spdy::SpdyStreamId stream_id, spdy::SpdyPriority priority);
+
+  // Called when the complete list of headers is available.
+  void OnHeaderList(const QuicHeaderList& header_list);
+
+  // Called when the size of the compressed frame payload is available.
+  void OnCompressedFrameSize(size_t frame_len);
+
+  std::unique_ptr<QpackEncoder> qpack_encoder_;
+  std::unique_ptr<QpackDecoder> qpack_decoder_;
+
+  // TODO(123528590): Remove this member.
+  std::unique_ptr<QuicHeadersStream> headers_stream_;
+
+  // The maximum size of a header block that will be accepted from the peer,
+  // defined per spec as key + value + overhead per field (uncompressed).
+  size_t max_inbound_header_list_size_;
+
+  // Set during handshake. If true, resources in x-associated-content and link
+  // headers will be pushed.
+  bool server_push_enabled_;
+
+  // Data about the stream whose headers are being processed.
+  QuicStreamId stream_id_;
+  QuicStreamId promised_stream_id_;
+  bool fin_;
+  size_t frame_len_;
+  size_t uncompressed_frame_len_;
+
+  bool supports_push_promise_;
+
+  spdy::SpdyFramer spdy_framer_;
+  http2::Http2DecoderAdapter h2_deframer_;
+  std::unique_ptr<SpdyFramerVisitor> spdy_framer_visitor_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_HTTP_QUIC_SPDY_SESSION_H_
diff --git a/quic/core/http/quic_spdy_session_test.cc b/quic/core/http/quic_spdy_session_test.cc
new file mode 100644
index 0000000..1c53472
--- /dev/null
+++ b/quic/core/http/quic_spdy_session_test.cc
@@ -0,0 +1,1803 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/third_party/quiche/src/quic/core/http/quic_spdy_session.h"
+
+#include <cstdint>
+#include <set>
+#include <utility>
+
+#include "net/third_party/quiche/src/quic/core/crypto/crypto_protocol.h"
+#include "net/third_party/quiche/src/quic/core/crypto/null_encrypter.h"
+#include "net/third_party/quiche/src/quic/core/quic_crypto_stream.h"
+#include "net/third_party/quiche/src/quic/core/quic_data_writer.h"
+#include "net/third_party/quiche/src/quic/core/quic_packets.h"
+#include "net/third_party/quiche/src/quic/core/quic_stream.h"
+#include "net/third_party/quiche/src/quic/core/quic_utils.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_expect_bug.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_flags.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_map_util.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_ptr_util.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_str_cat.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_string.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_string_piece.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_test.h"
+#include "net/third_party/quiche/src/quic/test_tools/quic_config_peer.h"
+#include "net/third_party/quiche/src/quic/test_tools/quic_connection_peer.h"
+#include "net/third_party/quiche/src/quic/test_tools/quic_flow_controller_peer.h"
+#include "net/third_party/quiche/src/quic/test_tools/quic_session_peer.h"
+#include "net/third_party/quiche/src/quic/test_tools/quic_spdy_session_peer.h"
+#include "net/third_party/quiche/src/quic/test_tools/quic_stream_peer.h"
+#include "net/third_party/quiche/src/quic/test_tools/quic_stream_send_buffer_peer.h"
+#include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h"
+#include "net/third_party/quiche/src/spdy/core/spdy_framer.h"
+
+using spdy::kV3HighestPriority;
+using spdy::Spdy3PriorityToHttp2Weight;
+using spdy::SpdyFramer;
+using spdy::SpdyHeaderBlock;
+using spdy::SpdyPriority;
+using spdy::SpdyPriorityIR;
+using spdy::SpdySerializedFrame;
+using testing::_;
+using testing::AtLeast;
+using testing::InSequence;
+using testing::Invoke;
+using testing::Return;
+using testing::StrictMock;
+
+namespace quic {
+namespace test {
+namespace {
+
+class TestCryptoStream : public QuicCryptoStream, public QuicCryptoHandshaker {
+ public:
+  explicit TestCryptoStream(QuicSession* session)
+      : QuicCryptoStream(session),
+        QuicCryptoHandshaker(this, session),
+        encryption_established_(false),
+        handshake_confirmed_(false),
+        params_(new QuicCryptoNegotiatedParameters) {}
+
+  void OnHandshakeMessage(const CryptoHandshakeMessage& /*message*/) override {
+    encryption_established_ = true;
+    handshake_confirmed_ = true;
+    CryptoHandshakeMessage msg;
+    QuicString error_details;
+    session()->config()->SetInitialStreamFlowControlWindowToSend(
+        kInitialStreamFlowControlWindowForTest);
+    session()->config()->SetInitialSessionFlowControlWindowToSend(
+        kInitialSessionFlowControlWindowForTest);
+    session()->config()->ToHandshakeMessage(&msg);
+    const QuicErrorCode error =
+        session()->config()->ProcessPeerHello(msg, CLIENT, &error_details);
+    EXPECT_EQ(QUIC_NO_ERROR, error);
+    session()->OnConfigNegotiated();
+    session()->connection()->SetDefaultEncryptionLevel(
+        ENCRYPTION_FORWARD_SECURE);
+    session()->OnCryptoHandshakeEvent(QuicSession::HANDSHAKE_CONFIRMED);
+  }
+
+  // QuicCryptoStream implementation
+  bool encryption_established() const override {
+    return encryption_established_;
+  }
+  bool handshake_confirmed() const override { return handshake_confirmed_; }
+  const QuicCryptoNegotiatedParameters& crypto_negotiated_params()
+      const override {
+    return *params_;
+  }
+  CryptoMessageParser* crypto_message_parser() override {
+    return QuicCryptoHandshaker::crypto_message_parser();
+  }
+
+  MOCK_METHOD0(OnCanWrite, void());
+
+  bool HasPendingCryptoRetransmission() override { return false; }
+
+  MOCK_CONST_METHOD0(HasPendingRetransmission, bool());
+
+ private:
+  using QuicCryptoStream::session;
+
+  bool encryption_established_;
+  bool handshake_confirmed_;
+  QuicReferenceCountedPointer<QuicCryptoNegotiatedParameters> params_;
+};
+
+class TestHeadersStream : public QuicHeadersStream {
+ public:
+  explicit TestHeadersStream(QuicSpdySession* session)
+      : QuicHeadersStream(session) {}
+
+  MOCK_METHOD0(OnCanWrite, void());
+};
+
+class TestStream : public QuicSpdyStream {
+ public:
+  TestStream(QuicStreamId id, QuicSpdySession* session, StreamType type)
+      : QuicSpdyStream(id, session, type) {}
+
+  TestStream(PendingStream pending, QuicSpdySession* session, StreamType type)
+      : QuicSpdyStream(std::move(pending), session, type) {}
+
+  using QuicStream::CloseWriteSide;
+
+  void OnBodyAvailable() override {}
+
+  MOCK_METHOD0(OnCanWrite, void());
+  MOCK_METHOD3(RetransmitStreamData,
+               bool(QuicStreamOffset, QuicByteCount, bool));
+
+  MOCK_CONST_METHOD0(HasPendingRetransmission, bool());
+};
+
+class TestSession : public QuicSpdySession {
+ public:
+  explicit TestSession(QuicConnection* connection)
+      : QuicSpdySession(connection,
+                        nullptr,
+                        DefaultQuicConfig(),
+                        CurrentSupportedVersions()),
+        crypto_stream_(this),
+        writev_consumes_all_data_(false) {
+    Initialize();
+    this->connection()->SetEncrypter(
+        ENCRYPTION_FORWARD_SECURE,
+        QuicMakeUnique<NullEncrypter>(connection->perspective()));
+  }
+
+  ~TestSession() override { delete connection(); }
+
+  TestCryptoStream* GetMutableCryptoStream() override {
+    return &crypto_stream_;
+  }
+
+  const TestCryptoStream* GetCryptoStream() const override {
+    return &crypto_stream_;
+  }
+
+  TestStream* CreateOutgoingBidirectionalStream() override {
+    TestStream* stream = new TestStream(GetNextOutgoingBidirectionalStreamId(),
+                                        this, BIDIRECTIONAL);
+    ActivateStream(QuicWrapUnique(stream));
+    return stream;
+  }
+
+  TestStream* CreateOutgoingUnidirectionalStream() override {
+    TestStream* stream = new TestStream(GetNextOutgoingUnidirectionalStreamId(),
+                                        this, WRITE_UNIDIRECTIONAL);
+    ActivateStream(QuicWrapUnique(stream));
+    return stream;
+  }
+
+  TestStream* CreateIncomingStream(QuicStreamId id) override {
+    // Enforce the limit on the number of open streams.
+    if (GetNumOpenIncomingStreams() + 1 >
+            max_open_incoming_bidirectional_streams() &&
+        connection()->transport_version() != QUIC_VERSION_99) {
+      connection()->CloseConnection(
+          QUIC_TOO_MANY_OPEN_STREAMS, "Too many streams!",
+          ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+      return nullptr;
+    } else {
+      TestStream* stream = new TestStream(
+          id, this,
+          DetermineStreamType(id, connection()->transport_version(),
+                              perspective(), /*is_incoming=*/true,
+                              BIDIRECTIONAL));
+      ActivateStream(QuicWrapUnique(stream));
+      return stream;
+    }
+  }
+
+  TestStream* CreateIncomingStream(PendingStream pending) override {
+    QuicStreamId id = pending.id();
+    TestStream* stream =
+        new TestStream(std::move(pending), this,
+                       DetermineStreamType(
+                           id, connection()->transport_version(), perspective(),
+                           /*is_incoming=*/true, BIDIRECTIONAL));
+    ActivateStream(QuicWrapUnique(stream));
+    return stream;
+  }
+
+  bool ShouldCreateIncomingStream(QuicStreamId /*id*/) override { return true; }
+
+  bool ShouldCreateOutgoingBidirectionalStream() override { return true; }
+  bool ShouldCreateOutgoingUnidirectionalStream() override { return true; }
+
+  bool IsClosedStream(QuicStreamId id) {
+    return QuicSession::IsClosedStream(id);
+  }
+
+  QuicStream* GetOrCreateDynamicStream(QuicStreamId stream_id) {
+    return QuicSpdySession::GetOrCreateDynamicStream(stream_id);
+  }
+
+  QuicConsumedData WritevData(QuicStream* stream,
+                              QuicStreamId id,
+                              size_t write_length,
+                              QuicStreamOffset offset,
+                              StreamSendingState state) override {
+    bool fin = state != NO_FIN;
+    QuicConsumedData consumed(write_length, fin);
+    if (!writev_consumes_all_data_) {
+      consumed =
+          QuicSession::WritevData(stream, id, write_length, offset, state);
+    }
+    if (fin && consumed.fin_consumed) {
+      stream->set_fin_sent(true);
+    }
+    QuicSessionPeer::GetWriteBlockedStreams(this)->UpdateBytesForStream(
+        id, consumed.bytes_consumed);
+    return consumed;
+  }
+
+  void set_writev_consumes_all_data(bool val) {
+    writev_consumes_all_data_ = val;
+  }
+
+  QuicConsumedData SendStreamData(QuicStream* stream) {
+    struct iovec iov;
+    if (stream->id() !=
+            QuicUtils::GetCryptoStreamId(connection()->transport_version()) &&
+        connection()->encryption_level() != ENCRYPTION_FORWARD_SECURE) {
+      this->connection()->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+    }
+    MakeIOVector("not empty", &iov);
+    QuicStreamPeer::SendBuffer(stream).SaveStreamData(&iov, 1, 0, 9);
+    QuicConsumedData consumed = WritevData(stream, stream->id(), 9, 0, FIN);
+    QuicStreamPeer::SendBuffer(stream).OnStreamDataConsumed(
+        consumed.bytes_consumed);
+    return consumed;
+  }
+
+  bool ClearControlFrame(const QuicFrame& frame) {
+    DeleteFrame(&const_cast<QuicFrame&>(frame));
+    return true;
+  }
+
+  QuicConsumedData SendLargeFakeData(QuicStream* stream, int bytes) {
+    DCHECK(writev_consumes_all_data_);
+    return WritevData(stream, stream->id(), bytes, 0, FIN);
+  }
+
+  using QuicSession::closed_streams;
+  using QuicSession::zombie_streams;
+  using QuicSpdySession::ShouldBufferIncomingStream;
+
+ private:
+  StrictMock<TestCryptoStream> crypto_stream_;
+
+  bool writev_consumes_all_data_;
+};
+
+class QuicSpdySessionTestBase : public QuicTestWithParam<ParsedQuicVersion> {
+ public:
+  bool ClearMaxStreamIdControlFrame(const QuicFrame& frame) {
+    if (frame.type == MAX_STREAM_ID_FRAME) {
+      DeleteFrame(&const_cast<QuicFrame&>(frame));
+      return true;
+    }
+    return false;
+  }
+
+ protected:
+  explicit QuicSpdySessionTestBase(Perspective perspective)
+      : connection_(
+            new StrictMock<MockQuicConnection>(&helper_,
+                                               &alarm_factory_,
+                                               perspective,
+                                               SupportedVersions(GetParam()))),
+        session_(connection_) {
+    session_.config()->SetInitialStreamFlowControlWindowToSend(
+        kInitialStreamFlowControlWindowForTest);
+    session_.config()->SetInitialSessionFlowControlWindowToSend(
+        kInitialSessionFlowControlWindowForTest);
+    headers_[":host"] = "www.google.com";
+    headers_[":path"] = "/index.hml";
+    headers_[":scheme"] = "http";
+    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 ";
+    connection_->AdvanceTime(QuicTime::Delta::FromSeconds(1));
+    TestCryptoStream* crypto_stream = session_.GetMutableCryptoStream();
+    EXPECT_CALL(*crypto_stream, HasPendingRetransmission())
+        .Times(testing::AnyNumber());
+  }
+
+  void CheckClosedStreams() {
+    for (QuicStreamId i =
+             QuicUtils::GetCryptoStreamId(connection_->transport_version());
+         i < 100; i++) {
+      if (!QuicContainsKey(closed_streams_, i)) {
+        EXPECT_FALSE(session_.IsClosedStream(i)) << " stream id: " << i;
+      } else {
+        EXPECT_TRUE(session_.IsClosedStream(i)) << " stream id: " << i;
+      }
+    }
+  }
+
+  void CloseStream(QuicStreamId id) {
+    if (!IsVersion99()) {
+      EXPECT_CALL(*connection_, SendControlFrame(_))
+          .WillOnce(Invoke(&session_, &TestSession::ClearControlFrame));
+    } else {
+      // V99 has two frames, RST_STREAM and STOP_SENDING
+      EXPECT_CALL(*connection_, SendControlFrame(_))
+          .Times(2)
+          .WillRepeatedly(Invoke(&session_, &TestSession::ClearControlFrame));
+    }
+    EXPECT_CALL(*connection_, OnStreamReset(id, _));
+    session_.CloseStream(id);
+    closed_streams_.insert(id);
+  }
+
+  QuicTransportVersion transport_version() const {
+    return connection_->transport_version();
+  }
+
+  bool IsVersion99() const { return transport_version() == QUIC_VERSION_99; }
+
+  QuicStreamId GetNthClientInitiatedBidirectionalId(int n) {
+    return GetNthClientInitiatedBidirectionalStreamId(transport_version(), n);
+  }
+
+  QuicStreamId GetNthServerInitiatedBidirectionalId(int n) {
+    return GetNthServerInitiatedBidirectionalStreamId(
+        connection_->transport_version(), n);
+  }
+
+  QuicStreamId IdDelta() {
+    return QuicUtils::StreamIdDelta(connection_->transport_version());
+  }
+
+  MockQuicConnectionHelper helper_;
+  MockAlarmFactory alarm_factory_;
+  StrictMock<MockQuicConnection>* connection_;
+  TestSession session_;
+  std::set<QuicStreamId> closed_streams_;
+  SpdyHeaderBlock headers_;
+};
+
+class QuicSpdySessionTestServer : public QuicSpdySessionTestBase {
+ protected:
+  QuicSpdySessionTestServer()
+      : QuicSpdySessionTestBase(Perspective::IS_SERVER) {}
+};
+
+INSTANTIATE_TEST_SUITE_P(Tests,
+                         QuicSpdySessionTestServer,
+                         ::testing::ValuesIn(AllSupportedVersions()));
+
+TEST_P(QuicSpdySessionTestServer, ShouldBufferIncomingStreamUnidirectional) {
+  if (!IsVersion99()) {
+    return;
+  }
+  EXPECT_TRUE(session_.ShouldBufferIncomingStream(
+      QuicUtils::GetFirstUnidirectionalStreamId(
+          connection_->transport_version(), Perspective::IS_CLIENT)));
+}
+
+TEST_P(QuicSpdySessionTestServer, ShouldBufferIncomingStreamBidirectional) {
+  if (!IsVersion99()) {
+    return;
+  }
+  EXPECT_FALSE(session_.ShouldBufferIncomingStream(
+      QuicUtils::GetFirstBidirectionalStreamId(connection_->transport_version(),
+                                               Perspective::IS_CLIENT)));
+}
+
+TEST_P(QuicSpdySessionTestServer, PeerAddress) {
+  EXPECT_EQ(QuicSocketAddress(QuicIpAddress::Loopback4(), kTestPort),
+            session_.peer_address());
+}
+
+TEST_P(QuicSpdySessionTestServer, SelfAddress) {
+  EXPECT_TRUE(session_.self_address().IsInitialized());
+}
+
+TEST_P(QuicSpdySessionTestServer, IsCryptoHandshakeConfirmed) {
+  EXPECT_FALSE(session_.IsCryptoHandshakeConfirmed());
+  CryptoHandshakeMessage message;
+  session_.GetMutableCryptoStream()->OnHandshakeMessage(message);
+  EXPECT_TRUE(session_.IsCryptoHandshakeConfirmed());
+}
+
+TEST_P(QuicSpdySessionTestServer, IsClosedStreamDefault) {
+  // Ensure that no streams are initially closed.
+  for (QuicStreamId i =
+           QuicUtils::GetCryptoStreamId(connection_->transport_version());
+       i < 100; i++) {
+    EXPECT_FALSE(session_.IsClosedStream(i)) << "stream id: " << i;
+  }
+}
+
+TEST_P(QuicSpdySessionTestServer, AvailableStreams) {
+  ASSERT_TRUE(session_.GetOrCreateDynamicStream(
+                  GetNthClientInitiatedBidirectionalId(2)) != nullptr);
+  // Both client initiated streams with smaller stream IDs are available.
+  EXPECT_TRUE(QuicSessionPeer::IsStreamAvailable(
+      &session_, GetNthClientInitiatedBidirectionalId(0)));
+  EXPECT_TRUE(QuicSessionPeer::IsStreamAvailable(
+      &session_, GetNthClientInitiatedBidirectionalId(1)));
+  ASSERT_TRUE(session_.GetOrCreateDynamicStream(
+                  GetNthClientInitiatedBidirectionalId(1)) != nullptr);
+  ASSERT_TRUE(session_.GetOrCreateDynamicStream(
+                  GetNthClientInitiatedBidirectionalId(0)) != nullptr);
+}
+
+TEST_P(QuicSpdySessionTestServer, IsClosedStreamLocallyCreated) {
+  TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
+  EXPECT_EQ(GetNthServerInitiatedBidirectionalId(0), stream2->id());
+  QuicSpdyStream* stream4 = session_.CreateOutgoingBidirectionalStream();
+  EXPECT_EQ(GetNthServerInitiatedBidirectionalId(1), stream4->id());
+
+  CheckClosedStreams();
+  CloseStream(GetNthServerInitiatedBidirectionalId(0));
+  CheckClosedStreams();
+  CloseStream(GetNthServerInitiatedBidirectionalId(1));
+  CheckClosedStreams();
+}
+
+TEST_P(QuicSpdySessionTestServer, IsClosedStreamPeerCreated) {
+  QuicStreamId stream_id1 = GetNthClientInitiatedBidirectionalId(0);
+  QuicStreamId stream_id2 = GetNthClientInitiatedBidirectionalId(1);
+  session_.GetOrCreateDynamicStream(stream_id1);
+  session_.GetOrCreateDynamicStream(stream_id2);
+
+  CheckClosedStreams();
+  CloseStream(stream_id1);
+  CheckClosedStreams();
+  CloseStream(stream_id2);
+  // Create a stream, and make another available.
+  QuicStream* stream3 = session_.GetOrCreateDynamicStream(stream_id2 + 4);
+  CheckClosedStreams();
+  // Close one, but make sure the other is still not closed
+  CloseStream(stream3->id());
+  CheckClosedStreams();
+}
+
+TEST_P(QuicSpdySessionTestServer, MaximumAvailableOpenedStreams) {
+  if (IsVersion99()) {
+    // For IETF QUIC, we should be able to obtain the max allowed
+    // stream ID, the next ID should fail. Since the actual limit
+    // is not the number of open streams, we allocate the max and the max+2.
+    // Get the max allowed stream ID, this should succeed.
+    EXPECT_NE(nullptr,
+              session_.GetOrCreateDynamicStream(
+                  QuicSessionPeer::v99_streamid_manager(
+                      dynamic_cast<QuicSession*>(&session_))
+                      ->actual_max_allowed_incoming_bidirectional_stream_id()));
+    EXPECT_NE(
+        nullptr,
+        session_.GetOrCreateDynamicStream(
+            QuicSessionPeer::v99_streamid_manager(
+                dynamic_cast<QuicSession*>(&session_))
+                ->actual_max_allowed_incoming_unidirectional_stream_id()));
+    EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(1);
+    // Get the (max allowed stream ID)++, this should fail.
+    EXPECT_EQ(nullptr,
+              session_.GetOrCreateDynamicStream(
+                  QuicSessionPeer::v99_streamid_manager(
+                      dynamic_cast<QuicSession*>(&session_))
+                      ->actual_max_allowed_incoming_bidirectional_stream_id() +
+                  IdDelta()));
+    EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(1);
+    EXPECT_EQ(nullptr,
+              session_.GetOrCreateDynamicStream(
+                  QuicSessionPeer::v99_streamid_manager(
+                      dynamic_cast<QuicSession*>(&session_))
+                      ->actual_max_allowed_incoming_unidirectional_stream_id() +
+                  IdDelta()));
+  } else {
+    QuicStreamId stream_id = GetNthClientInitiatedBidirectionalId(0);
+    session_.GetOrCreateDynamicStream(stream_id);
+    EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(0);
+    EXPECT_NE(
+        nullptr,
+        session_.GetOrCreateDynamicStream(
+            stream_id +
+            IdDelta() *
+                (session_.max_open_incoming_bidirectional_streams() - 1)));
+  }
+}
+
+TEST_P(QuicSpdySessionTestServer, TooManyAvailableStreams) {
+  QuicStreamId stream_id1 = GetNthClientInitiatedBidirectionalId(0);
+  QuicStreamId stream_id2;
+  EXPECT_NE(nullptr, session_.GetOrCreateDynamicStream(stream_id1));
+  // A stream ID which is too large to create.
+  stream_id2 = GetNthClientInitiatedBidirectionalId(
+      2 * session_.MaxAvailableBidirectionalStreams() + 4);
+  if (IsVersion99()) {
+    EXPECT_CALL(*connection_, CloseConnection(QUIC_INVALID_STREAM_ID, _, _));
+  } else {
+    EXPECT_CALL(*connection_,
+                CloseConnection(QUIC_TOO_MANY_AVAILABLE_STREAMS, _, _));
+  }
+  EXPECT_EQ(nullptr, session_.GetOrCreateDynamicStream(stream_id2));
+}
+
+TEST_P(QuicSpdySessionTestServer, ManyAvailableStreams) {
+  // When max_open_streams_ is 200, should be able to create 200 streams
+  // out-of-order, that is, creating the one with the largest stream ID first.
+  QuicSessionPeer::SetMaxOpenIncomingStreams(&session_, 200);
+  QuicStreamId stream_id = GetNthClientInitiatedBidirectionalId(0);
+  // Create one stream.
+  session_.GetOrCreateDynamicStream(stream_id);
+  EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(0);
+  // Stream count is 200, GetNth... starts counting at 0, so the 200'th stream
+  // is 199.
+  EXPECT_NE(nullptr, session_.GetOrCreateDynamicStream(
+                         GetNthClientInitiatedBidirectionalId(199)));
+}
+
+TEST_P(QuicSpdySessionTestServer,
+       DebugDFatalIfMarkingClosedStreamWriteBlocked) {
+  // EXPECT_QUIC_BUG tests are expensive so only run one instance of them.
+  if (GetParam() != AllSupportedVersions()[0]) {
+    return;
+  }
+
+  TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
+  QuicStreamId closed_stream_id = stream2->id();
+  // Close the stream.
+  EXPECT_CALL(*connection_, SendControlFrame(_));
+  EXPECT_CALL(*connection_, OnStreamReset(closed_stream_id, _));
+  stream2->Reset(QUIC_BAD_APPLICATION_PAYLOAD);
+  QuicString msg =
+      QuicStrCat("Marking unknown stream ", closed_stream_id, " blocked.");
+  EXPECT_QUIC_BUG(session_.MarkConnectionLevelWriteBlocked(closed_stream_id),
+                  msg);
+}
+
+TEST_P(QuicSpdySessionTestServer, OnCanWrite) {
+  session_.set_writev_consumes_all_data(true);
+  TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
+  TestStream* stream4 = session_.CreateOutgoingBidirectionalStream();
+  TestStream* stream6 = session_.CreateOutgoingBidirectionalStream();
+
+  session_.MarkConnectionLevelWriteBlocked(stream2->id());
+  session_.MarkConnectionLevelWriteBlocked(stream6->id());
+  session_.MarkConnectionLevelWriteBlocked(stream4->id());
+
+  InSequence s;
+
+  // Reregister, to test the loop limit.
+  EXPECT_CALL(*stream2, OnCanWrite()).WillOnce(Invoke([this, stream2]() {
+    session_.SendStreamData(stream2);
+    session_.MarkConnectionLevelWriteBlocked(stream2->id());
+  }));
+  // 2 will get called a second time as it didn't finish its block
+  EXPECT_CALL(*stream2, OnCanWrite()).WillOnce(Invoke([this, stream2]() {
+    session_.SendStreamData(stream2);
+  }));
+  EXPECT_CALL(*stream6, OnCanWrite()).WillOnce(Invoke([this, stream6]() {
+    session_.SendStreamData(stream6);
+  }));
+  // 4 will not get called, as we exceeded the loop limit.
+  session_.OnCanWrite();
+  EXPECT_TRUE(session_.WillingAndAbleToWrite());
+}
+
+TEST_P(QuicSpdySessionTestServer, TestBatchedWrites) {
+  session_.set_writev_consumes_all_data(true);
+  TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
+  TestStream* stream4 = session_.CreateOutgoingBidirectionalStream();
+  TestStream* stream6 = session_.CreateOutgoingBidirectionalStream();
+
+  session_.set_writev_consumes_all_data(true);
+  session_.MarkConnectionLevelWriteBlocked(stream2->id());
+  session_.MarkConnectionLevelWriteBlocked(stream4->id());
+
+  // With two sessions blocked, we should get two write calls.  They should both
+  // go to the first stream as it will only write 6k and mark itself blocked
+  // again.
+  InSequence s;
+  EXPECT_CALL(*stream2, OnCanWrite()).WillOnce(Invoke([this, stream2]() {
+    session_.SendLargeFakeData(stream2, 6000);
+    session_.MarkConnectionLevelWriteBlocked(stream2->id());
+  }));
+  EXPECT_CALL(*stream2, OnCanWrite()).WillOnce(Invoke([this, stream2]() {
+    session_.SendLargeFakeData(stream2, 6000);
+    session_.MarkConnectionLevelWriteBlocked(stream2->id());
+  }));
+  session_.OnCanWrite();
+
+  // We should get one more call for stream2, at which point it has used its
+  // write quota and we move over to stream 4.
+  EXPECT_CALL(*stream2, OnCanWrite()).WillOnce(Invoke([this, stream2]() {
+    session_.SendLargeFakeData(stream2, 6000);
+    session_.MarkConnectionLevelWriteBlocked(stream2->id());
+  }));
+  EXPECT_CALL(*stream4, OnCanWrite()).WillOnce(Invoke([this, stream4]() {
+    session_.SendLargeFakeData(stream4, 6000);
+    session_.MarkConnectionLevelWriteBlocked(stream4->id());
+  }));
+  session_.OnCanWrite();
+
+  // Now let stream 4 do the 2nd of its 3 writes, but add a block for a high
+  // priority stream 6.  4 should be preempted.  6 will write but *not* block so
+  // will cede back to 4.
+  stream6->SetPriority(kV3HighestPriority);
+  EXPECT_CALL(*stream4, OnCanWrite())
+      .WillOnce(Invoke([this, stream4, stream6]() {
+        session_.SendLargeFakeData(stream4, 6000);
+        session_.MarkConnectionLevelWriteBlocked(stream4->id());
+        session_.MarkConnectionLevelWriteBlocked(stream6->id());
+      }));
+  EXPECT_CALL(*stream6, OnCanWrite())
+      .WillOnce(Invoke([this, stream4, stream6]() {
+        session_.SendStreamData(stream6);
+        session_.SendLargeFakeData(stream4, 6000);
+      }));
+  session_.OnCanWrite();
+
+  // Stream4 alread did 6k worth of writes, so after doing another 12k it should
+  // cede and 2 should resume.
+  EXPECT_CALL(*stream4, OnCanWrite()).WillOnce(Invoke([this, stream4]() {
+    session_.SendLargeFakeData(stream4, 12000);
+    session_.MarkConnectionLevelWriteBlocked(stream4->id());
+  }));
+  EXPECT_CALL(*stream2, OnCanWrite()).WillOnce(Invoke([this, stream2]() {
+    session_.SendLargeFakeData(stream2, 6000);
+    session_.MarkConnectionLevelWriteBlocked(stream2->id());
+  }));
+  session_.OnCanWrite();
+}
+
+TEST_P(QuicSpdySessionTestServer, OnCanWriteBundlesStreams) {
+  if (IsVersion99()) {
+    EXPECT_CALL(*connection_, SendControlFrame(_))
+        .WillRepeatedly(Invoke(
+            this, &QuicSpdySessionTestServer::ClearMaxStreamIdControlFrame));
+  }
+  // Encryption needs to be established before data can be sent.
+  CryptoHandshakeMessage msg;
+  MockPacketWriter* writer = static_cast<MockPacketWriter*>(
+      QuicConnectionPeer::GetWriter(session_.connection()));
+  EXPECT_CALL(*writer, WritePacket(_, _, _, _, _))
+      .WillOnce(Return(WriteResult(WRITE_STATUS_OK, 0)));
+  session_.GetMutableCryptoStream()->OnHandshakeMessage(msg);
+
+  // Drive congestion control manually.
+  MockSendAlgorithm* send_algorithm = new StrictMock<MockSendAlgorithm>;
+  QuicConnectionPeer::SetSendAlgorithm(session_.connection(), send_algorithm);
+
+  TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
+  TestStream* stream4 = session_.CreateOutgoingBidirectionalStream();
+  TestStream* stream6 = session_.CreateOutgoingBidirectionalStream();
+
+  session_.MarkConnectionLevelWriteBlocked(stream2->id());
+  session_.MarkConnectionLevelWriteBlocked(stream6->id());
+  session_.MarkConnectionLevelWriteBlocked(stream4->id());
+
+  EXPECT_CALL(*send_algorithm, CanSend(_)).WillRepeatedly(Return(true));
+  EXPECT_CALL(*send_algorithm, GetCongestionWindow())
+      .WillRepeatedly(Return(kMaxPacketSize * 10));
+  EXPECT_CALL(*send_algorithm, InRecovery()).WillRepeatedly(Return(false));
+  EXPECT_CALL(*stream2, OnCanWrite()).WillOnce(Invoke([this, stream2]() {
+    session_.SendStreamData(stream2);
+  }));
+  EXPECT_CALL(*stream4, OnCanWrite()).WillOnce(Invoke([this, stream4]() {
+    session_.SendStreamData(stream4);
+  }));
+  EXPECT_CALL(*stream6, OnCanWrite()).WillOnce(Invoke([this, stream6]() {
+    session_.SendStreamData(stream6);
+  }));
+
+  // Expect that we only send one packet, the writes from different streams
+  // should be bundled together.
+  EXPECT_CALL(*writer, WritePacket(_, _, _, _, _))
+      .WillOnce(Return(WriteResult(WRITE_STATUS_OK, 0)));
+  EXPECT_CALL(*send_algorithm, OnPacketSent(_, _, _, _, _));
+  EXPECT_CALL(*send_algorithm, OnApplicationLimited(_));
+  session_.OnCanWrite();
+  EXPECT_FALSE(session_.WillingAndAbleToWrite());
+}
+
+TEST_P(QuicSpdySessionTestServer, OnCanWriteCongestionControlBlocks) {
+  session_.set_writev_consumes_all_data(true);
+  InSequence s;
+
+  // Drive congestion control manually.
+  MockSendAlgorithm* send_algorithm = new StrictMock<MockSendAlgorithm>;
+  QuicConnectionPeer::SetSendAlgorithm(session_.connection(), send_algorithm);
+
+  TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
+  TestStream* stream4 = session_.CreateOutgoingBidirectionalStream();
+  TestStream* stream6 = session_.CreateOutgoingBidirectionalStream();
+
+  session_.MarkConnectionLevelWriteBlocked(stream2->id());
+  session_.MarkConnectionLevelWriteBlocked(stream6->id());
+  session_.MarkConnectionLevelWriteBlocked(stream4->id());
+
+  EXPECT_CALL(*send_algorithm, CanSend(_)).WillOnce(Return(true));
+  EXPECT_CALL(*stream2, OnCanWrite()).WillOnce(Invoke([this, stream2]() {
+    session_.SendStreamData(stream2);
+  }));
+  EXPECT_CALL(*send_algorithm, CanSend(_)).WillOnce(Return(true));
+  EXPECT_CALL(*stream6, OnCanWrite()).WillOnce(Invoke([this, stream6]() {
+    session_.SendStreamData(stream6);
+  }));
+  EXPECT_CALL(*send_algorithm, CanSend(_)).WillOnce(Return(false));
+  // stream4->OnCanWrite is not called.
+
+  session_.OnCanWrite();
+  EXPECT_TRUE(session_.WillingAndAbleToWrite());
+
+  // Still congestion-control blocked.
+  EXPECT_CALL(*send_algorithm, CanSend(_)).WillOnce(Return(false));
+  session_.OnCanWrite();
+  EXPECT_TRUE(session_.WillingAndAbleToWrite());
+
+  // stream4->OnCanWrite is called once the connection stops being
+  // congestion-control blocked.
+  EXPECT_CALL(*send_algorithm, CanSend(_)).WillOnce(Return(true));
+  EXPECT_CALL(*stream4, OnCanWrite()).WillOnce(Invoke([this, stream4]() {
+    session_.SendStreamData(stream4);
+  }));
+  EXPECT_CALL(*send_algorithm, OnApplicationLimited(_));
+  session_.OnCanWrite();
+  EXPECT_FALSE(session_.WillingAndAbleToWrite());
+}
+
+TEST_P(QuicSpdySessionTestServer, OnCanWriteWriterBlocks) {
+  // Drive congestion control manually in order to ensure that
+  // application-limited signaling is handled correctly.
+  MockSendAlgorithm* send_algorithm = new StrictMock<MockSendAlgorithm>;
+  QuicConnectionPeer::SetSendAlgorithm(session_.connection(), send_algorithm);
+  EXPECT_CALL(*send_algorithm, CanSend(_)).WillRepeatedly(Return(true));
+
+  // Drive packet writer manually.
+  MockPacketWriter* writer = static_cast<MockPacketWriter*>(
+      QuicConnectionPeer::GetWriter(session_.connection()));
+  EXPECT_CALL(*writer, IsWriteBlocked()).WillRepeatedly(Return(true));
+  EXPECT_CALL(*writer, WritePacket(_, _, _, _, _)).Times(0);
+
+  TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
+
+  session_.MarkConnectionLevelWriteBlocked(stream2->id());
+
+  EXPECT_CALL(*stream2, OnCanWrite()).Times(0);
+  EXPECT_CALL(*send_algorithm, OnApplicationLimited(_)).Times(0);
+
+  session_.OnCanWrite();
+  EXPECT_TRUE(session_.WillingAndAbleToWrite());
+}
+
+TEST_P(QuicSpdySessionTestServer, BufferedHandshake) {
+  session_.set_writev_consumes_all_data(true);
+  EXPECT_FALSE(session_.HasPendingHandshake());  // Default value.
+
+  // Test that blocking other streams does not change our status.
+  TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
+  session_.MarkConnectionLevelWriteBlocked(stream2->id());
+  EXPECT_FALSE(session_.HasPendingHandshake());
+
+  TestStream* stream3 = session_.CreateOutgoingBidirectionalStream();
+  session_.MarkConnectionLevelWriteBlocked(stream3->id());
+  EXPECT_FALSE(session_.HasPendingHandshake());
+
+  // Blocking (due to buffering of) the Crypto stream is detected.
+  session_.MarkConnectionLevelWriteBlocked(
+      QuicUtils::GetCryptoStreamId(connection_->transport_version()));
+  EXPECT_TRUE(session_.HasPendingHandshake());
+
+  TestStream* stream4 = session_.CreateOutgoingBidirectionalStream();
+  session_.MarkConnectionLevelWriteBlocked(stream4->id());
+  EXPECT_TRUE(session_.HasPendingHandshake());
+
+  InSequence s;
+  // Force most streams to re-register, which is common scenario when we block
+  // the Crypto stream, and only the crypto stream can "really" write.
+
+  // Due to prioritization, we *should* be asked to write the crypto stream
+  // first.
+  // Don't re-register the crypto stream (which signals complete writing).
+  TestCryptoStream* crypto_stream = session_.GetMutableCryptoStream();
+  EXPECT_CALL(*crypto_stream, OnCanWrite());
+
+  EXPECT_CALL(*stream2, OnCanWrite()).WillOnce(Invoke([this, stream2]() {
+    session_.SendStreamData(stream2);
+  }));
+  EXPECT_CALL(*stream3, OnCanWrite()).WillOnce(Invoke([this, stream3]() {
+    session_.SendStreamData(stream3);
+  }));
+  EXPECT_CALL(*stream4, OnCanWrite()).WillOnce(Invoke([this, stream4]() {
+    session_.SendStreamData(stream4);
+    session_.MarkConnectionLevelWriteBlocked(stream4->id());
+  }));
+
+  session_.OnCanWrite();
+  EXPECT_TRUE(session_.WillingAndAbleToWrite());
+  EXPECT_FALSE(session_.HasPendingHandshake());  // Crypto stream wrote.
+}
+
+TEST_P(QuicSpdySessionTestServer, OnCanWriteWithClosedStream) {
+  session_.set_writev_consumes_all_data(true);
+  TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
+  TestStream* stream4 = session_.CreateOutgoingBidirectionalStream();
+  TestStream* stream6 = session_.CreateOutgoingBidirectionalStream();
+
+  session_.MarkConnectionLevelWriteBlocked(stream2->id());
+  session_.MarkConnectionLevelWriteBlocked(stream6->id());
+  session_.MarkConnectionLevelWriteBlocked(stream4->id());
+  CloseStream(stream6->id());
+
+  InSequence s;
+  EXPECT_CALL(*connection_, SendControlFrame(_))
+      .WillRepeatedly(Invoke(&session_, &TestSession::ClearControlFrame));
+  EXPECT_CALL(*stream2, OnCanWrite()).WillOnce(Invoke([this, stream2]() {
+    session_.SendStreamData(stream2);
+  }));
+  EXPECT_CALL(*stream4, OnCanWrite()).WillOnce(Invoke([this, stream4]() {
+    session_.SendStreamData(stream4);
+  }));
+  session_.OnCanWrite();
+  EXPECT_FALSE(session_.WillingAndAbleToWrite());
+}
+
+TEST_P(QuicSpdySessionTestServer,
+       OnCanWriteLimitsNumWritesIfFlowControlBlocked) {
+  // Drive congestion control manually in order to ensure that
+  // application-limited signaling is handled correctly.
+  MockSendAlgorithm* send_algorithm = new StrictMock<MockSendAlgorithm>;
+  QuicConnectionPeer::SetSendAlgorithm(session_.connection(), send_algorithm);
+  EXPECT_CALL(*send_algorithm, CanSend(_)).WillRepeatedly(Return(true));
+
+  // Ensure connection level flow control blockage.
+  QuicFlowControllerPeer::SetSendWindowOffset(session_.flow_controller(), 0);
+  EXPECT_TRUE(session_.flow_controller()->IsBlocked());
+  EXPECT_TRUE(session_.IsConnectionFlowControlBlocked());
+  EXPECT_FALSE(session_.IsStreamFlowControlBlocked());
+
+  // Mark the crypto and headers streams as write blocked, we expect them to be
+  // allowed to write later.
+  session_.MarkConnectionLevelWriteBlocked(
+      QuicUtils::GetCryptoStreamId(connection_->transport_version()));
+
+  // Create a data stream, and although it is write blocked we never expect it
+  // to be allowed to write as we are connection level flow control blocked.
+  TestStream* stream = session_.CreateOutgoingBidirectionalStream();
+  session_.MarkConnectionLevelWriteBlocked(stream->id());
+  EXPECT_CALL(*stream, OnCanWrite()).Times(0);
+
+  // The crypto and headers streams should be called even though we are
+  // connection flow control blocked.
+  TestCryptoStream* crypto_stream = session_.GetMutableCryptoStream();
+  EXPECT_CALL(*crypto_stream, OnCanWrite());
+  QuicSpdySessionPeer::SetHeadersStream(&session_, nullptr);
+  TestHeadersStream* headers_stream = new TestHeadersStream(&session_);
+  QuicSpdySessionPeer::SetHeadersStream(&session_, headers_stream);
+  session_.MarkConnectionLevelWriteBlocked(
+      QuicUtils::GetHeadersStreamId(connection_->transport_version()));
+  EXPECT_CALL(*headers_stream, OnCanWrite());
+
+  // After the crypto and header streams perform a write, the connection will be
+  // blocked by the flow control, hence it should become application-limited.
+  EXPECT_CALL(*send_algorithm, OnApplicationLimited(_));
+
+  session_.OnCanWrite();
+  EXPECT_FALSE(session_.WillingAndAbleToWrite());
+}
+
+TEST_P(QuicSpdySessionTestServer, SendGoAway) {
+  if (IsVersion99()) {
+    // GoAway frames are not in version 99
+    return;
+  }
+  MockPacketWriter* writer = static_cast<MockPacketWriter*>(
+      QuicConnectionPeer::GetWriter(session_.connection()));
+  EXPECT_CALL(*writer, WritePacket(_, _, _, _, _))
+      .WillOnce(Return(WriteResult(WRITE_STATUS_OK, 0)));
+
+  EXPECT_CALL(*connection_, SendControlFrame(_))
+      .WillOnce(
+          Invoke(connection_, &MockQuicConnection::ReallySendControlFrame));
+  session_.SendGoAway(QUIC_PEER_GOING_AWAY, "Going Away.");
+  EXPECT_TRUE(session_.goaway_sent());
+
+  const QuicStreamId kTestStreamId = 5u;
+  EXPECT_CALL(*connection_, SendControlFrame(_)).Times(0);
+  EXPECT_CALL(*connection_,
+              OnStreamReset(kTestStreamId, QUIC_STREAM_PEER_GOING_AWAY))
+      .Times(0);
+  EXPECT_TRUE(session_.GetOrCreateDynamicStream(kTestStreamId));
+}
+
+TEST_P(QuicSpdySessionTestServer, DoNotSendGoAwayTwice) {
+  if (IsVersion99()) {
+    // TODO(b/118808809): Enable this test for version 99 when GOAWAY is
+    // supported.
+    return;
+  }
+  EXPECT_CALL(*connection_, SendControlFrame(_))
+      .WillOnce(Invoke(&session_, &TestSession::ClearControlFrame));
+  session_.SendGoAway(QUIC_PEER_GOING_AWAY, "Going Away.");
+  EXPECT_TRUE(session_.goaway_sent());
+  session_.SendGoAway(QUIC_PEER_GOING_AWAY, "Going Away.");
+}
+
+TEST_P(QuicSpdySessionTestServer, InvalidGoAway) {
+  if (IsVersion99()) {
+    // TODO(b/118808809): Enable this test for version 99 when GOAWAY is
+    // supported.
+    return;
+  }
+  QuicGoAwayFrame go_away(kInvalidControlFrameId, QUIC_PEER_GOING_AWAY,
+                          session_.next_outgoing_bidirectional_stream_id(), "");
+  session_.OnGoAway(go_away);
+}
+
+// Test that server session will send a connectivity probe in response to a
+// connectivity probe on the same path.
+TEST_P(QuicSpdySessionTestServer, ServerReplyToConnecitivityProbe) {
+  QuicSocketAddress old_peer_address =
+      QuicSocketAddress(QuicIpAddress::Loopback4(), kTestPort);
+  EXPECT_EQ(old_peer_address, session_.peer_address());
+
+  QuicSocketAddress new_peer_address =
+      QuicSocketAddress(QuicIpAddress::Loopback4(), kTestPort + 1);
+
+  EXPECT_CALL(*connection_,
+              SendConnectivityProbingResponsePacket(new_peer_address));
+  if (IsVersion99()) {
+    // Need to explicitly do this to emulate the reception of a PathChallenge,
+    // which stores its payload for use in generating the response.
+    connection_->OnPathChallengeFrame(
+        QuicPathChallengeFrame(0, {{0, 1, 2, 3, 4, 5, 6, 7}}));
+  }
+  session_.OnConnectivityProbeReceived(session_.self_address(),
+                                       new_peer_address);
+  EXPECT_EQ(old_peer_address, session_.peer_address());
+}
+
+TEST_P(QuicSpdySessionTestServer, IncreasedTimeoutAfterCryptoHandshake) {
+  EXPECT_EQ(kInitialIdleTimeoutSecs + 3,
+            QuicConnectionPeer::GetNetworkTimeout(connection_).ToSeconds());
+  CryptoHandshakeMessage msg;
+  session_.GetMutableCryptoStream()->OnHandshakeMessage(msg);
+  EXPECT_EQ(kMaximumIdleTimeoutSecs + 3,
+            QuicConnectionPeer::GetNetworkTimeout(connection_).ToSeconds());
+}
+
+TEST_P(QuicSpdySessionTestServer, RstStreamBeforeHeadersDecompressed) {
+  // Send two bytes of payload.
+  QuicStreamFrame data1(GetNthClientInitiatedBidirectionalId(0), false, 0,
+                        QuicStringPiece("HT"));
+  session_.OnStreamFrame(data1);
+  EXPECT_EQ(1u, session_.GetNumOpenIncomingStreams());
+
+  EXPECT_CALL(*connection_, SendControlFrame(_));
+  if (!IsVersion99()) {
+    // For version99, OnStreamReset gets called because of the STOP_SENDING,
+    // below. EXPECT the call there.
+    EXPECT_CALL(*connection_,
+                OnStreamReset(GetNthClientInitiatedBidirectionalId(0), _));
+  }
+  QuicRstStreamFrame rst1(kInvalidControlFrameId,
+                          GetNthClientInitiatedBidirectionalId(0),
+                          QUIC_ERROR_PROCESSING_STREAM, 0);
+  session_.OnRstStream(rst1);
+
+  // Create and inject a STOP_SENDING frame. In GOOGLE QUIC, receiving a
+  // RST_STREAM frame causes a two-way close. For IETF QUIC, RST_STREAM causes a
+  // one-way close.
+  if (IsVersion99()) {
+    // Only needed for version 99/IETF QUIC.
+    QuicStopSendingFrame stop_sending(
+        kInvalidControlFrameId, GetNthClientInitiatedBidirectionalId(0),
+        static_cast<QuicApplicationErrorCode>(QUIC_ERROR_PROCESSING_STREAM));
+    // Expect the RESET_STREAM that is generated in response to receiving a
+    // STOP_SENDING.
+    EXPECT_CALL(*connection_,
+                OnStreamReset(GetNthClientInitiatedBidirectionalId(0),
+                              QUIC_ERROR_PROCESSING_STREAM));
+    session_.OnStopSendingFrame(stop_sending);
+  }
+
+  EXPECT_EQ(0u, session_.GetNumOpenIncomingStreams());
+  // Connection should remain alive.
+  EXPECT_TRUE(connection_->connected());
+}
+
+TEST_P(QuicSpdySessionTestServer, OnStreamFrameFinStaticStreamId) {
+  // Send two bytes of payload.
+  QuicStreamFrame data1(
+      QuicUtils::GetCryptoStreamId(connection_->transport_version()), true, 0,
+      QuicStringPiece("HT"));
+  EXPECT_CALL(*connection_,
+              CloseConnection(
+                  QUIC_INVALID_STREAM_ID, "Attempt to close a static stream",
+                  ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET));
+  session_.OnStreamFrame(data1);
+}
+
+TEST_P(QuicSpdySessionTestServer, OnRstStreamStaticStreamId) {
+  // Send two bytes of payload.
+  QuicRstStreamFrame rst1(
+      kInvalidControlFrameId,
+      QuicUtils::GetCryptoStreamId(connection_->transport_version()),
+      QUIC_ERROR_PROCESSING_STREAM, 0);
+  EXPECT_CALL(*connection_,
+              CloseConnection(
+                  QUIC_INVALID_STREAM_ID, "Attempt to reset a static stream",
+                  ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET));
+  session_.OnRstStream(rst1);
+}
+
+TEST_P(QuicSpdySessionTestServer, OnStreamFrameInvalidStreamId) {
+  // Send two bytes of payload.
+  QuicStreamFrame data1(
+      QuicUtils::GetInvalidStreamId(connection_->transport_version()), true, 0,
+      QuicStringPiece("HT"));
+  EXPECT_CALL(*connection_,
+              CloseConnection(
+                  QUIC_INVALID_STREAM_ID, "Recevied data for an invalid stream",
+                  ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET));
+  session_.OnStreamFrame(data1);
+}
+
+TEST_P(QuicSpdySessionTestServer, OnRstStreamInvalidStreamId) {
+  // Send two bytes of payload.
+  QuicRstStreamFrame rst1(
+      kInvalidControlFrameId,
+      QuicUtils::GetInvalidStreamId(connection_->transport_version()),
+      QUIC_ERROR_PROCESSING_STREAM, 0);
+  EXPECT_CALL(*connection_,
+              CloseConnection(
+                  QUIC_INVALID_STREAM_ID, "Recevied data for an invalid stream",
+                  ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET));
+  session_.OnRstStream(rst1);
+}
+
+TEST_P(QuicSpdySessionTestServer, HandshakeUnblocksFlowControlBlockedStream) {
+  // Test that if a stream is flow control blocked, then on receipt of the SHLO
+  // containing a suitable send window offset, the stream becomes unblocked.
+
+  // Ensure that Writev consumes all the data it is given (simulate no socket
+  // blocking).
+  session_.set_writev_consumes_all_data(true);
+
+  // Create a stream, and send enough data to make it flow control blocked.
+  TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
+  QuicString body(kMinimumFlowControlSendWindow, '.');
+  EXPECT_FALSE(stream2->flow_controller()->IsBlocked());
+  EXPECT_FALSE(session_.IsConnectionFlowControlBlocked());
+  EXPECT_FALSE(session_.IsStreamFlowControlBlocked());
+  EXPECT_CALL(*connection_, SendControlFrame(_)).Times(AtLeast(1));
+  stream2->WriteOrBufferBody(body, false);
+  EXPECT_TRUE(stream2->flow_controller()->IsBlocked());
+  EXPECT_TRUE(session_.IsConnectionFlowControlBlocked());
+  EXPECT_TRUE(session_.IsStreamFlowControlBlocked());
+
+  // Now complete the crypto handshake, resulting in an increased flow control
+  // send window.
+  CryptoHandshakeMessage msg;
+  session_.GetMutableCryptoStream()->OnHandshakeMessage(msg);
+  EXPECT_TRUE(QuicSessionPeer::IsStreamWriteBlocked(&session_, stream2->id()));
+  // Stream is now unblocked.
+  EXPECT_FALSE(stream2->flow_controller()->IsBlocked());
+  EXPECT_FALSE(session_.IsConnectionFlowControlBlocked());
+  EXPECT_FALSE(session_.IsStreamFlowControlBlocked());
+}
+
+TEST_P(QuicSpdySessionTestServer,
+       HandshakeUnblocksFlowControlBlockedCryptoStream) {
+  if (GetParam().transport_version >= QUIC_VERSION_47) {
+    // QUIC version 47 onwards uses CRYPTO frames for the handshake, so this
+    // test doesn't make sense for those versions.
+    return;
+  }
+  // Test that if the crypto stream is flow control blocked, then if the SHLO
+  // contains a larger send window offset, the stream becomes unblocked.
+  session_.set_writev_consumes_all_data(true);
+  TestCryptoStream* crypto_stream = session_.GetMutableCryptoStream();
+  EXPECT_FALSE(crypto_stream->flow_controller()->IsBlocked());
+  EXPECT_FALSE(session_.IsConnectionFlowControlBlocked());
+  EXPECT_FALSE(session_.IsStreamFlowControlBlocked());
+  QuicHeadersStream* headers_stream =
+      QuicSpdySessionPeer::GetHeadersStream(&session_);
+  EXPECT_FALSE(headers_stream->flow_controller()->IsBlocked());
+  EXPECT_FALSE(session_.IsConnectionFlowControlBlocked());
+  EXPECT_FALSE(session_.IsStreamFlowControlBlocked());
+  if (IsVersion99()) {
+    EXPECT_CALL(*connection_, SendControlFrame(_))
+        .WillOnce(Invoke(&session_, &TestSession::ClearControlFrame));
+  } else {
+    EXPECT_CALL(*connection_, SendControlFrame(_))
+        .WillOnce(Invoke(&session_, &TestSession::ClearControlFrame));
+  }
+  for (QuicStreamId i = 0;
+       !crypto_stream->flow_controller()->IsBlocked() && i < 1000u; i++) {
+    EXPECT_FALSE(session_.IsConnectionFlowControlBlocked());
+    EXPECT_FALSE(session_.IsStreamFlowControlBlocked());
+    QuicStreamOffset offset = crypto_stream->stream_bytes_written();
+    QuicConfig config;
+    CryptoHandshakeMessage crypto_message;
+    config.ToHandshakeMessage(&crypto_message);
+    crypto_stream->SendHandshakeMessage(crypto_message);
+    char buf[1000];
+    QuicDataWriter writer(1000, buf, NETWORK_BYTE_ORDER);
+    crypto_stream->WriteStreamData(offset, crypto_message.size(), &writer);
+  }
+  EXPECT_TRUE(crypto_stream->flow_controller()->IsBlocked());
+  EXPECT_FALSE(headers_stream->flow_controller()->IsBlocked());
+  EXPECT_FALSE(session_.IsConnectionFlowControlBlocked());
+  EXPECT_TRUE(session_.IsStreamFlowControlBlocked());
+  EXPECT_FALSE(session_.HasDataToWrite());
+  EXPECT_TRUE(crypto_stream->HasBufferedData());
+
+  // Now complete the crypto handshake, resulting in an increased flow control
+  // send window.
+  CryptoHandshakeMessage msg;
+  session_.GetMutableCryptoStream()->OnHandshakeMessage(msg);
+  EXPECT_TRUE(QuicSessionPeer::IsStreamWriteBlocked(
+      &session_,
+      QuicUtils::GetCryptoStreamId(connection_->transport_version())));
+  // Stream is now unblocked and will no longer have buffered data.
+  EXPECT_FALSE(crypto_stream->flow_controller()->IsBlocked());
+  EXPECT_FALSE(session_.IsConnectionFlowControlBlocked());
+  EXPECT_FALSE(session_.IsStreamFlowControlBlocked());
+}
+
+#if !defined(OS_IOS)
+// This test is failing flakily for iOS bots.
+// http://crbug.com/425050
+// NOTE: It's not possible to use the standard MAYBE_ convention to disable
+// this test on iOS because when this test gets instantiated it ends up with
+// various names that are dependent on the parameters passed.
+TEST_P(QuicSpdySessionTestServer,
+       HandshakeUnblocksFlowControlBlockedHeadersStream) {
+  // Test that if the header stream is flow control blocked, then if the SHLO
+  // contains a larger send window offset, the stream becomes unblocked.
+  session_.set_writev_consumes_all_data(true);
+  TestCryptoStream* crypto_stream = session_.GetMutableCryptoStream();
+  EXPECT_FALSE(crypto_stream->flow_controller()->IsBlocked());
+  EXPECT_FALSE(session_.IsConnectionFlowControlBlocked());
+  EXPECT_FALSE(session_.IsStreamFlowControlBlocked());
+  QuicHeadersStream* headers_stream =
+      QuicSpdySessionPeer::GetHeadersStream(&session_);
+  EXPECT_FALSE(headers_stream->flow_controller()->IsBlocked());
+  EXPECT_FALSE(session_.IsConnectionFlowControlBlocked());
+  EXPECT_FALSE(session_.IsStreamFlowControlBlocked());
+  QuicStreamId stream_id = 5;
+  // Write until the header stream is flow control blocked.
+  EXPECT_CALL(*connection_, SendControlFrame(_))
+      .WillOnce(Invoke(&session_, &TestSession::ClearControlFrame));
+  SpdyHeaderBlock headers;
+  SimpleRandom random;
+  while (!headers_stream->flow_controller()->IsBlocked() && stream_id < 2000) {
+    EXPECT_FALSE(session_.IsConnectionFlowControlBlocked());
+    EXPECT_FALSE(session_.IsStreamFlowControlBlocked());
+    headers["header"] = QuicStrCat(random.RandUint64(), random.RandUint64(),
+                                   random.RandUint64());
+    session_.WriteHeadersOnHeadersStream(stream_id, headers.Clone(), true, 0,
+                                         nullptr);
+    stream_id += IdDelta();
+  }
+  // Write once more to ensure that the headers stream has buffered data. The
+  // random headers may have exactly filled the flow control window.
+  session_.WriteHeadersOnHeadersStream(stream_id, std::move(headers), true, 0,
+                                       nullptr);
+  EXPECT_TRUE(headers_stream->HasBufferedData());
+
+  EXPECT_TRUE(headers_stream->flow_controller()->IsBlocked());
+  EXPECT_FALSE(crypto_stream->flow_controller()->IsBlocked());
+  EXPECT_FALSE(session_.IsConnectionFlowControlBlocked());
+  EXPECT_TRUE(session_.IsStreamFlowControlBlocked());
+  EXPECT_FALSE(session_.HasDataToWrite());
+
+  // Now complete the crypto handshake, resulting in an increased flow control
+  // send window.
+  CryptoHandshakeMessage msg;
+  session_.GetMutableCryptoStream()->OnHandshakeMessage(msg);
+
+  // Stream is now unblocked and will no longer have buffered data.
+  EXPECT_FALSE(headers_stream->flow_controller()->IsBlocked());
+  EXPECT_FALSE(session_.IsConnectionFlowControlBlocked());
+  EXPECT_FALSE(session_.IsStreamFlowControlBlocked());
+  EXPECT_TRUE(headers_stream->HasBufferedData());
+  EXPECT_TRUE(QuicSessionPeer::IsStreamWriteBlocked(
+      &session_,
+      QuicUtils::GetHeadersStreamId(connection_->transport_version())));
+}
+#endif  // !defined(OS_IOS)
+
+TEST_P(QuicSpdySessionTestServer,
+       ConnectionFlowControlAccountingRstOutOfOrder) {
+  // Test that when we receive an out of order stream RST we correctly adjust
+  // our connection level flow control receive window.
+  // On close, the stream should mark as consumed all bytes between the highest
+  // byte consumed so far and the final byte offset from the RST frame.
+  TestStream* stream = session_.CreateOutgoingBidirectionalStream();
+
+  const QuicStreamOffset kByteOffset =
+      1 + kInitialSessionFlowControlWindowForTest / 2;
+
+  EXPECT_CALL(*connection_, SendControlFrame(_))
+      .Times(2)
+      .WillRepeatedly(Invoke(&session_, &TestSession::ClearControlFrame));
+  if (!IsVersion99()) {
+    // For version99 the call to OnStreamReset happens as a result of receiving
+    // the STOP_SENDING, so set up the EXPECT there.
+    EXPECT_CALL(*connection_, OnStreamReset(stream->id(), _));
+  }
+  QuicRstStreamFrame rst_frame(kInvalidControlFrameId, stream->id(),
+                               QUIC_STREAM_CANCELLED, kByteOffset);
+  session_.OnRstStream(rst_frame);
+  // Create and inject a STOP_SENDING frame. In GOOGLE QUIC, receiving a
+  // RST_STREAM frame causes a two-way close. For IETF QUIC, RST_STREAM causes a
+  // one-way close.
+  if (IsVersion99()) {
+    // Only needed for version 99/IETF QUIC.
+    QuicStopSendingFrame stop_sending(
+        kInvalidControlFrameId, stream->id(),
+        static_cast<QuicApplicationErrorCode>(QUIC_STREAM_CANCELLED));
+    // Expect the RESET_STREAM that is generated in response to receiving a
+    // STOP_SENDING.
+    EXPECT_CALL(*connection_,
+                OnStreamReset(stream->id(), QUIC_STREAM_CANCELLED));
+    session_.OnStopSendingFrame(stop_sending);
+  }
+
+  EXPECT_EQ(kByteOffset, session_.flow_controller()->bytes_consumed());
+}
+
+TEST_P(QuicSpdySessionTestServer,
+       ConnectionFlowControlAccountingFinAndLocalReset) {
+  // Test the situation where we receive a FIN on a stream, and before we fully
+  // consume all the data from the sequencer buffer we locally RST the stream.
+  // The bytes between highest consumed byte, and the final byte offset that we
+  // determined when the FIN arrived, should be marked as consumed at the
+  // connection level flow controller when the stream is reset.
+  TestStream* stream = session_.CreateOutgoingBidirectionalStream();
+
+  const QuicStreamOffset kByteOffset =
+      kInitialSessionFlowControlWindowForTest / 2 - 1;
+  QuicStreamFrame frame(stream->id(), true, kByteOffset, ".");
+  session_.OnStreamFrame(frame);
+  EXPECT_TRUE(connection_->connected());
+
+  EXPECT_EQ(0u, stream->flow_controller()->bytes_consumed());
+  EXPECT_EQ(kByteOffset + frame.data_length,
+            stream->flow_controller()->highest_received_byte_offset());
+
+  // Reset stream locally.
+  EXPECT_CALL(*connection_, SendControlFrame(_));
+  EXPECT_CALL(*connection_, OnStreamReset(stream->id(), _));
+  stream->Reset(QUIC_STREAM_CANCELLED);
+  EXPECT_EQ(kByteOffset + frame.data_length,
+            session_.flow_controller()->bytes_consumed());
+}
+
+TEST_P(QuicSpdySessionTestServer, ConnectionFlowControlAccountingFinAfterRst) {
+  // Test that when we RST the stream (and tear down stream state), and then
+  // receive a FIN from the peer, we correctly adjust our connection level flow
+  // control receive window.
+
+  // Connection starts with some non-zero highest received byte offset,
+  // due to other active streams.
+  const uint64_t kInitialConnectionBytesConsumed = 567;
+  const uint64_t kInitialConnectionHighestReceivedOffset = 1234;
+  EXPECT_LT(kInitialConnectionBytesConsumed,
+            kInitialConnectionHighestReceivedOffset);
+  session_.flow_controller()->UpdateHighestReceivedOffset(
+      kInitialConnectionHighestReceivedOffset);
+  session_.flow_controller()->AddBytesConsumed(kInitialConnectionBytesConsumed);
+
+  // Reset our stream: this results in the stream being closed locally.
+  TestStream* stream = session_.CreateOutgoingBidirectionalStream();
+  EXPECT_CALL(*connection_, SendControlFrame(_));
+  EXPECT_CALL(*connection_, OnStreamReset(stream->id(), _));
+  stream->Reset(QUIC_STREAM_CANCELLED);
+
+  // Now receive a response from the peer with a FIN. We should handle this by
+  // adjusting the connection level flow control receive window to take into
+  // account the total number of bytes sent by the peer.
+  const QuicStreamOffset kByteOffset = 5678;
+  QuicString body = "hello";
+  QuicStreamFrame frame(stream->id(), true, kByteOffset, QuicStringPiece(body));
+  session_.OnStreamFrame(frame);
+
+  QuicStreamOffset total_stream_bytes_sent_by_peer =
+      kByteOffset + body.length();
+  EXPECT_EQ(kInitialConnectionBytesConsumed + total_stream_bytes_sent_by_peer,
+            session_.flow_controller()->bytes_consumed());
+  EXPECT_EQ(
+      kInitialConnectionHighestReceivedOffset + total_stream_bytes_sent_by_peer,
+      session_.flow_controller()->highest_received_byte_offset());
+}
+
+TEST_P(QuicSpdySessionTestServer, ConnectionFlowControlAccountingRstAfterRst) {
+  // Test that when we RST the stream (and tear down stream state), and then
+  // receive a RST from the peer, we correctly adjust our connection level flow
+  // control receive window.
+
+  // Connection starts with some non-zero highest received byte offset,
+  // due to other active streams.
+  const uint64_t kInitialConnectionBytesConsumed = 567;
+  const uint64_t kInitialConnectionHighestReceivedOffset = 1234;
+  EXPECT_LT(kInitialConnectionBytesConsumed,
+            kInitialConnectionHighestReceivedOffset);
+  session_.flow_controller()->UpdateHighestReceivedOffset(
+      kInitialConnectionHighestReceivedOffset);
+  session_.flow_controller()->AddBytesConsumed(kInitialConnectionBytesConsumed);
+
+  // Reset our stream: this results in the stream being closed locally.
+  TestStream* stream = session_.CreateOutgoingBidirectionalStream();
+  EXPECT_CALL(*connection_, SendControlFrame(_));
+  EXPECT_CALL(*connection_, OnStreamReset(stream->id(), _));
+  stream->Reset(QUIC_STREAM_CANCELLED);
+  EXPECT_TRUE(QuicStreamPeer::read_side_closed(stream));
+
+  // Now receive a RST from the peer. We should handle this by adjusting the
+  // connection level flow control receive window to take into account the total
+  // number of bytes sent by the peer.
+  const QuicStreamOffset kByteOffset = 5678;
+  QuicRstStreamFrame rst_frame(kInvalidControlFrameId, stream->id(),
+                               QUIC_STREAM_CANCELLED, kByteOffset);
+  session_.OnRstStream(rst_frame);
+
+  EXPECT_EQ(kInitialConnectionBytesConsumed + kByteOffset,
+            session_.flow_controller()->bytes_consumed());
+  EXPECT_EQ(kInitialConnectionHighestReceivedOffset + kByteOffset,
+            session_.flow_controller()->highest_received_byte_offset());
+}
+
+TEST_P(QuicSpdySessionTestServer, InvalidStreamFlowControlWindowInHandshake) {
+  // Test that receipt of an invalid (< default) stream flow control window from
+  // the peer results in the connection being torn down.
+  const uint32_t kInvalidWindow = kMinimumFlowControlSendWindow - 1;
+  QuicConfigPeer::SetReceivedInitialStreamFlowControlWindow(session_.config(),
+                                                            kInvalidWindow);
+
+  EXPECT_CALL(*connection_,
+              CloseConnection(QUIC_FLOW_CONTROL_INVALID_WINDOW, _, _));
+  session_.OnConfigNegotiated();
+}
+
+TEST_P(QuicSpdySessionTestServer, InvalidSessionFlowControlWindowInHandshake) {
+  // Test that receipt of an invalid (< default) session flow control window
+  // from the peer results in the connection being torn down.
+  const uint32_t kInvalidWindow = kMinimumFlowControlSendWindow - 1;
+  QuicConfigPeer::SetReceivedInitialSessionFlowControlWindow(session_.config(),
+                                                             kInvalidWindow);
+
+  EXPECT_CALL(*connection_,
+              CloseConnection(QUIC_FLOW_CONTROL_INVALID_WINDOW, _, _));
+  session_.OnConfigNegotiated();
+}
+
+// Test negotiation of custom server initial flow control window.
+TEST_P(QuicSpdySessionTestServer, CustomFlowControlWindow) {
+  QuicTagVector copt;
+  copt.push_back(kIFW7);
+  QuicConfigPeer::SetReceivedConnectionOptions(session_.config(), copt);
+
+  session_.OnConfigNegotiated();
+  EXPECT_EQ(192 * 1024u, QuicFlowControllerPeer::ReceiveWindowSize(
+                             session_.flow_controller()));
+}
+
+TEST_P(QuicSpdySessionTestServer, FlowControlWithInvalidFinalOffset) {
+  // Test that if we receive a stream RST with a highest byte offset that
+  // violates flow control, that we close the connection.
+  const uint64_t kLargeOffset = kInitialSessionFlowControlWindowForTest + 1;
+  EXPECT_CALL(*connection_,
+              CloseConnection(QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA, _, _))
+      .Times(2);
+
+  // Check that stream frame + FIN results in connection close.
+  TestStream* stream = session_.CreateOutgoingBidirectionalStream();
+  EXPECT_CALL(*connection_, SendControlFrame(_));
+  EXPECT_CALL(*connection_, OnStreamReset(stream->id(), _));
+  stream->Reset(QUIC_STREAM_CANCELLED);
+  QuicStreamFrame frame(stream->id(), true, kLargeOffset, QuicStringPiece());
+  session_.OnStreamFrame(frame);
+
+  // Check that RST results in connection close.
+  QuicRstStreamFrame rst_frame(kInvalidControlFrameId, stream->id(),
+                               QUIC_STREAM_CANCELLED, kLargeOffset);
+  session_.OnRstStream(rst_frame);
+}
+
+TEST_P(QuicSpdySessionTestServer, WindowUpdateUnblocksHeadersStream) {
+  // Test that a flow control blocked headers stream gets unblocked on recipt of
+  // a WINDOW_UPDATE frame.
+
+  // Set the headers stream to be flow control blocked.
+  QuicHeadersStream* headers_stream =
+      QuicSpdySessionPeer::GetHeadersStream(&session_);
+  QuicFlowControllerPeer::SetSendWindowOffset(headers_stream->flow_controller(),
+                                              0);
+  EXPECT_TRUE(headers_stream->flow_controller()->IsBlocked());
+  EXPECT_FALSE(session_.IsConnectionFlowControlBlocked());
+  EXPECT_TRUE(session_.IsStreamFlowControlBlocked());
+
+  // Unblock the headers stream by supplying a WINDOW_UPDATE.
+  QuicWindowUpdateFrame window_update_frame(kInvalidControlFrameId,
+                                            headers_stream->id(),
+                                            2 * kMinimumFlowControlSendWindow);
+  session_.OnWindowUpdateFrame(window_update_frame);
+  EXPECT_FALSE(headers_stream->flow_controller()->IsBlocked());
+  EXPECT_FALSE(session_.IsConnectionFlowControlBlocked());
+  EXPECT_FALSE(session_.IsStreamFlowControlBlocked());
+}
+
+TEST_P(QuicSpdySessionTestServer,
+       TooManyUnfinishedStreamsCauseServerRejectStream) {
+  // If a buggy/malicious peer creates too many streams that are not ended
+  // with a FIN or RST then we send an RST to refuse streams for versions other
+  // than version 99. In version 99 the connection gets closed.
+  const QuicStreamId kMaxStreams = 5;
+  QuicSessionPeer::SetMaxOpenIncomingStreams(&session_, kMaxStreams);
+  const QuicStreamId kFirstStreamId = GetNthClientInitiatedBidirectionalId(0);
+  const QuicStreamId kFinalStreamId =
+      GetNthClientInitiatedBidirectionalId(kMaxStreams);
+  // Create kMaxStreams data streams, and close them all without receiving a
+  // FIN or a RST_STREAM from the client.
+  const QuicStreamId kNextId =
+      QuicUtils::StreamIdDelta(connection_->transport_version());
+  for (QuicStreamId i = kFirstStreamId; i < kFinalStreamId; i += kNextId) {
+    QuicStreamFrame data1(i, false, 0, QuicStringPiece("HT"));
+    session_.OnStreamFrame(data1);
+    // EXPECT_EQ(1u, session_.GetNumOpenStreams());
+    if (!IsVersion99()) {
+      EXPECT_CALL(*connection_, SendControlFrame(_))
+          .WillOnce(Invoke(&session_, &TestSession::ClearControlFrame));
+    } else {
+      // V99 has two frames, RST_STREAM and STOP_SENDING
+      EXPECT_CALL(*connection_, SendControlFrame(_))
+          .Times(2)
+          .WillRepeatedly(Invoke(&session_, &TestSession::ClearControlFrame));
+    }
+    // Close the stream only if not version 99. If we are version 99
+    // then closing the stream opens up the available stream id space,
+    // so we never bump into the limit.
+    EXPECT_CALL(*connection_, OnStreamReset(i, _));
+    session_.CloseStream(i);
+  }
+  // Try and open a stream that exceeds the limit.
+  if (!IsVersion99()) {
+    // On versions other than 99, opening such a stream results in a
+    // RST_STREAM.
+    EXPECT_CALL(*connection_, SendControlFrame(_)).Times(1);
+    EXPECT_CALL(*connection_,
+                OnStreamReset(kFinalStreamId, QUIC_REFUSED_STREAM))
+        .Times(1);
+  } else {
+    // On version 99 opening such a stream results in a connection close.
+    EXPECT_CALL(*connection_, CloseConnection(QUIC_INVALID_STREAM_ID,
+                                              "Stream id 28 above 24", _));
+  }
+  // Create one more data streams to exceed limit of open stream.
+  QuicStreamFrame data1(kFinalStreamId, false, 0, QuicStringPiece("HT"));
+  session_.OnStreamFrame(data1);
+}
+
+TEST_P(QuicSpdySessionTestServer, DrainingStreamsDoNotCountAsOpened) {
+  // Verify that a draining stream (which has received a FIN but not consumed
+  // it) does not count against the open quota (because it is closed from the
+  // protocol point of view).
+  if (IsVersion99()) {
+    // Version 99 will result in a MAX_STREAM_ID frame as streams are consumed
+    // (via the OnStreamFrame call) and then released (via
+    // StreamDraining). Eventually this node will believe that the peer is
+    // running low on available stream ids and then send a MAX_STREAM_ID frame,
+    // caught by this EXPECT_CALL.
+    EXPECT_CALL(*connection_, SendControlFrame(_)).Times(1);
+  } else {
+    EXPECT_CALL(*connection_, SendControlFrame(_)).Times(0);
+  }
+  EXPECT_CALL(*connection_, OnStreamReset(_, QUIC_REFUSED_STREAM)).Times(0);
+  const QuicStreamId kMaxStreams = 5;
+  QuicSessionPeer::SetMaxOpenIncomingStreams(&session_, kMaxStreams);
+
+  // Create kMaxStreams + 1 data streams, and mark them draining.
+  const QuicStreamId kFirstStreamId = GetNthClientInitiatedBidirectionalId(0);
+  const QuicStreamId kFinalStreamId =
+      GetNthClientInitiatedBidirectionalId(kMaxStreams + 1);
+  for (QuicStreamId i = kFirstStreamId; i < kFinalStreamId; i += IdDelta()) {
+    QuicStreamFrame data1(i, true, 0, QuicStringPiece("HT"));
+    session_.OnStreamFrame(data1);
+    EXPECT_EQ(1u, session_.GetNumOpenIncomingStreams());
+    session_.StreamDraining(i);
+    EXPECT_EQ(0u, session_.GetNumOpenIncomingStreams());
+  }
+}
+
+class QuicSpdySessionTestClient : public QuicSpdySessionTestBase {
+ protected:
+  QuicSpdySessionTestClient()
+      : QuicSpdySessionTestBase(Perspective::IS_CLIENT) {}
+};
+
+INSTANTIATE_TEST_SUITE_P(Tests,
+                         QuicSpdySessionTestClient,
+                         ::testing::ValuesIn(AllSupportedVersions()));
+
+TEST_P(QuicSpdySessionTestClient, AvailableStreamsClient) {
+  ASSERT_TRUE(session_.GetOrCreateDynamicStream(
+                  GetNthServerInitiatedBidirectionalId(2)) != nullptr);
+  // Both server initiated streams with smaller stream IDs should be available.
+  EXPECT_TRUE(QuicSessionPeer::IsStreamAvailable(
+      &session_, GetNthServerInitiatedBidirectionalId(0)));
+  EXPECT_TRUE(QuicSessionPeer::IsStreamAvailable(
+      &session_, GetNthServerInitiatedBidirectionalId(1)));
+  ASSERT_TRUE(session_.GetOrCreateDynamicStream(
+                  GetNthServerInitiatedBidirectionalId(0)) != nullptr);
+  ASSERT_TRUE(session_.GetOrCreateDynamicStream(
+                  GetNthServerInitiatedBidirectionalId(1)) != nullptr);
+  // And client initiated stream ID should be not available.
+  EXPECT_FALSE(QuicSessionPeer::IsStreamAvailable(
+      &session_, GetNthClientInitiatedBidirectionalId(0)));
+}
+
+TEST_P(QuicSpdySessionTestClient, RecordFinAfterReadSideClosed) {
+  // Verify that an incoming FIN is recorded in a stream object even if the read
+  // side has been closed.  This prevents an entry from being made in
+  // locally_closed_streams_highest_offset_ (which will never be deleted).
+  TestStream* stream = session_.CreateOutgoingBidirectionalStream();
+  QuicStreamId stream_id = stream->id();
+
+  // Close the read side manually.
+  QuicStreamPeer::CloseReadSide(stream);
+
+  // Receive a stream data frame with FIN.
+  QuicStreamFrame frame(stream_id, true, 0, QuicStringPiece());
+  session_.OnStreamFrame(frame);
+  EXPECT_TRUE(stream->fin_received());
+
+  // Reset stream locally.
+  EXPECT_CALL(*connection_, SendControlFrame(_));
+  EXPECT_CALL(*connection_, OnStreamReset(stream->id(), _));
+  stream->Reset(QUIC_STREAM_CANCELLED);
+  EXPECT_TRUE(QuicStreamPeer::read_side_closed(stream));
+
+  EXPECT_TRUE(connection_->connected());
+  EXPECT_TRUE(QuicSessionPeer::IsStreamClosed(&session_, stream_id));
+  EXPECT_FALSE(QuicSessionPeer::IsStreamCreated(&session_, stream_id));
+
+  // The stream is not waiting for the arrival of the peer's final offset as it
+  // was received with the FIN earlier.
+  EXPECT_EQ(
+      0u,
+      QuicSessionPeer::GetLocallyClosedStreamsHighestOffset(&session_).size());
+}
+
+TEST_P(QuicSpdySessionTestClient, WritePriority) {
+  QuicSpdySessionPeer::SetHeadersStream(&session_, nullptr);
+  TestHeadersStream* headers_stream = new TestHeadersStream(&session_);
+  QuicSpdySessionPeer::SetHeadersStream(&session_, headers_stream);
+
+  // Make packet writer blocked so |headers_stream| will buffer its write data.
+  MockPacketWriter* writer = static_cast<MockPacketWriter*>(
+      QuicConnectionPeer::GetWriter(session_.connection()));
+  EXPECT_CALL(*writer, IsWriteBlocked()).WillRepeatedly(Return(true));
+
+  const QuicStreamId id = 4;
+  const QuicStreamId parent_stream_id = 9;
+  const SpdyPriority priority = kV3HighestPriority;
+  const bool exclusive = true;
+  session_.WritePriority(id, parent_stream_id,
+                         Spdy3PriorityToHttp2Weight(priority), exclusive);
+
+  QuicStreamSendBuffer& send_buffer =
+      QuicStreamPeer::SendBuffer(headers_stream);
+  if (transport_version() > QUIC_VERSION_39) {
+    ASSERT_EQ(1u, send_buffer.size());
+
+    SpdyPriorityIR priority_frame(
+        id, parent_stream_id, Spdy3PriorityToHttp2Weight(priority), exclusive);
+    SpdyFramer spdy_framer(SpdyFramer::ENABLE_COMPRESSION);
+    SpdySerializedFrame frame = spdy_framer.SerializeFrame(priority_frame);
+
+    const QuicMemSlice& slice =
+        QuicStreamSendBufferPeer::CurrentWriteSlice(&send_buffer)->slice;
+    EXPECT_EQ(QuicStringPiece(frame.data(), frame.size()),
+              QuicStringPiece(slice.data(), slice.length()));
+  } else {
+    EXPECT_EQ(0u, send_buffer.size());
+  }
+}
+
+TEST_P(QuicSpdySessionTestServer, ZombieStreams) {
+  TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
+  QuicStreamPeer::SetStreamBytesWritten(3, stream2);
+  EXPECT_TRUE(stream2->IsWaitingForAcks());
+
+  EXPECT_CALL(*connection_, SendControlFrame(_));
+  EXPECT_CALL(*connection_, OnStreamReset(stream2->id(), _));
+  session_.CloseStream(stream2->id());
+  EXPECT_FALSE(QuicContainsKey(session_.zombie_streams(), stream2->id()));
+  ASSERT_EQ(1u, session_.closed_streams()->size());
+  EXPECT_EQ(stream2->id(), session_.closed_streams()->front()->id());
+  session_.OnStreamDoneWaitingForAcks(2);
+  EXPECT_FALSE(QuicContainsKey(session_.zombie_streams(), stream2->id()));
+  EXPECT_EQ(1u, session_.closed_streams()->size());
+  EXPECT_EQ(stream2->id(), session_.closed_streams()->front()->id());
+}
+
+TEST_P(QuicSpdySessionTestServer, OnStreamFrameLost) {
+  QuicConnectionPeer::SetSessionDecidesWhatToWrite(connection_);
+  InSequence s;
+
+  // Drive congestion control manually.
+  MockSendAlgorithm* send_algorithm = new StrictMock<MockSendAlgorithm>;
+  QuicConnectionPeer::SetSendAlgorithm(session_.connection(), send_algorithm);
+
+  TestCryptoStream* crypto_stream = session_.GetMutableCryptoStream();
+  TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
+  TestStream* stream4 = session_.CreateOutgoingBidirectionalStream();
+
+  QuicStreamFrame frame1(
+      QuicUtils::GetCryptoStreamId(connection_->transport_version()), false, 0,
+      1300);
+  QuicStreamFrame frame2(stream2->id(), false, 0, 9);
+  QuicStreamFrame frame3(stream4->id(), false, 0, 9);
+
+  // Lost data on cryption stream, streams 2 and 4.
+  EXPECT_CALL(*stream4, HasPendingRetransmission()).WillOnce(Return(true));
+  if (connection_->transport_version() < QUIC_VERSION_47) {
+    EXPECT_CALL(*crypto_stream, HasPendingRetransmission())
+        .WillOnce(Return(true));
+  }
+  EXPECT_CALL(*stream2, HasPendingRetransmission()).WillOnce(Return(true));
+  session_.OnFrameLost(QuicFrame(frame3));
+  if (connection_->transport_version() < QUIC_VERSION_47) {
+    session_.OnFrameLost(QuicFrame(frame1));
+  } else {
+    QuicCryptoFrame crypto_frame(ENCRYPTION_NONE, 0, 1300);
+    session_.OnFrameLost(QuicFrame(&crypto_frame));
+  }
+  session_.OnFrameLost(QuicFrame(frame2));
+  EXPECT_TRUE(session_.WillingAndAbleToWrite());
+
+  // Mark streams 2 and 4 write blocked.
+  session_.MarkConnectionLevelWriteBlocked(stream2->id());
+  session_.MarkConnectionLevelWriteBlocked(stream4->id());
+
+  // Lost data is retransmitted before new data, and retransmissions for crypto
+  // stream go first.
+  // Do not check congestion window when crypto stream has lost data.
+  EXPECT_CALL(*send_algorithm, CanSend(_)).Times(0);
+  if (connection_->transport_version() < QUIC_VERSION_47) {
+    EXPECT_CALL(*crypto_stream, OnCanWrite());
+    EXPECT_CALL(*crypto_stream, HasPendingRetransmission())
+        .WillOnce(Return(false));
+  }
+  // Check congestion window for non crypto streams.
+  EXPECT_CALL(*send_algorithm, CanSend(_)).WillOnce(Return(true));
+  EXPECT_CALL(*stream4, OnCanWrite());
+  EXPECT_CALL(*stream4, HasPendingRetransmission()).WillOnce(Return(false));
+  // Connection is blocked.
+  EXPECT_CALL(*send_algorithm, CanSend(_)).WillRepeatedly(Return(false));
+
+  session_.OnCanWrite();
+  EXPECT_TRUE(session_.WillingAndAbleToWrite());
+
+  // Unblock connection.
+  // Stream 2 retransmits lost data.
+  EXPECT_CALL(*send_algorithm, CanSend(_)).WillOnce(Return(true));
+  EXPECT_CALL(*stream2, OnCanWrite());
+  EXPECT_CALL(*stream2, HasPendingRetransmission()).WillOnce(Return(false));
+  EXPECT_CALL(*send_algorithm, CanSend(_)).WillOnce(Return(true));
+  // Stream 2 sends new data.
+  EXPECT_CALL(*stream2, OnCanWrite());
+  EXPECT_CALL(*send_algorithm, CanSend(_)).WillOnce(Return(true));
+  EXPECT_CALL(*stream4, OnCanWrite());
+  EXPECT_CALL(*send_algorithm, OnApplicationLimited(_));
+
+  session_.OnCanWrite();
+  EXPECT_FALSE(session_.WillingAndAbleToWrite());
+}
+
+TEST_P(QuicSpdySessionTestServer, DonotRetransmitDataOfClosedStreams) {
+  QuicConnectionPeer::SetSessionDecidesWhatToWrite(connection_);
+  InSequence s;
+
+  TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
+  TestStream* stream4 = session_.CreateOutgoingBidirectionalStream();
+  TestStream* stream6 = session_.CreateOutgoingBidirectionalStream();
+
+  QuicStreamFrame frame1(stream2->id(), false, 0, 9);
+  QuicStreamFrame frame2(stream4->id(), false, 0, 9);
+  QuicStreamFrame frame3(stream6->id(), false, 0, 9);
+
+  EXPECT_CALL(*stream6, HasPendingRetransmission()).WillOnce(Return(true));
+  EXPECT_CALL(*stream4, HasPendingRetransmission()).WillOnce(Return(true));
+  EXPECT_CALL(*stream2, HasPendingRetransmission()).WillOnce(Return(true));
+  session_.OnFrameLost(QuicFrame(frame3));
+  session_.OnFrameLost(QuicFrame(frame2));
+  session_.OnFrameLost(QuicFrame(frame1));
+
+  session_.MarkConnectionLevelWriteBlocked(stream2->id());
+  session_.MarkConnectionLevelWriteBlocked(stream4->id());
+  session_.MarkConnectionLevelWriteBlocked(stream6->id());
+
+  // Reset stream 4 locally.
+  EXPECT_CALL(*connection_, SendControlFrame(_));
+  EXPECT_CALL(*connection_, OnStreamReset(stream4->id(), _));
+  stream4->Reset(QUIC_STREAM_CANCELLED);
+
+  // Verify stream 4 is removed from streams with lost data list.
+  EXPECT_CALL(*stream6, OnCanWrite());
+  EXPECT_CALL(*stream6, HasPendingRetransmission()).WillOnce(Return(false));
+  EXPECT_CALL(*stream2, OnCanWrite());
+  EXPECT_CALL(*stream2, HasPendingRetransmission()).WillOnce(Return(false));
+  EXPECT_CALL(*connection_, SendControlFrame(_))
+      .WillRepeatedly(Invoke(&session_, &TestSession::ClearControlFrame));
+  EXPECT_CALL(*stream2, OnCanWrite());
+  EXPECT_CALL(*stream6, OnCanWrite());
+  session_.OnCanWrite();
+}
+
+TEST_P(QuicSpdySessionTestServer, RetransmitFrames) {
+  QuicConnectionPeer::SetSessionDecidesWhatToWrite(connection_);
+  MockSendAlgorithm* send_algorithm = new StrictMock<MockSendAlgorithm>;
+  QuicConnectionPeer::SetSendAlgorithm(session_.connection(), send_algorithm);
+  InSequence s;
+
+  TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
+  TestStream* stream4 = session_.CreateOutgoingBidirectionalStream();
+  TestStream* stream6 = session_.CreateOutgoingBidirectionalStream();
+  EXPECT_CALL(*connection_, SendControlFrame(_))
+      .WillOnce(Invoke(&session_, &TestSession::ClearControlFrame));
+  session_.SendWindowUpdate(stream2->id(), 9);
+
+  QuicStreamFrame frame1(stream2->id(), false, 0, 9);
+  QuicStreamFrame frame2(stream4->id(), false, 0, 9);
+  QuicStreamFrame frame3(stream6->id(), false, 0, 9);
+  QuicWindowUpdateFrame window_update(1, stream2->id(), 9);
+  QuicFrames frames;
+  frames.push_back(QuicFrame(frame1));
+  frames.push_back(QuicFrame(&window_update));
+  frames.push_back(QuicFrame(frame2));
+  frames.push_back(QuicFrame(frame3));
+  EXPECT_FALSE(session_.WillingAndAbleToWrite());
+
+  EXPECT_CALL(*stream2, RetransmitStreamData(_, _, _)).WillOnce(Return(true));
+  EXPECT_CALL(*connection_, SendControlFrame(_))
+      .WillOnce(Invoke(&session_, &TestSession::ClearControlFrame));
+  EXPECT_CALL(*stream4, RetransmitStreamData(_, _, _)).WillOnce(Return(true));
+  EXPECT_CALL(*stream6, RetransmitStreamData(_, _, _)).WillOnce(Return(true));
+  EXPECT_CALL(*send_algorithm, OnApplicationLimited(_));
+  session_.RetransmitFrames(frames, TLP_RETRANSMISSION);
+}
+
+TEST_P(QuicSpdySessionTestServer, OnPriorityFrame) {
+  QuicStreamId stream_id = GetNthClientInitiatedBidirectionalId(0);
+  TestStream* stream = session_.CreateIncomingStream(stream_id);
+  session_.OnPriorityFrame(stream_id, kV3HighestPriority);
+  EXPECT_EQ(kV3HighestPriority, stream->priority());
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quic/core/http/quic_spdy_stream.cc b/quic/core/http/quic_spdy_stream.cc
new file mode 100644
index 0000000..9e9f1b7
--- /dev/null
+++ b/quic/core/http/quic_spdy_stream.cc
@@ -0,0 +1,623 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/third_party/quiche/src/quic/core/http/quic_spdy_stream.h"
+
+#include <utility>
+
+#include "net/third_party/quiche/src/quic/core/http/quic_spdy_session.h"
+#include "net/third_party/quiche/src/quic/core/http/spdy_utils.h"
+#include "net/third_party/quiche/src/quic/core/quic_utils.h"
+#include "net/third_party/quiche/src/quic/core/quic_write_blocked_list.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_bug_tracker.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_flag_utils.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_flags.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_logging.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_mem_slice_storage.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_string.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_string_piece.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_text_utils.h"
+#include "net/third_party/quiche/src/spdy/core/spdy_protocol.h"
+
+using spdy::SpdyHeaderBlock;
+using spdy::SpdyPriority;
+
+namespace quic {
+
+// Visitor of HttpDecoder that passes data frame to QuicSpdyStream and closes
+// the connection on unexpected frames.
+class QuicSpdyStream::HttpDecoderVisitor : public HttpDecoder::Visitor {
+ public:
+  explicit HttpDecoderVisitor(QuicSpdyStream* stream) : stream_(stream) {}
+  HttpDecoderVisitor(const HttpDecoderVisitor&) = delete;
+  HttpDecoderVisitor& operator=(const HttpDecoderVisitor&) = delete;
+
+  void OnError(HttpDecoder* decoder) override {
+    stream_->session()->connection()->CloseConnection(
+        QUIC_HTTP_DECODER_ERROR, "Http decoder internal error",
+        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+  }
+
+  void OnPriorityFrame(const PriorityFrame& frame) override {
+    CloseConnectionOnWrongFrame("Priority");
+  }
+
+  void OnCancelPushFrame(const CancelPushFrame& frame) override {
+    CloseConnectionOnWrongFrame("Cancel Push");
+  }
+
+  void OnMaxPushIdFrame(const MaxPushIdFrame& frame) override {
+    CloseConnectionOnWrongFrame("Max Push Id");
+  }
+
+  void OnGoAwayFrame(const GoAwayFrame& frame) override {
+    CloseConnectionOnWrongFrame("Goaway");
+  }
+
+  void OnSettingsFrame(const SettingsFrame& frame) override {
+    CloseConnectionOnWrongFrame("Settings");
+  }
+
+  void OnDuplicatePushFrame(const DuplicatePushFrame& frame) override {
+    CloseConnectionOnWrongFrame("Duplicate Push");
+  }
+
+  void OnDataFrameStart(Http3FrameLengths frame_lengths) override {
+    stream_->OnDataFrameStart(frame_lengths);
+  }
+
+  void OnDataFramePayload(QuicStringPiece payload) override {
+    stream_->OnDataFramePayload(payload);
+  }
+
+  void OnDataFrameEnd() override { stream_->OnDataFrameEnd(); }
+
+  void OnHeadersFrameStart() override {
+    CloseConnectionOnWrongFrame("Headers");
+  }
+
+  void OnHeadersFramePayload(QuicStringPiece payload) override {
+    CloseConnectionOnWrongFrame("Headers");
+  }
+
+  void OnHeadersFrameEnd(QuicByteCount frame_len) override {
+    CloseConnectionOnWrongFrame("Headers");
+  }
+
+  void OnPushPromiseFrameStart(PushId push_id) override {
+    CloseConnectionOnWrongFrame("Push Promise");
+  }
+
+  void OnPushPromiseFramePayload(QuicStringPiece payload) override {
+    CloseConnectionOnWrongFrame("Push Promise");
+  }
+
+  void OnPushPromiseFrameEnd() override {
+    CloseConnectionOnWrongFrame("Push Promise");
+  }
+
+ private:
+  void CloseConnectionOnWrongFrame(QuicString frame_type) {
+    stream_->session()->connection()->CloseConnection(
+        QUIC_HTTP_DECODER_ERROR, frame_type + " frame received on data stream",
+        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+  }
+
+  QuicSpdyStream* stream_;
+};
+
+#define ENDPOINT                                                   \
+  (session()->perspective() == Perspective::IS_SERVER ? "Server: " \
+                                                      : "Client:"  \
+                                                        " ")
+
+QuicSpdyStream::QuicSpdyStream(QuicStreamId id,
+                               QuicSpdySession* spdy_session,
+                               StreamType type)
+    : QuicStream(id, spdy_session, /*is_static=*/false, type),
+      spdy_session_(spdy_session),
+      visitor_(nullptr),
+      headers_decompressed_(false),
+      trailers_decompressed_(false),
+      trailers_consumed_(false),
+      http_decoder_visitor_(new HttpDecoderVisitor(this)),
+      body_buffer_(sequencer()),
+      ack_listener_(nullptr) {
+  DCHECK_NE(QuicUtils::GetCryptoStreamId(
+                spdy_session->connection()->transport_version()),
+            id);
+  // Don't receive any callbacks from the sequencer until headers
+  // are complete.
+  sequencer()->SetBlockedUntilFlush();
+
+  if (VersionHasDataFrameHeader(
+          spdy_session_->connection()->transport_version())) {
+    sequencer()->set_level_triggered(true);
+  }
+  decoder_.set_visitor(http_decoder_visitor_.get());
+}
+
+QuicSpdyStream::QuicSpdyStream(PendingStream pending,
+                               QuicSpdySession* spdy_session,
+                               StreamType type)
+    : QuicStream(std::move(pending), type),
+      spdy_session_(spdy_session),
+      visitor_(nullptr),
+      headers_decompressed_(false),
+      trailers_decompressed_(false),
+      trailers_consumed_(false),
+      http_decoder_visitor_(new HttpDecoderVisitor(this)),
+      body_buffer_(sequencer()),
+      ack_listener_(nullptr) {
+  DCHECK_NE(QuicUtils::GetCryptoStreamId(
+                spdy_session->connection()->transport_version()),
+            id());
+  // Don't receive any callbacks from the sequencer until headers
+  // are complete.
+  sequencer()->SetBlockedUntilFlush();
+
+  if (VersionHasDataFrameHeader(
+          spdy_session_->connection()->transport_version())) {
+    sequencer()->set_level_triggered(true);
+  }
+  decoder_.set_visitor(http_decoder_visitor_.get());
+}
+
+QuicSpdyStream::~QuicSpdyStream() {}
+
+size_t QuicSpdyStream::WriteHeaders(
+    SpdyHeaderBlock header_block,
+    bool fin,
+    QuicReferenceCountedPointer<QuicAckListenerInterface> ack_listener) {
+  size_t bytes_written =
+      WriteHeadersImpl(std::move(header_block), fin, std::move(ack_listener));
+  if (fin) {
+    // TODO(rch): Add test to ensure fin_sent_ is set whenever a fin is sent.
+    set_fin_sent(true);
+    CloseWriteSide();
+  }
+  return bytes_written;
+}
+
+void QuicSpdyStream::WriteOrBufferBody(QuicStringPiece data, bool fin) {
+  if (!VersionHasDataFrameHeader(
+          spdy_session_->connection()->transport_version()) ||
+      data.length() == 0) {
+    WriteOrBufferData(data, fin, nullptr);
+    return;
+  }
+  QuicConnection::ScopedPacketFlusher flusher(
+      spdy_session_->connection(), QuicConnection::SEND_ACK_IF_PENDING);
+
+  // Write frame header.
+  std::unique_ptr<char[]> buffer;
+  QuicByteCount header_length =
+      encoder_.SerializeDataFrameHeader(data.length(), &buffer);
+  unacked_frame_headers_offsets_.Add(
+      send_buffer().stream_offset(),
+      send_buffer().stream_offset() + header_length);
+  QUIC_DLOG(INFO) << "Stream " << id() << " is writing header of length "
+                  << header_length;
+  WriteOrBufferData(QuicStringPiece(buffer.get(), header_length), false,
+                    nullptr);
+
+  // Write body.
+  QUIC_DLOG(INFO) << "Stream " << id() << " is writing body of length "
+                  << data.length();
+  WriteOrBufferData(data, fin, nullptr);
+}
+
+size_t QuicSpdyStream::WriteTrailers(
+    SpdyHeaderBlock trailer_block,
+    QuicReferenceCountedPointer<QuicAckListenerInterface> ack_listener) {
+  if (fin_sent()) {
+    QUIC_BUG << "Trailers cannot be sent after a FIN, on stream " << id();
+    return 0;
+  }
+
+  // The header block must contain the final offset for this stream, as the
+  // trailers may be processed out of order at the peer.
+  QUIC_DLOG(INFO) << "Inserting trailer: (" << kFinalOffsetHeaderKey << ", "
+                  << stream_bytes_written() + BufferedDataBytes() << ")";
+  trailer_block.insert(
+      std::make_pair(kFinalOffsetHeaderKey,
+                     QuicTextUtils::Uint64ToString(stream_bytes_written() +
+                                                   BufferedDataBytes())));
+
+  // Write the trailing headers with a FIN, and close stream for writing:
+  // trailers are the last thing to be sent on a stream.
+  const bool kFin = true;
+  size_t bytes_written =
+      WriteHeadersImpl(std::move(trailer_block), kFin, std::move(ack_listener));
+  set_fin_sent(kFin);
+
+  // Trailers are the last thing to be sent on a stream, but if there is still
+  // queued data then CloseWriteSide() will cause it never to be sent.
+  if (BufferedDataBytes() == 0) {
+    CloseWriteSide();
+  }
+
+  return bytes_written;
+}
+
+QuicConsumedData QuicSpdyStream::WritevBody(const struct iovec* iov,
+                                            int count,
+                                            bool fin) {
+  if (!GetQuicReloadableFlag(quic_call_write_mem_slices)) {
+    return WritevData(iov, count, fin);
+  }
+  QUIC_RELOADABLE_FLAG_COUNT(quic_call_write_mem_slices);
+  QuicMemSliceStorage storage(
+      iov, count,
+      session()->connection()->helper()->GetStreamSendBufferAllocator(),
+      GetQuicFlag(FLAGS_quic_send_buffer_max_data_slice_size));
+  return WriteBodySlices(storage.ToSpan(), fin);
+}
+
+QuicConsumedData QuicSpdyStream::WriteBodySlices(QuicMemSliceSpan slices,
+                                                 bool fin) {
+  if (!VersionHasDataFrameHeader(
+          spdy_session_->connection()->transport_version()) ||
+      slices.empty()) {
+    return WriteMemSlices(slices, fin);
+  }
+
+  std::unique_ptr<char[]> buffer;
+  QuicByteCount header_length =
+      encoder_.SerializeDataFrameHeader(slices.total_length(), &buffer);
+  if (!CanWriteNewDataAfterData(header_length)) {
+    return {0, false};
+  }
+
+  QuicConnection::ScopedPacketFlusher flusher(
+      spdy_session_->connection(), QuicConnection::SEND_ACK_IF_PENDING);
+
+  // Write frame header.
+  struct iovec header_iov = {static_cast<void*>(buffer.get()), header_length};
+  QuicMemSliceStorage storage(
+      &header_iov, 1,
+      spdy_session_->connection()->helper()->GetStreamSendBufferAllocator(),
+      GetQuicFlag(FLAGS_quic_send_buffer_max_data_slice_size));
+  unacked_frame_headers_offsets_.Add(
+      send_buffer().stream_offset(),
+      send_buffer().stream_offset() + header_length);
+  QUIC_DLOG(INFO) << "Stream " << id() << " is writing header of length "
+                  << header_length;
+  WriteMemSlices(storage.ToSpan(), false);
+
+  // Write body.
+  QUIC_DLOG(INFO) << "Stream " << id() << " is writing body of length "
+                  << slices.total_length();
+  return WriteMemSlices(slices, fin);
+}
+
+size_t QuicSpdyStream::Readv(const struct iovec* iov, size_t iov_len) {
+  DCHECK(FinishedReadingHeaders());
+  if (!VersionHasDataFrameHeader(
+          spdy_session_->connection()->transport_version())) {
+    return sequencer()->Readv(iov, iov_len);
+  }
+  return body_buffer_.ReadBody(iov, iov_len);
+}
+
+int QuicSpdyStream::GetReadableRegions(iovec* iov, size_t iov_len) const {
+  DCHECK(FinishedReadingHeaders());
+  if (!VersionHasDataFrameHeader(
+          spdy_session_->connection()->transport_version())) {
+    return sequencer()->GetReadableRegions(iov, iov_len);
+  }
+  return body_buffer_.PeekBody(iov, iov_len);
+}
+
+void QuicSpdyStream::MarkConsumed(size_t num_bytes) {
+  DCHECK(FinishedReadingHeaders());
+  if (!VersionHasDataFrameHeader(
+          spdy_session_->connection()->transport_version())) {
+    sequencer()->MarkConsumed(num_bytes);
+    return;
+  }
+  body_buffer_.MarkBodyConsumed(num_bytes);
+}
+
+bool QuicSpdyStream::IsDoneReading() const {
+  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 {
+  if (!VersionHasDataFrameHeader(
+          spdy_session_->connection()->transport_version())) {
+    return sequencer()->HasBytesToRead();
+  }
+  return body_buffer_.HasBytesToRead();
+}
+
+void QuicSpdyStream::MarkTrailersConsumed() {
+  trailers_consumed_ = true;
+}
+
+uint64_t QuicSpdyStream::total_body_bytes_read() const {
+  if (VersionHasDataFrameHeader(
+          spdy_session_->connection()->transport_version())) {
+    return body_buffer_.total_body_bytes_received();
+  }
+  return sequencer()->NumBytesConsumed();
+}
+
+void QuicSpdyStream::ConsumeHeaderList() {
+  header_list_.Clear();
+  if (FinishedReadingHeaders()) {
+    sequencer()->SetUnblocked();
+  }
+}
+
+void QuicSpdyStream::OnStreamHeadersPriority(SpdyPriority priority) {
+  DCHECK_EQ(Perspective::IS_SERVER, session()->connection()->perspective());
+  SetPriority(priority);
+}
+
+void QuicSpdyStream::OnStreamHeaderList(bool fin,
+                                        size_t frame_len,
+                                        const QuicHeaderList& header_list) {
+  // The headers list avoid infinite buffering by clearing the headers list
+  // if the current headers are too large. So if the list is empty here
+  // then the headers list must have been too large, and the stream should
+  // be reset.
+  // TODO(rch): Use an explicit "headers too large" signal. An empty header list
+  // might be acceptable if it corresponds to a trailing header frame.
+  if (header_list.empty()) {
+    OnHeadersTooLarge();
+    if (IsDoneReading()) {
+      return;
+    }
+  }
+  if (!headers_decompressed_) {
+    OnInitialHeadersComplete(fin, frame_len, header_list);
+  } else {
+    OnTrailingHeadersComplete(fin, frame_len, header_list);
+  }
+}
+
+void QuicSpdyStream::OnHeadersTooLarge() {
+  Reset(QUIC_HEADERS_TOO_LARGE);
+}
+
+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, QuicStringPiece()));
+  }
+  if (FinishedReadingHeaders()) {
+    sequencer()->SetUnblocked();
+  }
+}
+
+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);
+}
+
+void QuicSpdyStream::OnTrailingHeadersComplete(
+    bool fin,
+    size_t /*frame_len*/,
+    const QuicHeaderList& header_list) {
+  DCHECK(!trailers_decompressed_);
+  if (fin_received()) {
+    QUIC_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) {
+    QUIC_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_)) {
+    QUIC_DLOG(ERROR) << "Trailers for stream " << id() << " are malformed.";
+    session()->connection()->CloseConnection(
+        QUIC_INVALID_HEADERS_STREAM_DATA, "Trailers are malformed",
+        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+    return;
+  }
+  trailers_decompressed_ = true;
+  OnStreamFrame(
+      QuicStreamFrame(id(), fin, final_byte_offset, QuicStringPiece()));
+}
+
+size_t QuicSpdyStream::WriteHeadersImpl(
+    spdy::SpdyHeaderBlock header_block,
+    bool fin,
+    QuicReferenceCountedPointer<QuicAckListenerInterface> ack_listener) {
+  return spdy_session_->WriteHeadersOnHeadersStream(
+      id(), std::move(header_block), fin, priority(), std::move(ack_listener));
+}
+
+void QuicSpdyStream::OnPriorityFrame(SpdyPriority priority) {
+  DCHECK_EQ(Perspective::IS_SERVER, session()->connection()->perspective());
+  SetPriority(priority);
+}
+
+void QuicSpdyStream::OnStreamReset(const QuicRstStreamFrame& frame) {
+  if (frame.error_code != QUIC_STREAM_NO_ERROR) {
+    QuicStream::OnStreamReset(frame);
+    return;
+  }
+  QUIC_DVLOG(1) << "Received QUIC_STREAM_NO_ERROR, not discarding response";
+  set_rst_received(true);
+  MaybeIncreaseHighestReceivedOffset(frame.byte_offset);
+  set_stream_error(frame.error_code);
+  CloseWriteSide();
+}
+
+void QuicSpdyStream::OnDataAvailable() {
+  if (!VersionHasDataFrameHeader(
+          session()->connection()->transport_version())) {
+    OnBodyAvailable();
+    return;
+  }
+
+  iovec iov;
+  bool has_payload = false;
+  while (sequencer()->PrefetchNextRegion(&iov)) {
+    decoder_.ProcessInput(reinterpret_cast<const char*>(iov.iov_base),
+                          iov.iov_len);
+    if (decoder_.has_payload()) {
+      has_payload = true;
+    }
+  }
+
+  if (has_payload) {
+    OnBodyAvailable();
+    return;
+  }
+
+  if (sequencer()->IsClosed()) {
+    OnBodyAvailable();
+    return;
+  }
+}
+
+void QuicSpdyStream::OnClose() {
+  QuicStream::OnClose();
+
+  if (visitor_) {
+    Visitor* visitor = visitor_;
+    // Calling Visitor::OnClose() may result the destruction of the visitor,
+    // so we need to ensure we don't call it again.
+    visitor_ = nullptr;
+    visitor->OnClose(this);
+  }
+}
+
+void QuicSpdyStream::OnCanWrite() {
+  QuicStream::OnCanWrite();
+
+  // Trailers (and hence a FIN) may have been sent ahead of queued body bytes.
+  if (!HasBufferedData() && fin_sent()) {
+    CloseWriteSide();
+  }
+}
+
+bool QuicSpdyStream::FinishedReadingHeaders() const {
+  return headers_decompressed_ && header_list_.empty();
+}
+
+bool QuicSpdyStream::ParseHeaderStatusCode(const SpdyHeaderBlock& header,
+                                           int* status_code) const {
+  SpdyHeaderBlock::const_iterator it = header.find(spdy::kHttp2StatusHeader);
+  if (it == header.end()) {
+    return false;
+  }
+  const QuicStringPiece status(it->second);
+  if (status.size() != 3) {
+    return false;
+  }
+  // First character must be an integer in range [1,5].
+  if (status[0] < '1' || status[0] > '5') {
+    return false;
+  }
+  // The remaining two characters must be integers.
+  if (!isdigit(status[1]) || !isdigit(status[2])) {
+    return false;
+  }
+  return QuicTextUtils::StringToInt(status, status_code);
+}
+
+bool QuicSpdyStream::FinishedReadingTrailers() const {
+  // If no further trailing headers are expected, and the decompressed trailers
+  // (if any) have been consumed, then reading of trailers is finished.
+  if (!fin_received()) {
+    return false;
+  } else if (!trailers_decompressed_) {
+    return true;
+  } else {
+    return trailers_consumed_;
+  }
+}
+
+void QuicSpdyStream::ClearSession() {
+  spdy_session_ = nullptr;
+}
+
+void QuicSpdyStream::OnDataFrameStart(Http3FrameLengths frame_lengths) {
+  body_buffer_.OnDataHeader(frame_lengths);
+}
+
+void QuicSpdyStream::OnDataFramePayload(QuicStringPiece payload) {
+  body_buffer_.OnDataPayload(payload);
+}
+
+void QuicSpdyStream::OnDataFrameEnd() {
+  DVLOG(1) << "Reaches the end of a data frame. Total bytes received are "
+           << body_buffer_.total_body_bytes_received();
+}
+
+bool QuicSpdyStream::OnStreamFrameAcked(QuicStreamOffset offset,
+                                        QuicByteCount data_length,
+                                        bool fin_acked,
+                                        QuicTime::Delta ack_delay_time,
+                                        QuicByteCount* newly_acked_length) {
+  const bool new_data_acked = QuicStream::OnStreamFrameAcked(
+      offset, data_length, fin_acked, ack_delay_time, newly_acked_length);
+
+  const QuicByteCount newly_acked_header_length =
+      GetNumFrameHeadersInInterval(offset, data_length);
+  DCHECK_LE(newly_acked_header_length, *newly_acked_length);
+  unacked_frame_headers_offsets_.Difference(offset, offset + data_length);
+  if (ack_listener_ != nullptr && new_data_acked) {
+    ack_listener_->OnPacketAcked(
+        *newly_acked_length - newly_acked_header_length, ack_delay_time);
+  }
+  return new_data_acked;
+}
+
+void QuicSpdyStream::OnStreamFrameRetransmitted(QuicStreamOffset offset,
+                                                QuicByteCount data_length,
+                                                bool fin_retransmitted) {
+  QuicStream::OnStreamFrameRetransmitted(offset, data_length,
+                                         fin_retransmitted);
+
+  const QuicByteCount retransmitted_header_length =
+      GetNumFrameHeadersInInterval(offset, data_length);
+  DCHECK_LE(retransmitted_header_length, data_length);
+
+  if (ack_listener_ != nullptr) {
+    ack_listener_->OnPacketRetransmitted(data_length -
+                                         retransmitted_header_length);
+  }
+}
+
+QuicByteCount QuicSpdyStream::GetNumFrameHeadersInInterval(
+    QuicStreamOffset offset,
+    QuicByteCount data_length) const {
+  QuicByteCount header_acked_length = 0;
+  QuicIntervalSet<QuicStreamOffset> newly_acked(offset, offset + data_length);
+  newly_acked.Intersection(unacked_frame_headers_offsets_);
+  for (const auto& interval : newly_acked) {
+    header_acked_length += interval.Length();
+  }
+  return header_acked_length;
+}
+
+#undef ENDPOINT  // undef for jumbo builds
+}  // namespace quic
diff --git a/quic/core/http/quic_spdy_stream.h b/quic/core/http/quic_spdy_stream.h
new file mode 100644
index 0000000..2bad21a
--- /dev/null
+++ b/quic/core/http/quic_spdy_stream.h
@@ -0,0 +1,284 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// The base class for streams which deliver data to/from an application.
+// In each direction, the data on such a stream first contains compressed
+// headers then body data.
+
+#ifndef QUICHE_QUIC_CORE_HTTP_QUIC_SPDY_STREAM_H_
+#define QUICHE_QUIC_CORE_HTTP_QUIC_SPDY_STREAM_H_
+
+#include <sys/types.h>
+
+#include <cstddef>
+#include <list>
+
+#include "base/macros.h"
+#include "net/third_party/quiche/src/quic/core/http/http_decoder.h"
+#include "net/third_party/quiche/src/quic/core/http/http_encoder.h"
+#include "net/third_party/quiche/src/quic/core/http/quic_header_list.h"
+#include "net/third_party/quiche/src/quic/core/http/quic_spdy_stream_body_buffer.h"
+#include "net/third_party/quiche/src/quic/core/quic_packets.h"
+#include "net/third_party/quiche/src/quic/core/quic_stream.h"
+#include "net/third_party/quiche/src/quic/core/quic_stream_sequencer.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_export.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_flags.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_socket_address.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_string.h"
+#include "net/third_party/quiche/src/spdy/core/spdy_framer.h"
+
+namespace quic {
+
+namespace test {
+class QuicSpdyStreamPeer;
+class QuicStreamPeer;
+}  // namespace test
+
+class QuicSpdySession;
+
+// A QUIC stream that can send and receive HTTP2 (SPDY) headers.
+class QUIC_EXPORT_PRIVATE QuicSpdyStream : public QuicStream {
+ public:
+  // Visitor receives callbacks from the stream.
+  class QUIC_EXPORT_PRIVATE Visitor {
+   public:
+    Visitor() {}
+    Visitor(const Visitor&) = delete;
+    Visitor& operator=(const Visitor&) = delete;
+
+    // Called when the stream is closed.
+    virtual void OnClose(QuicSpdyStream* stream) = 0;
+
+    // Allows subclasses to override and do work.
+    virtual void OnPromiseHeadersComplete(QuicStreamId promised_id,
+                                          size_t frame_len) {}
+
+   protected:
+    virtual ~Visitor() {}
+  };
+
+  QuicSpdyStream(QuicStreamId id,
+                 QuicSpdySession* spdy_session,
+                 StreamType type);
+  QuicSpdyStream(PendingStream pending,
+                 QuicSpdySession* spdy_session,
+                 StreamType type);
+  QuicSpdyStream(const QuicSpdyStream&) = delete;
+  QuicSpdyStream& operator=(const QuicSpdyStream&) = delete;
+  ~QuicSpdyStream() override;
+
+  // QuicStream implementation
+  void OnClose() override;
+
+  // Override to maybe close the write side after writing.
+  void OnCanWrite() override;
+
+  // Called by the session when headers with a priority have been received
+  // for this stream.  This method will only be called for server streams.
+  virtual void OnStreamHeadersPriority(spdy::SpdyPriority priority);
+
+  // Called by the session when decompressed headers have been completely
+  // delivered to this stream.  If |fin| is true, then this stream
+  // should be closed; no more data will be sent by the peer.
+  virtual void OnStreamHeaderList(bool fin,
+                                  size_t frame_len,
+                                  const QuicHeaderList& header_list);
+
+  // Called when the received headers are too large. By default this will
+  // reset the stream.
+  virtual void OnHeadersTooLarge();
+
+  // Called by the session when decompressed push promise headers have
+  // been completely delivered to this stream.
+  virtual void OnPromiseHeaderList(QuicStreamId promised_id,
+                                   size_t frame_len,
+                                   const QuicHeaderList& header_list);
+
+  // Called by the session when a PRIORITY frame has been been received for this
+  // stream. This method will only be called for server streams.
+  void OnPriorityFrame(spdy::SpdyPriority priority);
+
+  // Override the base class to not discard response when receiving
+  // QUIC_STREAM_NO_ERROR.
+  void OnStreamReset(const QuicRstStreamFrame& frame) override;
+
+  // Called by the sequencer when new data is available. Decodes the data and
+  // calls OnBodyAvailable() to pass to the upper layer.
+  void OnDataAvailable() override;
+
+  // Called in OnDataAvailable() after it finishes the decoding job.
+  virtual void OnBodyAvailable() = 0;
+
+  // Writes the headers contained in |header_block| to the dedicated
+  // headers stream.
+  virtual size_t WriteHeaders(
+      spdy::SpdyHeaderBlock header_block,
+      bool fin,
+      QuicReferenceCountedPointer<QuicAckListenerInterface> ack_listener);
+
+  // Sends |data| to the peer, or buffers if it can't be sent immediately.
+  void WriteOrBufferBody(QuicStringPiece data, bool fin);
+
+  // Writes the trailers contained in |trailer_block| to the dedicated
+  // headers stream. Trailers will always have the FIN set.
+  virtual size_t WriteTrailers(
+      spdy::SpdyHeaderBlock trailer_block,
+      QuicReferenceCountedPointer<QuicAckListenerInterface> ack_listener);
+
+  // Override to report newly acked bytes via ack_listener_.
+  bool OnStreamFrameAcked(QuicStreamOffset offset,
+                          QuicByteCount data_length,
+                          bool fin_acked,
+                          QuicTime::Delta ack_delay_time,
+                          QuicByteCount* newly_acked_length) override;
+
+  // Override to report bytes retransmitted via ack_listener_.
+  void OnStreamFrameRetransmitted(QuicStreamOffset offset,
+                                  QuicByteCount data_length,
+                                  bool fin_retransmitted) override;
+
+  // Does the same thing as WriteOrBufferBody except this method takes iovec
+  // as the data input. Right now it only calls WritevData.
+  // TODO(renjietang): Write data frame header before writing body.
+  QuicConsumedData WritevBody(const struct iovec* iov, int count, bool fin);
+
+  // Does the same thing as WriteOrBufferBody except this method takes
+  // memslicespan as the data input. Right now it only calls WriteMemSlices.
+  // TODO(renjietang): Write data frame header before writing body.
+  QuicConsumedData WriteBodySlices(QuicMemSliceSpan slices, bool fin);
+
+  // Marks the trailers as consumed. This applies to the case where this object
+  // receives headers and trailers as QuicHeaderLists via calls to
+  // OnStreamHeaderList().
+  void MarkTrailersConsumed();
+
+  // Clears |header_list_|.
+  void ConsumeHeaderList();
+
+  // This block of functions wraps the sequencer's functions of the same
+  // name.  These methods return uncompressed data until that has
+  // been fully processed.  Then they simply delegate to the sequencer.
+  virtual size_t Readv(const struct iovec* iov, size_t iov_len);
+  virtual int GetReadableRegions(iovec* iov, size_t iov_len) const;
+  void MarkConsumed(size_t num_bytes);
+
+  // Returns true if header contains a valid 3-digit status and parse the status
+  // code to |status_code|.
+  bool ParseHeaderStatusCode(const spdy::SpdyHeaderBlock& header,
+                             int* status_code) const;
+
+  // Returns true when all data has been read from the peer, including the fin.
+  bool IsDoneReading() const;
+  bool HasBytesToRead() const;
+
+  void set_visitor(Visitor* visitor) { visitor_ = visitor; }
+
+  bool headers_decompressed() const { return headers_decompressed_; }
+
+  // Returns total amount of body bytes that have been read.
+  uint64_t total_body_bytes_read() const;
+
+  const QuicHeaderList& header_list() const { return header_list_; }
+
+  bool trailers_decompressed() const { return trailers_decompressed_; }
+
+  // Returns whatever trailers have been received for this stream.
+  const spdy::SpdyHeaderBlock& received_trailers() const {
+    return received_trailers_;
+  }
+
+  // Returns true if headers have been fully read and consumed.
+  bool FinishedReadingHeaders() const;
+
+  // Returns true if trailers have been fully read and consumed, or FIN has
+  // been received and there are no trailers.
+  bool FinishedReadingTrailers() const;
+
+  // Called when owning session is getting deleted to avoid subsequent
+  // use of the spdy_session_ member.
+  void ClearSession();
+
+  // Returns true if the sequencer has delivered the FIN, and no more body bytes
+  // will be available.
+  bool IsClosed() { return sequencer()->IsClosed(); }
+
+  void OnDataFrameStart(Http3FrameLengths frame_lengths);
+  void OnDataFramePayload(QuicStringPiece payload);
+  void OnDataFrameEnd();
+
+  using QuicStream::CloseWriteSide;
+
+ protected:
+  virtual void OnInitialHeadersComplete(bool fin,
+                                        size_t frame_len,
+                                        const QuicHeaderList& header_list);
+  virtual void OnTrailingHeadersComplete(bool fin,
+                                         size_t frame_len,
+                                         const QuicHeaderList& header_list);
+  virtual size_t WriteHeadersImpl(
+      spdy::SpdyHeaderBlock header_block,
+      bool fin,
+      QuicReferenceCountedPointer<QuicAckListenerInterface> ack_listener);
+
+  QuicSpdySession* spdy_session() const { return spdy_session_; }
+  Visitor* visitor() { return visitor_; }
+
+  void set_headers_decompressed(bool val) { headers_decompressed_ = val; }
+
+  void set_ack_listener(
+      QuicReferenceCountedPointer<QuicAckListenerInterface> ack_listener) {
+    ack_listener_ = std::move(ack_listener);
+  }
+
+  const QuicIntervalSet<QuicStreamOffset>& unacked_frame_headers_offsets() {
+    return unacked_frame_headers_offsets_;
+  }
+
+ private:
+  friend class test::QuicSpdyStreamPeer;
+  friend class test::QuicStreamPeer;
+  friend class QuicStreamUtils;
+  class HttpDecoderVisitor;
+
+  // Given the interval marked by [|offset|, |offset| + |data_length|), return
+  // the number of frame header bytes contained in it.
+  QuicByteCount GetNumFrameHeadersInInterval(QuicStreamOffset offset,
+                                             QuicByteCount data_length) const;
+
+  QuicSpdySession* spdy_session_;
+
+  Visitor* visitor_;
+  // True if the headers have been completely decompressed.
+  bool headers_decompressed_;
+  // Contains a copy of the decompressed header (name, value) pairs until they
+  // are consumed via Readv.
+  QuicHeaderList header_list_;
+
+  // True if the trailers have been completely decompressed.
+  bool trailers_decompressed_;
+  // True if the trailers have been consumed.
+  bool trailers_consumed_;
+  // The parsed trailers received from the peer.
+  spdy::SpdyHeaderBlock received_trailers_;
+
+  // Http encoder for writing streams.
+  HttpEncoder encoder_;
+  // Http decoder for processing raw incoming stream frames.
+  HttpDecoder decoder_;
+  // Visitor of the HttpDecoder.
+  std::unique_ptr<HttpDecoderVisitor> http_decoder_visitor_;
+  // Buffer that contains decoded data of the stream.
+  QuicSpdyStreamBodyBuffer body_buffer_;
+
+  // Ack listener of this stream, and it is notified when any of written bytes
+  // are acked or retransmitted.
+  QuicReferenceCountedPointer<QuicAckListenerInterface> ack_listener_;
+
+  // Offset of unacked frame headers.
+  QuicIntervalSet<QuicStreamOffset> unacked_frame_headers_offsets_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_HTTP_QUIC_SPDY_STREAM_H_
diff --git a/quic/core/http/quic_spdy_stream_body_buffer.cc b/quic/core/http/quic_spdy_stream_body_buffer.cc
new file mode 100644
index 0000000..dcb8030
--- /dev/null
+++ b/quic/core/http/quic_spdy_stream_body_buffer.cc
@@ -0,0 +1,127 @@
+// Copyright (c) 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/third_party/quiche/src/quic/core/http/quic_spdy_stream_body_buffer.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_logging.h"
+
+namespace quic {
+
+QuicSpdyStreamBodyBuffer::QuicSpdyStreamBodyBuffer(
+    QuicStreamSequencer* sequencer)
+    : bytes_remaining_(0),
+      total_body_bytes_readable_(0),
+      total_body_bytes_received_(0),
+      total_payload_lengths_(0),
+      sequencer_(sequencer) {}
+
+QuicSpdyStreamBodyBuffer::~QuicSpdyStreamBodyBuffer() {}
+
+void QuicSpdyStreamBodyBuffer::OnDataHeader(Http3FrameLengths frame_lengths) {
+  frame_meta_.push_back(frame_lengths);
+  total_payload_lengths_ += frame_lengths.payload_length;
+}
+
+void QuicSpdyStreamBodyBuffer::OnDataPayload(QuicStringPiece payload) {
+  bodies_.push_back(payload);
+  total_body_bytes_received_ += payload.length();
+  total_body_bytes_readable_ += payload.length();
+  DCHECK_LE(total_body_bytes_received_, total_payload_lengths_);
+}
+
+void QuicSpdyStreamBodyBuffer::MarkBodyConsumed(size_t num_bytes) {
+  // Check if the stream has enough decoded data.
+  if (num_bytes > total_body_bytes_readable_) {
+    QUIC_BUG << "Invalid argument to MarkBodyConsumed."
+             << " expect to consume: " << num_bytes
+             << ", but not enough bytes available. "
+             << "Total bytes readable are: " << total_body_bytes_readable_;
+    return;
+  }
+  // Discard references in the stream before the sequencer marks them consumed.
+  size_t remaining = num_bytes;
+  while (remaining > 0) {
+    if (bodies_.empty()) {
+      QUIC_BUG << "Failed to consume because body buffer is empty.";
+      return;
+    }
+    auto body = bodies_.front();
+    bodies_.pop_front();
+    if (body.length() <= remaining) {
+      remaining -= body.length();
+    } else {
+      body = body.substr(remaining, body.length() - remaining);
+      bodies_.push_front(body);
+      remaining = 0;
+    }
+  }
+  // Consume headers.
+  while (bytes_remaining_ < num_bytes) {
+    if (frame_meta_.empty()) {
+      QUIC_BUG << "Faild to consume because frame header buffer is empty.";
+      return;
+    }
+    auto meta = frame_meta_.front();
+    frame_meta_.pop_front();
+    bytes_remaining_ += meta.payload_length;
+    sequencer_->MarkConsumed(meta.header_length);
+  }
+  sequencer_->MarkConsumed(num_bytes);
+  // Update accountings.
+  bytes_remaining_ -= num_bytes;
+  total_body_bytes_readable_ -= num_bytes;
+}
+
+int QuicSpdyStreamBodyBuffer::PeekBody(iovec* iov, size_t iov_len) const {
+  DCHECK(iov != nullptr);
+  DCHECK_GT(iov_len, 0u);
+
+  if (bodies_.empty()) {
+    iov[0].iov_base = nullptr;
+    iov[0].iov_len = 0;
+    return 0;
+  }
+  // Fill iovs with references from the stream.
+  size_t iov_filled = 0;
+  while (iov_filled < bodies_.size() && iov_filled < iov_len) {
+    QuicStringPiece body = bodies_[iov_filled];
+    iov[iov_filled].iov_base = const_cast<char*>(body.data());
+    iov[iov_filled].iov_len = body.size();
+    iov_filled++;
+  }
+  return iov_filled;
+}
+
+size_t QuicSpdyStreamBodyBuffer::ReadBody(const struct iovec* iov,
+                                          size_t iov_len) {
+  size_t total_data_read = 0;
+  QuicByteCount total_remaining = total_body_bytes_readable_;
+  size_t index = 0;
+  size_t src_offset = 0;
+  for (size_t i = 0; i < iov_len && total_remaining > 0; ++i) {
+    char* dest = reinterpret_cast<char*>(iov[i].iov_base);
+    size_t dest_remaining = iov[i].iov_len;
+    while (dest_remaining > 0 && total_remaining > 0) {
+      auto body = bodies_[index];
+      size_t bytes_to_copy =
+          std::min<size_t>(body.length() - src_offset, dest_remaining);
+      memcpy(dest, body.substr(src_offset, bytes_to_copy).data(),
+             bytes_to_copy);
+      dest += bytes_to_copy;
+      dest_remaining -= bytes_to_copy;
+      total_data_read += bytes_to_copy;
+      total_remaining -= bytes_to_copy;
+      if (bytes_to_copy < body.length() - src_offset) {
+        src_offset += bytes_to_copy;
+      } else {
+        index++;
+        src_offset = 0;
+      }
+    }
+  }
+
+  MarkBodyConsumed(total_data_read);
+  return total_data_read;
+}
+
+}  // namespace quic
diff --git a/quic/core/http/quic_spdy_stream_body_buffer.h b/quic/core/http/quic_spdy_stream_body_buffer.h
new file mode 100644
index 0000000..2485aac
--- /dev/null
+++ b/quic/core/http/quic_spdy_stream_body_buffer.h
@@ -0,0 +1,75 @@
+// Copyright (c) 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_HTTP_QUIC_SPDY_STREAM_BODY_BUFFER_H_
+#define QUICHE_QUIC_CORE_HTTP_QUIC_SPDY_STREAM_BODY_BUFFER_H_
+
+#include "net/third_party/quiche/src/quic/core/http/http_decoder.h"
+#include "net/third_party/quiche/src/quic/core/quic_stream_sequencer.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_bug_tracker.h"
+
+namespace quic {
+
+// Buffer decoded body for QuicSpdyStream. It also talks to the sequencer to
+// consume data.
+class QUIC_EXPORT_PRIVATE QuicSpdyStreamBodyBuffer {
+ public:
+  // QuicSpdyStreamBodyBuffer doesn't own the sequencer and the sequencer can
+  // outlive the buffer.
+  explicit QuicSpdyStreamBodyBuffer(QuicStreamSequencer* sequencer);
+
+  ~QuicSpdyStreamBodyBuffer();
+
+  // Add metadata of the frame to accountings.
+  // Called when QuicSpdyStream receives data frame header.
+  void OnDataHeader(Http3FrameLengths frame_lengths);
+
+  // Add new data payload to buffer.
+  // Called when QuicSpdyStream received data payload.
+  // Data pointed by payload must be alive until consumed by
+  // QuicStreamSequencer::MarkConsumed().
+  void OnDataPayload(QuicStringPiece payload);
+
+  // Take |num_bytes| as the body size, calculate header sizes accordingly, and
+  // consume the right amount of data in the stream sequencer.
+  void MarkBodyConsumed(size_t num_bytes);
+
+  // Fill up to |iov_len| with bodies available in buffer. No data is consumed.
+  // |iov|.iov_base will point to data in the buffer, and |iov|.iov_len will
+  // be set to the underlying data length accordingly.
+  // Returns the number of iov used.
+  int PeekBody(iovec* iov, size_t iov_len) const;
+
+  // Copies from buffer into |iov| up to |iov_len|, and consume data in
+  // sequencer. |iov.iov_base| and |iov.iov_len| are preassigned and will not be
+  // changed.
+  // Returns the number of bytes read.
+  size_t ReadBody(const struct iovec* iov, size_t iov_len);
+
+  bool HasBytesToRead() const { return !bodies_.empty(); }
+
+  uint64_t total_body_bytes_received() const {
+    return total_body_bytes_received_;
+  }
+
+ private:
+  // Storage for decoded data.
+  QuicDeque<QuicStringPiece> bodies_;
+  // Storage for header lengths.
+  QuicDeque<Http3FrameLengths> frame_meta_;
+  // Bytes in the first available data frame that are not consumed yet.
+  QuicByteCount bytes_remaining_;
+  // Total available body data in the stream.
+  QuicByteCount total_body_bytes_readable_;
+  // Total bytes read from the stream excluding headers.
+  QuicByteCount total_body_bytes_received_;
+  // Total length of payloads tracked by frame_meta_.
+  QuicByteCount total_payload_lengths_;
+  // Stream sequencer that directly manages data in the stream.
+  QuicStreamSequencer* sequencer_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_HTTP_QUIC_SPDY_STREAM_BODY_BUFFER_H_
diff --git a/quic/core/http/quic_spdy_stream_body_buffer_test.cc b/quic/core/http/quic_spdy_stream_body_buffer_test.cc
new file mode 100644
index 0000000..7ea776f
--- /dev/null
+++ b/quic/core/http/quic_spdy_stream_body_buffer_test.cc
@@ -0,0 +1,240 @@
+// Copyright (c) 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/third_party/quiche/src/quic/core/http/quic_spdy_stream_body_buffer.h"
+
+#include "testing/gtest/include/gtest/gtest.h"
+#include "net/third_party/quiche/src/quic/core/quic_stream_sequencer.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_expect_bug.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_logging.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_ptr_util.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_str_cat.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_string.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_test.h"
+#include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h"
+
+namespace quic {
+
+namespace test {
+
+namespace {
+
+class MockStream : public QuicStreamSequencer::StreamInterface {
+ public:
+  MOCK_METHOD0(OnFinRead, void());
+  MOCK_METHOD0(OnDataAvailable, void());
+  MOCK_METHOD2(CloseConnectionWithDetails,
+               void(QuicErrorCode error, const QuicString& details));
+  MOCK_METHOD1(Reset, void(QuicRstStreamErrorCode error));
+  MOCK_METHOD0(OnCanWrite, void());
+  MOCK_METHOD1(AddBytesConsumed, void(QuicByteCount bytes));
+
+  QuicStreamId id() const override { return 1; }
+
+  const QuicSocketAddress& PeerAddressOfLatestPacket() const override {
+    return peer_address_;
+  }
+
+ protected:
+  QuicSocketAddress peer_address_ =
+      QuicSocketAddress(QuicIpAddress::Any4(), 65535);
+};
+
+class MockSequencer : public QuicStreamSequencer {
+ public:
+  explicit MockSequencer(MockStream* stream) : QuicStreamSequencer(stream) {}
+  virtual ~MockSequencer() = default;
+  MOCK_METHOD1(MarkConsumed, void(size_t num_bytes_consumed));
+};
+
+class QuicSpdyStreamBodyBufferTest : public QuicTest {
+ public:
+  QuicSpdyStreamBodyBufferTest()
+      : sequencer_(&stream_), body_buffer_(&sequencer_) {}
+
+ protected:
+  MockStream stream_;
+  MockSequencer sequencer_;
+  QuicSpdyStreamBodyBuffer body_buffer_;
+  HttpEncoder encoder_;
+};
+
+TEST_F(QuicSpdyStreamBodyBufferTest, ReceiveBodies) {
+  QuicString body(1024, 'a');
+  EXPECT_FALSE(body_buffer_.HasBytesToRead());
+  body_buffer_.OnDataHeader(Http3FrameLengths(3, 1024));
+  body_buffer_.OnDataPayload(QuicStringPiece(body));
+  EXPECT_EQ(1024u, body_buffer_.total_body_bytes_received());
+  EXPECT_TRUE(body_buffer_.HasBytesToRead());
+}
+
+TEST_F(QuicSpdyStreamBodyBufferTest, PeekBody) {
+  QuicString body(1024, 'a');
+  body_buffer_.OnDataHeader(Http3FrameLengths(3, 1024));
+  body_buffer_.OnDataPayload(QuicStringPiece(body));
+  EXPECT_EQ(1024u, body_buffer_.total_body_bytes_received());
+  iovec vec;
+  EXPECT_EQ(1, body_buffer_.PeekBody(&vec, 1));
+  EXPECT_EQ(1024u, vec.iov_len);
+  EXPECT_EQ(body,
+            QuicStringPiece(static_cast<const char*>(vec.iov_base), 1024));
+}
+
+// Buffer only receives 1 frame. Stream consumes less or equal than a frame.
+TEST_F(QuicSpdyStreamBodyBufferTest, MarkConsumedPartialSingleFrame) {
+  testing::InSequence seq;
+  QuicString body(1024, 'a');
+  std::unique_ptr<char[]> buffer;
+  QuicByteCount header_length =
+      encoder_.SerializeDataFrameHeader(body.length(), &buffer);
+  QuicString header = QuicString(buffer.get(), header_length);
+  Http3FrameLengths lengths(header_length, 1024);
+  QuicString data = header + body;
+  QuicStreamFrame frame(1, false, 0, data);
+  sequencer_.OnStreamFrame(frame);
+  body_buffer_.OnDataHeader(lengths);
+  body_buffer_.OnDataPayload(QuicStringPiece(body));
+  EXPECT_CALL(stream_, AddBytesConsumed(header_length));
+  EXPECT_CALL(stream_, AddBytesConsumed(1024));
+  body_buffer_.MarkBodyConsumed(1024);
+}
+
+// Buffer received 2 frames. Stream consumes multiple times.
+TEST_F(QuicSpdyStreamBodyBufferTest, MarkConsumedMultipleFrames) {
+  testing::InSequence seq;
+  // 1st frame.
+  QuicString body1(1024, 'a');
+  std::unique_ptr<char[]> buffer;
+  QuicByteCount header_length1 =
+      encoder_.SerializeDataFrameHeader(body1.length(), &buffer);
+  QuicString header1 = QuicString(buffer.get(), header_length1);
+  Http3FrameLengths lengths1(header_length1, 1024);
+  QuicString data1 = header1 + body1;
+  QuicStreamFrame frame1(1, false, 0, data1);
+  sequencer_.OnStreamFrame(frame1);
+  body_buffer_.OnDataHeader(lengths1);
+  body_buffer_.OnDataPayload(QuicStringPiece(body1));
+
+  // 2nd frame.
+  QuicString body2(2048, 'b');
+  QuicByteCount header_length2 =
+      encoder_.SerializeDataFrameHeader(body2.length(), &buffer);
+  QuicString header2 = QuicString(buffer.get(), header_length2);
+  Http3FrameLengths lengths2(header_length2, 2048);
+  QuicString data2 = header2 + body2;
+  QuicStreamFrame frame2(1, false, data1.length(), data2);
+  sequencer_.OnStreamFrame(frame2);
+  body_buffer_.OnDataHeader(lengths2);
+  body_buffer_.OnDataPayload(QuicStringPiece(body2));
+
+  EXPECT_CALL(stream_, AddBytesConsumed(header_length1));
+  EXPECT_CALL(stream_, AddBytesConsumed(512));
+  body_buffer_.MarkBodyConsumed(512);
+  EXPECT_CALL(stream_, AddBytesConsumed(header_length2));
+  EXPECT_CALL(stream_, AddBytesConsumed(2048));
+  body_buffer_.MarkBodyConsumed(2048);
+  EXPECT_CALL(stream_, AddBytesConsumed(512));
+  body_buffer_.MarkBodyConsumed(512);
+}
+
+TEST_F(QuicSpdyStreamBodyBufferTest, MarkConsumedMoreThanBuffered) {
+  QuicString body(1024, 'a');
+  Http3FrameLengths lengths(3, 1024);
+  body_buffer_.OnDataHeader(lengths);
+  body_buffer_.OnDataPayload(body);
+  EXPECT_QUIC_BUG(
+      body_buffer_.MarkBodyConsumed(2048),
+      "Invalid argument to MarkBodyConsumed. expect to consume: 2048, but not "
+      "enough bytes available. Total bytes readable are: 1024");
+}
+
+// Buffer receives 1 frame. Stream read from the buffer.
+TEST_F(QuicSpdyStreamBodyBufferTest, ReadSingleBody) {
+  testing::InSequence seq;
+  QuicString body(1024, 'a');
+  std::unique_ptr<char[]> buffer;
+  QuicByteCount header_length =
+      encoder_.SerializeDataFrameHeader(body.length(), &buffer);
+  QuicString header = QuicString(buffer.get(), header_length);
+  Http3FrameLengths lengths(header_length, 1024);
+  QuicString data = header + body;
+  QuicStreamFrame frame(1, false, 0, data);
+  sequencer_.OnStreamFrame(frame);
+  body_buffer_.OnDataHeader(lengths);
+  body_buffer_.OnDataPayload(QuicStringPiece(body));
+
+  EXPECT_CALL(stream_, AddBytesConsumed(header_length));
+  EXPECT_CALL(stream_, AddBytesConsumed(1024));
+
+  char base[1024];
+  iovec iov = {&base[0], 1024};
+  EXPECT_EQ(1024u, body_buffer_.ReadBody(&iov, 1));
+  EXPECT_EQ(1024u, iov.iov_len);
+  EXPECT_EQ(body,
+            QuicStringPiece(static_cast<const char*>(iov.iov_base), 1024));
+}
+
+// Buffer receives 2 frames, stream read from the buffer multiple times.
+TEST_F(QuicSpdyStreamBodyBufferTest, ReadMultipleBody) {
+  testing::InSequence seq;
+  // 1st frame.
+  QuicString body1(1024, 'a');
+  std::unique_ptr<char[]> buffer;
+  QuicByteCount header_length1 =
+      encoder_.SerializeDataFrameHeader(body1.length(), &buffer);
+  QuicString header1 = QuicString(buffer.get(), header_length1);
+  Http3FrameLengths lengths1(header_length1, 1024);
+  QuicString data1 = header1 + body1;
+  QuicStreamFrame frame1(1, false, 0, data1);
+  sequencer_.OnStreamFrame(frame1);
+  body_buffer_.OnDataHeader(lengths1);
+  body_buffer_.OnDataPayload(QuicStringPiece(body1));
+
+  // 2nd frame.
+  QuicString body2(2048, 'b');
+  QuicByteCount header_length2 =
+      encoder_.SerializeDataFrameHeader(body2.length(), &buffer);
+  QuicString header2 = QuicString(buffer.get(), header_length2);
+  Http3FrameLengths lengths2(header_length2, 2048);
+  QuicString data2 = header2 + body2;
+  QuicStreamFrame frame2(1, false, data1.length(), data2);
+  sequencer_.OnStreamFrame(frame2);
+  body_buffer_.OnDataHeader(lengths2);
+  body_buffer_.OnDataPayload(QuicStringPiece(body2));
+
+  // First read of 512 bytes.
+  EXPECT_CALL(stream_, AddBytesConsumed(header_length1));
+  EXPECT_CALL(stream_, AddBytesConsumed(512));
+  char base[512];
+  iovec iov = {&base[0], 512};
+  EXPECT_EQ(512u, body_buffer_.ReadBody(&iov, 1));
+  EXPECT_EQ(512u, iov.iov_len);
+  EXPECT_EQ(body1.substr(0, 512),
+            QuicStringPiece(static_cast<const char*>(iov.iov_base), 512));
+
+  // Second read of 2048 bytes.
+  EXPECT_CALL(stream_, AddBytesConsumed(header_length2));
+  EXPECT_CALL(stream_, AddBytesConsumed(2048));
+  char base2[2048];
+  iovec iov2 = {&base2[0], 2048};
+  EXPECT_EQ(2048u, body_buffer_.ReadBody(&iov2, 1));
+  EXPECT_EQ(2048u, iov2.iov_len);
+  EXPECT_EQ(body1.substr(512, 512) + body2.substr(0, 1536),
+            QuicStringPiece(static_cast<const char*>(iov2.iov_base), 2048));
+
+  // Third read of the rest 512 bytes.
+  EXPECT_CALL(stream_, AddBytesConsumed(512));
+  char base3[512];
+  iovec iov3 = {&base3[0], 512};
+  EXPECT_EQ(512u, body_buffer_.ReadBody(&iov3, 1));
+  EXPECT_EQ(512u, iov3.iov_len);
+  EXPECT_EQ(body2.substr(1536, 512),
+            QuicStringPiece(static_cast<const char*>(iov3.iov_base), 512));
+}
+
+}  // anonymous namespace
+
+}  // namespace test
+
+}  // namespace quic
diff --git a/quic/core/http/quic_spdy_stream_test.cc b/quic/core/http/quic_spdy_stream_test.cc
new file mode 100644
index 0000000..1aabe0e
--- /dev/null
+++ b/quic/core/http/quic_spdy_stream_test.cc
@@ -0,0 +1,1518 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/third_party/quiche/src/quic/core/http/quic_spdy_stream.h"
+
+#include <memory>
+#include <utility>
+
+#include "net/third_party/quiche/src/quic/core/http/http_encoder.h"
+#include "net/third_party/quiche/src/quic/core/http/spdy_utils.h"
+#include "net/third_party/quiche/src/quic/core/quic_connection.h"
+#include "net/third_party/quiche/src/quic/core/quic_stream_sequencer_buffer.h"
+#include "net/third_party/quiche/src/quic/core/quic_utils.h"
+#include "net/third_party/quiche/src/quic/core/quic_versions.h"
+#include "net/third_party/quiche/src/quic/core/quic_write_blocked_list.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_arraysize.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_expect_bug.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_map_util.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_ptr_util.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_string.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_string_piece.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_test.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_text_utils.h"
+#include "net/third_party/quiche/src/quic/test_tools/quic_flow_controller_peer.h"
+#include "net/third_party/quiche/src/quic/test_tools/quic_session_peer.h"
+#include "net/third_party/quiche/src/quic/test_tools/quic_spdy_session_peer.h"
+#include "net/third_party/quiche/src/quic/test_tools/quic_spdy_stream_peer.h"
+#include "net/third_party/quiche/src/quic/test_tools/quic_stream_peer.h"
+#include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h"
+
+using spdy::kV3HighestPriority;
+using spdy::kV3LowestPriority;
+using spdy::SpdyHeaderBlock;
+using spdy::SpdyPriority;
+using testing::_;
+using testing::AtLeast;
+using testing::Invoke;
+using testing::Return;
+using testing::StrictMock;
+
+namespace quic {
+namespace test {
+namespace {
+
+const bool kShouldProcessData = true;
+
+class TestStream : public QuicSpdyStream {
+ public:
+  TestStream(QuicStreamId id,
+             QuicSpdySession* session,
+             bool should_process_data)
+      : QuicSpdyStream(id, session, BIDIRECTIONAL),
+        should_process_data_(should_process_data) {}
+  ~TestStream() override = default;
+
+  using QuicSpdyStream::set_ack_listener;
+  using QuicStream::CloseWriteSide;
+  using QuicStream::WriteOrBufferData;
+
+  void OnBodyAvailable() override {
+    if (!should_process_data_) {
+      return;
+    }
+    char buffer[2048];
+    struct iovec vec;
+    vec.iov_base = buffer;
+    vec.iov_len = QUIC_ARRAYSIZE(buffer);
+    size_t bytes_read = Readv(&vec, 1);
+    data_ += QuicString(buffer, bytes_read);
+  }
+
+  MOCK_METHOD1(WriteHeadersMock, void(bool fin));
+
+  size_t WriteHeadersImpl(spdy::SpdyHeaderBlock header_block,
+                          bool fin,
+                          QuicReferenceCountedPointer<QuicAckListenerInterface>
+                              ack_listener) override {
+    saved_headers_ = std::move(header_block);
+    WriteHeadersMock(fin);
+    return 0;
+  }
+
+  const QuicString& data() const { return data_; }
+  const spdy::SpdyHeaderBlock& saved_headers() const { return saved_headers_; }
+
+ private:
+  bool should_process_data_;
+  spdy::SpdyHeaderBlock saved_headers_;
+  QuicString data_;
+};
+
+class TestMockUpdateStreamSession : public MockQuicSpdySession {
+ public:
+  explicit TestMockUpdateStreamSession(QuicConnection* connection)
+      : MockQuicSpdySession(connection) {}
+
+  void UpdateStreamPriority(QuicStreamId id, SpdyPriority priority) override {
+    EXPECT_EQ(id, expected_stream_->id());
+    EXPECT_EQ(expected_priority_, priority);
+    EXPECT_EQ(expected_priority_, expected_stream_->priority());
+  }
+
+  void SetExpectedStream(QuicSpdyStream* stream) { expected_stream_ = stream; }
+  void SetExpectedPriority(SpdyPriority priority) {
+    expected_priority_ = priority;
+  }
+
+ private:
+  QuicSpdyStream* expected_stream_;
+  SpdyPriority expected_priority_;
+};
+
+class QuicSpdyStreamTest : public QuicTestWithParam<ParsedQuicVersion> {
+ public:
+  QuicSpdyStreamTest() {
+    headers_[":host"] = "www.google.com";
+    headers_[":path"] = "/index.hml";
+    headers_[":scheme"] = "https";
+    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 ";
+  }
+
+  void Initialize(bool stream_should_process_data) {
+    connection_ = new StrictMock<MockQuicConnection>(
+        &helper_, &alarm_factory_, Perspective::IS_SERVER,
+        SupportedVersions(GetParam()));
+    session_ = QuicMakeUnique<StrictMock<MockQuicSpdySession>>(connection_);
+    session_->Initialize();
+    ON_CALL(*session_, WritevData(_, _, _, _, _))
+        .WillByDefault(Invoke(MockQuicSession::ConsumeData));
+
+    stream_ =
+        new StrictMock<TestStream>(GetNthClientInitiatedBidirectionalId(0),
+                                   session_.get(), stream_should_process_data);
+    session_->ActivateStream(QuicWrapUnique(stream_));
+    stream2_ =
+        new StrictMock<TestStream>(GetNthClientInitiatedBidirectionalId(1),
+                                   session_.get(), stream_should_process_data);
+    session_->ActivateStream(QuicWrapUnique(stream2_));
+  }
+
+  QuicHeaderList ProcessHeaders(bool fin, const SpdyHeaderBlock& headers) {
+    QuicHeaderList h = AsHeaderList(headers);
+    stream_->OnStreamHeaderList(fin, h.uncompressed_header_bytes(), h);
+    return h;
+  }
+
+  QuicStreamId GetNthClientInitiatedBidirectionalId(int n) {
+    return GetNthClientInitiatedBidirectionalStreamId(
+        connection_->transport_version(), n);
+  }
+
+  bool HasFrameHeader() const {
+    return VersionHasDataFrameHeader(connection_->transport_version());
+  }
+
+ protected:
+  MockQuicConnectionHelper helper_;
+  MockAlarmFactory alarm_factory_;
+  MockQuicConnection* connection_;
+  std::unique_ptr<MockQuicSpdySession> session_;
+
+  // Owned by the |session_|.
+  TestStream* stream_;
+  TestStream* stream2_;
+
+  SpdyHeaderBlock headers_;
+
+  HttpEncoder encoder_;
+};
+
+INSTANTIATE_TEST_SUITE_P(Tests, QuicSpdyStreamTest,
+                         ::testing::ValuesIn(AllSupportedVersions()));
+
+TEST_P(QuicSpdyStreamTest, ProcessHeaderList) {
+  Initialize(kShouldProcessData);
+
+  stream_->OnStreamHeadersPriority(kV3HighestPriority);
+  ProcessHeaders(false, headers_);
+  EXPECT_EQ("", stream_->data());
+  EXPECT_FALSE(stream_->header_list().empty());
+  EXPECT_FALSE(stream_->IsDoneReading());
+}
+
+TEST_P(QuicSpdyStreamTest, ProcessTooLargeHeaderList) {
+  Initialize(kShouldProcessData);
+
+  QuicHeaderList headers;
+  stream_->OnStreamHeadersPriority(kV3HighestPriority);
+
+  EXPECT_CALL(*session_,
+              SendRstStream(stream_->id(), QUIC_HEADERS_TOO_LARGE, 0));
+  stream_->OnStreamHeaderList(false, 1 << 20, headers);
+  EXPECT_EQ(QUIC_HEADERS_TOO_LARGE, stream_->stream_error());
+}
+
+TEST_P(QuicSpdyStreamTest, ProcessHeaderListWithFin) {
+  Initialize(kShouldProcessData);
+
+  size_t total_bytes = 0;
+  QuicHeaderList headers;
+  for (auto p : headers_) {
+    headers.OnHeader(p.first, p.second);
+    total_bytes += p.first.size() + p.second.size();
+  }
+  stream_->OnStreamHeadersPriority(kV3HighestPriority);
+  stream_->OnStreamHeaderList(true, total_bytes, headers);
+  EXPECT_EQ("", stream_->data());
+  EXPECT_FALSE(stream_->header_list().empty());
+  EXPECT_FALSE(stream_->IsDoneReading());
+  EXPECT_TRUE(stream_->HasFinalReceivedByteOffset());
+}
+
+TEST_P(QuicSpdyStreamTest, ParseHeaderStatusCode) {
+  // A valid status code should be 3-digit integer. The first digit should be in
+  // the range of [1, 5]. All the others are invalid.
+  Initialize(kShouldProcessData);
+  int status_code = 0;
+
+  // Valid status codes.
+  headers_[":status"] = "404";
+  EXPECT_TRUE(stream_->ParseHeaderStatusCode(headers_, &status_code));
+  EXPECT_EQ(404, status_code);
+
+  headers_[":status"] = "100";
+  EXPECT_TRUE(stream_->ParseHeaderStatusCode(headers_, &status_code));
+  EXPECT_EQ(100, status_code);
+
+  headers_[":status"] = "599";
+  EXPECT_TRUE(stream_->ParseHeaderStatusCode(headers_, &status_code));
+  EXPECT_EQ(599, status_code);
+
+  // Invalid status codes.
+  headers_[":status"] = "010";
+  EXPECT_FALSE(stream_->ParseHeaderStatusCode(headers_, &status_code));
+
+  headers_[":status"] = "600";
+  EXPECT_FALSE(stream_->ParseHeaderStatusCode(headers_, &status_code));
+
+  headers_[":status"] = "200 ok";
+  EXPECT_FALSE(stream_->ParseHeaderStatusCode(headers_, &status_code));
+
+  headers_[":status"] = "2000";
+  EXPECT_FALSE(stream_->ParseHeaderStatusCode(headers_, &status_code));
+
+  headers_[":status"] = "+200";
+  EXPECT_FALSE(stream_->ParseHeaderStatusCode(headers_, &status_code));
+
+  headers_[":status"] = "+20";
+  EXPECT_FALSE(stream_->ParseHeaderStatusCode(headers_, &status_code));
+
+  headers_[":status"] = "-10";
+  EXPECT_FALSE(stream_->ParseHeaderStatusCode(headers_, &status_code));
+
+  headers_[":status"] = "-100";
+  EXPECT_FALSE(stream_->ParseHeaderStatusCode(headers_, &status_code));
+
+  // Leading or trailing spaces are also invalid.
+  headers_[":status"] = " 200";
+  EXPECT_FALSE(stream_->ParseHeaderStatusCode(headers_, &status_code));
+
+  headers_[":status"] = "200 ";
+  EXPECT_FALSE(stream_->ParseHeaderStatusCode(headers_, &status_code));
+
+  headers_[":status"] = " 200 ";
+  EXPECT_FALSE(stream_->ParseHeaderStatusCode(headers_, &status_code));
+
+  headers_[":status"] = "  ";
+  EXPECT_FALSE(stream_->ParseHeaderStatusCode(headers_, &status_code));
+}
+
+TEST_P(QuicSpdyStreamTest, MarkHeadersConsumed) {
+  Initialize(kShouldProcessData);
+
+  QuicString body = "this is the body";
+  QuicHeaderList headers = ProcessHeaders(false, headers_);
+  EXPECT_EQ(headers, stream_->header_list());
+
+  stream_->ConsumeHeaderList();
+  EXPECT_EQ(QuicHeaderList(), stream_->header_list());
+}
+
+TEST_P(QuicSpdyStreamTest, ProcessHeadersAndBody) {
+  Initialize(kShouldProcessData);
+
+  QuicString body = "this is the body";
+  std::unique_ptr<char[]> buffer;
+  QuicByteCount header_length =
+      encoder_.SerializeDataFrameHeader(body.length(), &buffer);
+  QuicString header = QuicString(buffer.get(), header_length);
+  QuicString data = HasFrameHeader() ? header + body : body;
+
+  EXPECT_EQ("", stream_->data());
+  QuicHeaderList headers = ProcessHeaders(false, headers_);
+  EXPECT_EQ(headers, stream_->header_list());
+  stream_->ConsumeHeaderList();
+  QuicStreamFrame frame(GetNthClientInitiatedBidirectionalId(0), false, 0,
+                        QuicStringPiece(data));
+  stream_->OnStreamFrame(frame);
+  EXPECT_EQ(QuicHeaderList(), stream_->header_list());
+  EXPECT_EQ(body, stream_->data());
+}
+
+TEST_P(QuicSpdyStreamTest, ProcessHeadersAndBodyFragments) {
+  Initialize(kShouldProcessData);
+  QuicString body = "this is the body";
+  std::unique_ptr<char[]> buffer;
+  QuicByteCount header_length =
+      encoder_.SerializeDataFrameHeader(body.length(), &buffer);
+  QuicString header = QuicString(buffer.get(), header_length);
+  QuicString data = HasFrameHeader() ? header + body : body;
+
+  for (size_t fragment_size = 1; fragment_size < data.size(); ++fragment_size) {
+    Initialize(kShouldProcessData);
+    QuicHeaderList headers = ProcessHeaders(false, headers_);
+    ASSERT_EQ(headers, stream_->header_list());
+    stream_->ConsumeHeaderList();
+    for (size_t offset = 0; offset < data.size(); offset += fragment_size) {
+      size_t remaining_data = data.size() - offset;
+      QuicStringPiece fragment(data.data() + offset,
+                               std::min(fragment_size, remaining_data));
+      QuicStreamFrame frame(GetNthClientInitiatedBidirectionalId(0), false,
+                            offset, QuicStringPiece(fragment));
+      stream_->OnStreamFrame(frame);
+    }
+    ASSERT_EQ(body, stream_->data()) << "fragment_size: " << fragment_size;
+  }
+}
+
+TEST_P(QuicSpdyStreamTest, ProcessHeadersAndBodyFragmentsSplit) {
+  Initialize(kShouldProcessData);
+  QuicString body = "this is the body";
+  std::unique_ptr<char[]> buffer;
+  QuicByteCount header_length =
+      encoder_.SerializeDataFrameHeader(body.length(), &buffer);
+  QuicString header = QuicString(buffer.get(), header_length);
+  QuicString data = HasFrameHeader() ? header + body : body;
+
+  for (size_t split_point = 1; split_point < data.size() - 1; ++split_point) {
+    Initialize(kShouldProcessData);
+    QuicHeaderList headers = ProcessHeaders(false, headers_);
+    ASSERT_EQ(headers, stream_->header_list());
+    stream_->ConsumeHeaderList();
+
+    QuicStringPiece fragment1(data.data(), split_point);
+    QuicStreamFrame frame1(GetNthClientInitiatedBidirectionalId(0), false, 0,
+                           QuicStringPiece(fragment1));
+    stream_->OnStreamFrame(frame1);
+
+    QuicStringPiece fragment2(data.data() + split_point,
+                              data.size() - split_point);
+    QuicStreamFrame frame2(GetNthClientInitiatedBidirectionalId(0), false,
+                           split_point, QuicStringPiece(fragment2));
+    stream_->OnStreamFrame(frame2);
+
+    ASSERT_EQ(body, stream_->data()) << "split_point: " << split_point;
+  }
+}
+
+TEST_P(QuicSpdyStreamTest, ProcessHeadersAndBodyReadv) {
+  Initialize(!kShouldProcessData);
+
+  QuicString body = "this is the body";
+  std::unique_ptr<char[]> buf;
+  QuicByteCount header_length =
+      encoder_.SerializeDataFrameHeader(body.length(), &buf);
+  QuicString header = QuicString(buf.get(), header_length);
+  QuicString data = HasFrameHeader() ? header + body : body;
+
+  ProcessHeaders(false, headers_);
+  QuicStreamFrame frame(GetNthClientInitiatedBidirectionalId(0), false, 0,
+                        QuicStringPiece(data));
+  stream_->OnStreamFrame(frame);
+  stream_->ConsumeHeaderList();
+
+  char buffer[2048];
+  ASSERT_LT(data.length(), QUIC_ARRAYSIZE(buffer));
+  struct iovec vec;
+  vec.iov_base = buffer;
+  vec.iov_len = QUIC_ARRAYSIZE(buffer);
+
+  size_t bytes_read = stream_->Readv(&vec, 1);
+  EXPECT_EQ(body.length(), bytes_read);
+  EXPECT_EQ(body, QuicString(buffer, bytes_read));
+}
+
+TEST_P(QuicSpdyStreamTest, ProcessHeadersAndLargeBodySmallReadv) {
+  Initialize(kShouldProcessData);
+  QuicString body(12 * 1024, 'a');
+  std::unique_ptr<char[]> buf;
+  QuicByteCount header_length =
+      encoder_.SerializeDataFrameHeader(body.length(), &buf);
+  QuicString header = QuicString(buf.get(), header_length);
+  QuicString data = HasFrameHeader() ? header + body : body;
+  ProcessHeaders(false, headers_);
+  QuicStreamFrame frame(GetNthClientInitiatedBidirectionalId(0), false, 0,
+                        QuicStringPiece(data));
+  stream_->OnStreamFrame(frame);
+  stream_->ConsumeHeaderList();
+  char buffer[2048];
+  char buffer2[2048];
+  struct iovec vec[2];
+  vec[0].iov_base = buffer;
+  vec[0].iov_len = QUIC_ARRAYSIZE(buffer);
+  vec[1].iov_base = buffer2;
+  vec[1].iov_len = QUIC_ARRAYSIZE(buffer2);
+  size_t bytes_read = stream_->Readv(vec, 2);
+  EXPECT_EQ(2048u * 2, bytes_read);
+  EXPECT_EQ(body.substr(0, 2048), QuicString(buffer, 2048));
+  EXPECT_EQ(body.substr(2048, 2048), QuicString(buffer2, 2048));
+}
+
+TEST_P(QuicSpdyStreamTest, ProcessHeadersAndBodyMarkConsumed) {
+  Initialize(!kShouldProcessData);
+
+  QuicString body = "this is the body";
+  std::unique_ptr<char[]> buf;
+  QuicByteCount header_length =
+      encoder_.SerializeDataFrameHeader(body.length(), &buf);
+  QuicString header = QuicString(buf.get(), header_length);
+  QuicString data = HasFrameHeader() ? header + body : body;
+
+  ProcessHeaders(false, headers_);
+  QuicStreamFrame frame(GetNthClientInitiatedBidirectionalId(0), false, 0,
+                        QuicStringPiece(data));
+  stream_->OnStreamFrame(frame);
+  stream_->ConsumeHeaderList();
+
+  struct iovec vec;
+
+  EXPECT_EQ(1, stream_->GetReadableRegions(&vec, 1));
+  EXPECT_EQ(body.length(), vec.iov_len);
+  EXPECT_EQ(body, QuicString(static_cast<char*>(vec.iov_base), vec.iov_len));
+
+  stream_->MarkConsumed(body.length());
+  EXPECT_EQ(data.length(), stream_->flow_controller()->bytes_consumed());
+}
+
+TEST_P(QuicSpdyStreamTest, ProcessHeadersAndConsumeMultipleBody) {
+  Initialize(!kShouldProcessData);
+  QuicString body1 = "this is body 1";
+  QuicString body2 = "body 2";
+  std::unique_ptr<char[]> buf;
+  QuicByteCount header_length =
+      encoder_.SerializeDataFrameHeader(body1.length(), &buf);
+  QuicString header = QuicString(buf.get(), header_length);
+  QuicString data1 = HasFrameHeader() ? header + body1 : body1;
+  header_length = encoder_.SerializeDataFrameHeader(body2.length(), &buf);
+  QuicString data2 = HasFrameHeader() ? header + body2 : body2;
+
+  ProcessHeaders(false, headers_);
+  QuicStreamFrame frame1(GetNthClientInitiatedBidirectionalId(0), false, 0,
+                         QuicStringPiece(data1));
+  QuicStreamFrame frame2(GetNthClientInitiatedBidirectionalId(0), false,
+                         data1.length(), QuicStringPiece(data2));
+  stream_->OnStreamFrame(frame1);
+  stream_->OnStreamFrame(frame2);
+  stream_->ConsumeHeaderList();
+
+  stream_->MarkConsumed(body1.length() + body2.length());
+  EXPECT_EQ(data1.length() + data2.length(),
+            stream_->flow_controller()->bytes_consumed());
+}
+
+TEST_P(QuicSpdyStreamTest, ProcessHeadersAndBodyIncrementalReadv) {
+  Initialize(!kShouldProcessData);
+
+  QuicString body = "this is the body";
+  std::unique_ptr<char[]> buf;
+  QuicByteCount header_length =
+      encoder_.SerializeDataFrameHeader(body.length(), &buf);
+  QuicString header = QuicString(buf.get(), header_length);
+  QuicString data = HasFrameHeader() ? header + body : body;
+
+  ProcessHeaders(false, headers_);
+  QuicStreamFrame frame(GetNthClientInitiatedBidirectionalId(0), false, 0,
+                        QuicStringPiece(data));
+  stream_->OnStreamFrame(frame);
+  stream_->ConsumeHeaderList();
+
+  char buffer[1];
+  struct iovec vec;
+  vec.iov_base = buffer;
+  vec.iov_len = QUIC_ARRAYSIZE(buffer);
+
+  for (size_t i = 0; i < body.length(); ++i) {
+    size_t bytes_read = stream_->Readv(&vec, 1);
+    ASSERT_EQ(1u, bytes_read);
+    EXPECT_EQ(body.data()[i], buffer[0]);
+  }
+}
+
+TEST_P(QuicSpdyStreamTest, ProcessHeadersUsingReadvWithMultipleIovecs) {
+  Initialize(!kShouldProcessData);
+
+  QuicString body = "this is the body";
+  std::unique_ptr<char[]> buf;
+  QuicByteCount header_length =
+      encoder_.SerializeDataFrameHeader(body.length(), &buf);
+  QuicString header = QuicString(buf.get(), header_length);
+  QuicString data = HasFrameHeader() ? header + body : body;
+
+  ProcessHeaders(false, headers_);
+  QuicStreamFrame frame(GetNthClientInitiatedBidirectionalId(0), false, 0,
+                        QuicStringPiece(data));
+  stream_->OnStreamFrame(frame);
+  stream_->ConsumeHeaderList();
+
+  char buffer1[1];
+  char buffer2[1];
+  struct iovec vec[2];
+  vec[0].iov_base = buffer1;
+  vec[0].iov_len = QUIC_ARRAYSIZE(buffer1);
+  vec[1].iov_base = buffer2;
+  vec[1].iov_len = QUIC_ARRAYSIZE(buffer2);
+
+  for (size_t i = 0; i < body.length(); i += 2) {
+    size_t bytes_read = stream_->Readv(vec, 2);
+    ASSERT_EQ(2u, bytes_read) << i;
+    ASSERT_EQ(body.data()[i], buffer1[0]) << i;
+    ASSERT_EQ(body.data()[i + 1], buffer2[0]) << i;
+  }
+}
+
+TEST_P(QuicSpdyStreamTest, StreamFlowControlBlocked) {
+  testing::InSequence seq;
+  // Tests that we send a BLOCKED frame to the peer when we attempt to write,
+  // but are flow control blocked.
+  Initialize(kShouldProcessData);
+
+  // Set a small flow control limit.
+  const uint64_t kWindow = 36;
+  QuicFlowControllerPeer::SetSendWindowOffset(stream_->flow_controller(),
+                                              kWindow);
+  EXPECT_EQ(kWindow, QuicFlowControllerPeer::SendWindowOffset(
+                         stream_->flow_controller()));
+
+  // Try to send more data than the flow control limit allows.
+  const uint64_t kOverflow = 15;
+  QuicString body(kWindow + kOverflow, 'a');
+
+  const uint64_t kHeaderLength = HasFrameHeader() ? 2 : 0;
+  if (HasFrameHeader()) {
+    EXPECT_CALL(*session_, WritevData(_, _, kHeaderLength, _, NO_FIN));
+  }
+  EXPECT_CALL(*session_, WritevData(_, _, _, _, _))
+      .WillOnce(Return(QuicConsumedData(kWindow - kHeaderLength, true)));
+  EXPECT_CALL(*connection_, SendControlFrame(_));
+  stream_->WriteOrBufferBody(body, false);
+
+  // Should have sent as much as possible, resulting in no send window left.
+  EXPECT_EQ(0u,
+            QuicFlowControllerPeer::SendWindowSize(stream_->flow_controller()));
+
+  // And we should have queued the overflowed data.
+  EXPECT_EQ(kOverflow + kHeaderLength,
+            QuicStreamPeer::SizeOfQueuedData(stream_));
+}
+
+TEST_P(QuicSpdyStreamTest, StreamFlowControlNoWindowUpdateIfNotConsumed) {
+  // The flow control receive window decreases whenever we add new bytes to the
+  // sequencer, whether they are consumed immediately or buffered. However we
+  // only send WINDOW_UPDATE frames based on increasing number of bytes
+  // consumed.
+
+  // Don't process data - it will be buffered instead.
+  Initialize(!kShouldProcessData);
+
+  // Expect no WINDOW_UPDATE frames to be sent.
+  EXPECT_CALL(*connection_, SendWindowUpdate(_, _)).Times(0);
+
+  // Set a small flow control receive window.
+  const uint64_t kWindow = 36;
+  QuicFlowControllerPeer::SetReceiveWindowOffset(stream_->flow_controller(),
+                                                 kWindow);
+  QuicFlowControllerPeer::SetMaxReceiveWindow(stream_->flow_controller(),
+                                              kWindow);
+  EXPECT_EQ(kWindow, QuicFlowControllerPeer::ReceiveWindowOffset(
+                         stream_->flow_controller()));
+
+  // Stream receives enough data to fill a fraction of the receive window.
+  QuicString body(kWindow / 3, 'a');
+  QuicByteCount header_length = 0;
+  QuicString data;
+
+  if (HasFrameHeader()) {
+    std::unique_ptr<char[]> buffer;
+    header_length = encoder_.SerializeDataFrameHeader(body.length(), &buffer);
+    QuicString header = QuicString(buffer.get(), header_length);
+    data = header + body;
+  } else {
+    data = body;
+  }
+
+  ProcessHeaders(false, headers_);
+
+  QuicStreamFrame frame1(GetNthClientInitiatedBidirectionalId(0), false, 0,
+                         QuicStringPiece(data));
+  stream_->OnStreamFrame(frame1);
+  EXPECT_EQ(
+      kWindow - (kWindow / 3) - header_length,
+      QuicFlowControllerPeer::ReceiveWindowSize(stream_->flow_controller()));
+
+  // Now receive another frame which results in the receive window being over
+  // half full. This should all be buffered, decreasing the receive window but
+  // not sending WINDOW_UPDATE.
+  QuicStreamFrame frame2(GetNthClientInitiatedBidirectionalId(0), false,
+                         kWindow / 3 + header_length, QuicStringPiece(data));
+  stream_->OnStreamFrame(frame2);
+  EXPECT_EQ(
+      kWindow - (2 * kWindow / 3) - 2 * header_length,
+      QuicFlowControllerPeer::ReceiveWindowSize(stream_->flow_controller()));
+}
+
+TEST_P(QuicSpdyStreamTest, StreamFlowControlWindowUpdate) {
+  // Tests that on receipt of data, the stream updates its receive window offset
+  // appropriately, and sends WINDOW_UPDATE frames when its receive window drops
+  // too low.
+  Initialize(kShouldProcessData);
+
+  // Set a small flow control limit.
+  const uint64_t kWindow = 36;
+  QuicFlowControllerPeer::SetReceiveWindowOffset(stream_->flow_controller(),
+                                                 kWindow);
+  QuicFlowControllerPeer::SetMaxReceiveWindow(stream_->flow_controller(),
+                                              kWindow);
+  EXPECT_EQ(kWindow, QuicFlowControllerPeer::ReceiveWindowOffset(
+                         stream_->flow_controller()));
+
+  // Stream receives enough data to fill a fraction of the receive window.
+  QuicString body(kWindow / 3, 'a');
+  QuicByteCount header_length = 0;
+  QuicString data;
+
+  if (HasFrameHeader()) {
+    std::unique_ptr<char[]> buffer;
+    header_length = encoder_.SerializeDataFrameHeader(body.length(), &buffer);
+    QuicString header = QuicString(buffer.get(), header_length);
+    data = header + body;
+  } else {
+    data = body;
+  }
+
+  ProcessHeaders(false, headers_);
+  stream_->ConsumeHeaderList();
+
+  QuicStreamFrame frame1(GetNthClientInitiatedBidirectionalId(0), false, 0,
+                         QuicStringPiece(data));
+  stream_->OnStreamFrame(frame1);
+  EXPECT_EQ(
+      kWindow - (kWindow / 3) - header_length,
+      QuicFlowControllerPeer::ReceiveWindowSize(stream_->flow_controller()));
+
+  // Now receive another frame which results in the receive window being over
+  // half full.  This will trigger the stream to increase its receive window
+  // offset and send a WINDOW_UPDATE. The result will be again an available
+  // window of kWindow bytes.
+  QuicStreamFrame frame2(GetNthClientInitiatedBidirectionalId(0), false,
+                         kWindow / 3 + header_length, QuicStringPiece(data));
+  EXPECT_CALL(*connection_, SendControlFrame(_));
+  stream_->OnStreamFrame(frame2);
+  EXPECT_EQ(kWindow, QuicFlowControllerPeer::ReceiveWindowSize(
+                         stream_->flow_controller()));
+}
+
+TEST_P(QuicSpdyStreamTest, ConnectionFlowControlWindowUpdate) {
+  // Tests that on receipt of data, the connection updates its receive window
+  // offset appropriately, and sends WINDOW_UPDATE frames when its receive
+  // window drops too low.
+  Initialize(kShouldProcessData);
+
+  // Set a small flow control limit for streams and connection.
+  const uint64_t kWindow = 36;
+  QuicFlowControllerPeer::SetReceiveWindowOffset(stream_->flow_controller(),
+                                                 kWindow);
+  QuicFlowControllerPeer::SetMaxReceiveWindow(stream_->flow_controller(),
+                                              kWindow);
+  QuicFlowControllerPeer::SetReceiveWindowOffset(stream2_->flow_controller(),
+                                                 kWindow);
+  QuicFlowControllerPeer::SetMaxReceiveWindow(stream2_->flow_controller(),
+                                              kWindow);
+  QuicFlowControllerPeer::SetReceiveWindowOffset(session_->flow_controller(),
+                                                 kWindow);
+  QuicFlowControllerPeer::SetMaxReceiveWindow(session_->flow_controller(),
+                                              kWindow);
+
+  // Supply headers to both streams so that they are happy to receive data.
+  auto headers = AsHeaderList(headers_);
+  stream_->OnStreamHeaderList(false, headers.uncompressed_header_bytes(),
+                              headers);
+  stream_->ConsumeHeaderList();
+  stream2_->OnStreamHeaderList(false, headers.uncompressed_header_bytes(),
+                               headers);
+  stream2_->ConsumeHeaderList();
+
+  // Each stream gets a quarter window of data. This should not trigger a
+  // WINDOW_UPDATE for either stream, nor for the connection.
+  QuicByteCount header_length = 0;
+  QuicString body;
+  QuicString data;
+  QuicString data2;
+  QuicString body2(1, 'a');
+
+  if (HasFrameHeader()) {
+    body = QuicString(kWindow / 4 - 2, 'a');
+    std::unique_ptr<char[]> buffer;
+    header_length = encoder_.SerializeDataFrameHeader(body.length(), &buffer);
+    QuicString header = QuicString(buffer.get(), header_length);
+    data = header + body;
+    std::unique_ptr<char[]> buffer2;
+    QuicByteCount header_length2 =
+        encoder_.SerializeDataFrameHeader(body2.length(), &buffer2);
+    QuicString header2 = QuicString(buffer2.get(), header_length2);
+    data2 = header2 + body2;
+  } else {
+    body = QuicString(kWindow / 4, 'a');
+    data = body;
+    data2 = body2;
+  }
+
+  QuicStreamFrame frame1(GetNthClientInitiatedBidirectionalId(0), false, 0,
+                         QuicStringPiece(data));
+  stream_->OnStreamFrame(frame1);
+  QuicStreamFrame frame2(GetNthClientInitiatedBidirectionalId(1), false, 0,
+                         QuicStringPiece(data));
+  stream2_->OnStreamFrame(frame2);
+
+  // Now receive a further single byte on one stream - again this does not
+  // trigger a stream WINDOW_UPDATE, but now the connection flow control window
+  // is over half full and thus a connection WINDOW_UPDATE is sent.
+  EXPECT_CALL(*connection_, SendControlFrame(_));
+  QuicStreamFrame frame3(GetNthClientInitiatedBidirectionalId(0), false,
+                         body.length() + header_length, QuicStringPiece(data2));
+  stream_->OnStreamFrame(frame3);
+}
+
+TEST_P(QuicSpdyStreamTest, StreamFlowControlViolation) {
+  // Tests that on if the peer sends too much data (i.e. violates the flow
+  // control protocol), then we terminate the connection.
+
+  // Stream should not process data, so that data gets buffered in the
+  // sequencer, triggering flow control limits.
+  Initialize(!kShouldProcessData);
+
+  // Set a small flow control limit.
+  const uint64_t kWindow = 50;
+  QuicFlowControllerPeer::SetReceiveWindowOffset(stream_->flow_controller(),
+                                                 kWindow);
+
+  ProcessHeaders(false, headers_);
+
+  // Receive data to overflow the window, violating flow control.
+  QuicString body(kWindow + 1, 'a');
+  std::unique_ptr<char[]> buf;
+  QuicByteCount header_length =
+      encoder_.SerializeDataFrameHeader(body.length(), &buf);
+  QuicString header = QuicString(buf.get(), header_length);
+  QuicString data = HasFrameHeader() ? header + body : body;
+  QuicStreamFrame frame(GetNthClientInitiatedBidirectionalId(0), false, 0,
+                        QuicStringPiece(data));
+  EXPECT_CALL(*connection_,
+              CloseConnection(QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA, _, _));
+  stream_->OnStreamFrame(frame);
+}
+
+TEST_P(QuicSpdyStreamTest, TestHandlingQuicRstStreamNoError) {
+  Initialize(kShouldProcessData);
+  ProcessHeaders(false, headers_);
+
+  stream_->OnStreamReset(QuicRstStreamFrame(
+      kInvalidControlFrameId, stream_->id(), QUIC_STREAM_NO_ERROR, 0));
+  EXPECT_TRUE(stream_->write_side_closed());
+  EXPECT_FALSE(stream_->reading_stopped());
+}
+
+TEST_P(QuicSpdyStreamTest, ConnectionFlowControlViolation) {
+  // Tests that on if the peer sends too much data (i.e. violates the flow
+  // control protocol), at the connection level (rather than the stream level)
+  // then we terminate the connection.
+
+  // Stream should not process data, so that data gets buffered in the
+  // sequencer, triggering flow control limits.
+  Initialize(!kShouldProcessData);
+
+  // Set a small flow control window on streams, and connection.
+  const uint64_t kStreamWindow = 50;
+  const uint64_t kConnectionWindow = 10;
+  QuicFlowControllerPeer::SetReceiveWindowOffset(stream_->flow_controller(),
+                                                 kStreamWindow);
+  QuicFlowControllerPeer::SetReceiveWindowOffset(session_->flow_controller(),
+                                                 kConnectionWindow);
+
+  ProcessHeaders(false, headers_);
+
+  // Send enough data to overflow the connection level flow control window.
+  QuicString body(kConnectionWindow + 1, 'a');
+  std::unique_ptr<char[]> buf;
+  QuicByteCount header_length =
+      encoder_.SerializeDataFrameHeader(body.length(), &buf);
+  QuicString header = QuicString(buf.get(), header_length);
+  QuicString data = HasFrameHeader() ? header + body : body;
+
+  EXPECT_LT(data.size(), kStreamWindow);
+  QuicStreamFrame frame(GetNthClientInitiatedBidirectionalId(0), false, 0,
+                        QuicStringPiece(data));
+
+  EXPECT_CALL(*connection_,
+              CloseConnection(QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA, _, _));
+  stream_->OnStreamFrame(frame);
+}
+
+TEST_P(QuicSpdyStreamTest, StreamFlowControlFinNotBlocked) {
+  // An attempt to write a FIN with no data should not be flow control blocked,
+  // even if the send window is 0.
+
+  Initialize(kShouldProcessData);
+
+  // Set a flow control limit of zero.
+  QuicFlowControllerPeer::SetReceiveWindowOffset(stream_->flow_controller(), 0);
+  EXPECT_EQ(0u, QuicFlowControllerPeer::ReceiveWindowOffset(
+                    stream_->flow_controller()));
+
+  // Send a frame with a FIN but no data. This should not be blocked.
+  QuicString body = "";
+  bool fin = true;
+
+  EXPECT_CALL(*connection_,
+              SendBlocked(GetNthClientInitiatedBidirectionalId(0)))
+      .Times(0);
+  EXPECT_CALL(*session_, WritevData(_, _, 0, _, FIN));
+
+  stream_->WriteOrBufferBody(body, fin);
+}
+
+TEST_P(QuicSpdyStreamTest, ReceivingTrailersViaHeaderList) {
+  // Test that receiving trailing headers from the peer via
+  // OnStreamHeaderList() works, and can be read from the stream and consumed.
+  Initialize(kShouldProcessData);
+
+  // Receive initial headers.
+  size_t total_bytes = 0;
+  QuicHeaderList headers;
+  for (const auto& p : headers_) {
+    headers.OnHeader(p.first, p.second);
+    total_bytes += p.first.size() + p.second.size();
+  }
+
+  stream_->OnStreamHeadersPriority(kV3HighestPriority);
+  stream_->OnStreamHeaderList(/*fin=*/false, total_bytes, headers);
+  stream_->ConsumeHeaderList();
+
+  // Receive trailing headers.
+  SpdyHeaderBlock trailers_block;
+  trailers_block["key1"] = "value1";
+  trailers_block["key2"] = "value2";
+  trailers_block["key3"] = "value3";
+  SpdyHeaderBlock trailers_block_with_final_offset = trailers_block.Clone();
+  trailers_block_with_final_offset[kFinalOffsetHeaderKey] = "0";
+  total_bytes = 0;
+  QuicHeaderList trailers;
+  for (const auto& p : trailers_block_with_final_offset) {
+    trailers.OnHeader(p.first, p.second);
+    total_bytes += p.first.size() + p.second.size();
+  }
+  stream_->OnStreamHeaderList(/*fin=*/true, total_bytes, trailers);
+
+  // The trailers should be decompressed, and readable from the stream.
+  EXPECT_TRUE(stream_->trailers_decompressed());
+  EXPECT_EQ(trailers_block, stream_->received_trailers());
+
+  // IsDoneReading() returns false until trailers marked consumed.
+  EXPECT_FALSE(stream_->IsDoneReading());
+  stream_->MarkTrailersConsumed();
+  EXPECT_TRUE(stream_->IsDoneReading());
+}
+
+TEST_P(QuicSpdyStreamTest, ReceivingTrailersWithOffset) {
+  // Test that when receiving trailing headers with an offset before response
+  // body, stream is closed at the right offset.
+  Initialize(kShouldProcessData);
+
+  // Receive initial headers.
+  QuicHeaderList headers = ProcessHeaders(false, headers_);
+  stream_->ConsumeHeaderList();
+
+  const QuicString body = "this is the body";
+  std::unique_ptr<char[]> buf;
+  QuicByteCount header_length =
+      encoder_.SerializeDataFrameHeader(body.length(), &buf);
+  QuicString header = QuicString(buf.get(), header_length);
+  QuicString data = HasFrameHeader() ? header + body : body;
+
+  // Receive trailing headers.
+  SpdyHeaderBlock trailers_block;
+  trailers_block["key1"] = "value1";
+  trailers_block["key2"] = "value2";
+  trailers_block["key3"] = "value3";
+  trailers_block[kFinalOffsetHeaderKey] =
+      QuicTextUtils::Uint64ToString(data.size());
+
+  QuicHeaderList trailers = ProcessHeaders(true, trailers_block);
+
+  // The trailers should be decompressed, and readable from the stream.
+  EXPECT_TRUE(stream_->trailers_decompressed());
+
+  // The final offset trailer will be consumed by QUIC.
+  trailers_block.erase(kFinalOffsetHeaderKey);
+  EXPECT_EQ(trailers_block, stream_->received_trailers());
+
+  // Consuming the trailers erases them from the stream.
+  stream_->MarkTrailersConsumed();
+  EXPECT_TRUE(stream_->FinishedReadingTrailers());
+
+  EXPECT_FALSE(stream_->IsDoneReading());
+  // Receive and consume body.
+  QuicStreamFrame frame(GetNthClientInitiatedBidirectionalId(0), /*fin=*/false,
+                        0, data);
+  stream_->OnStreamFrame(frame);
+  EXPECT_EQ(body, stream_->data());
+  EXPECT_TRUE(stream_->IsDoneReading());
+}
+
+TEST_P(QuicSpdyStreamTest, ReceivingTrailersWithoutOffset) {
+  // Test that receiving trailers without a final offset field is an error.
+  Initialize(kShouldProcessData);
+
+  // Receive initial headers.
+  ProcessHeaders(false, headers_);
+  stream_->ConsumeHeaderList();
+
+  // Receive trailing headers, without kFinalOffsetHeaderKey.
+  SpdyHeaderBlock trailers_block;
+  trailers_block["key1"] = "value1";
+  trailers_block["key2"] = "value2";
+  trailers_block["key3"] = "value3";
+  auto trailers = AsHeaderList(trailers_block);
+
+  // Verify that the trailers block didn't contain a final offset.
+  EXPECT_EQ("", trailers_block[kFinalOffsetHeaderKey].as_string());
+
+  // Receipt of the malformed trailers will close the connection.
+  EXPECT_CALL(*connection_,
+              CloseConnection(QUIC_INVALID_HEADERS_STREAM_DATA, _, _))
+      .Times(1);
+  stream_->OnStreamHeaderList(/*fin=*/true,
+                              trailers.uncompressed_header_bytes(), trailers);
+}
+
+TEST_P(QuicSpdyStreamTest, ReceivingTrailersWithoutFin) {
+  // Test that received Trailers must always have the FIN set.
+  Initialize(kShouldProcessData);
+
+  // Receive initial headers.
+  auto headers = AsHeaderList(headers_);
+  stream_->OnStreamHeaderList(/*fin=*/false,
+                              headers.uncompressed_header_bytes(), headers);
+  stream_->ConsumeHeaderList();
+
+  // Receive trailing headers with FIN deliberately set to false.
+  SpdyHeaderBlock trailers_block;
+  trailers_block["foo"] = "bar";
+  auto trailers = AsHeaderList(trailers_block);
+
+  EXPECT_CALL(*connection_,
+              CloseConnection(QUIC_INVALID_HEADERS_STREAM_DATA, _, _))
+      .Times(1);
+  stream_->OnStreamHeaderList(/*fin=*/false,
+                              trailers.uncompressed_header_bytes(), trailers);
+}
+
+TEST_P(QuicSpdyStreamTest, ReceivingTrailersAfterHeadersWithFin) {
+  // If headers are received with a FIN, no trailers should then arrive.
+  Initialize(kShouldProcessData);
+
+  // Receive initial headers with FIN set.
+  ProcessHeaders(true, headers_);
+  stream_->ConsumeHeaderList();
+
+  // Receive trailing headers after FIN already received.
+  SpdyHeaderBlock trailers_block;
+  trailers_block["foo"] = "bar";
+  EXPECT_CALL(*connection_,
+              CloseConnection(QUIC_INVALID_HEADERS_STREAM_DATA, _, _))
+      .Times(1);
+  ProcessHeaders(true, trailers_block);
+}
+
+TEST_P(QuicSpdyStreamTest, ReceivingTrailersAfterBodyWithFin) {
+  // If body data are received with a FIN, no trailers should then arrive.
+  Initialize(kShouldProcessData);
+
+  // Receive initial headers without FIN set.
+  ProcessHeaders(false, headers_);
+  stream_->ConsumeHeaderList();
+
+  // Receive body data, with FIN.
+  QuicStreamFrame frame(GetNthClientInitiatedBidirectionalId(0), /*fin=*/true,
+                        0, "body");
+  stream_->OnStreamFrame(frame);
+
+  // Receive trailing headers after FIN already received.
+  SpdyHeaderBlock trailers_block;
+  trailers_block["foo"] = "bar";
+  EXPECT_CALL(*connection_,
+              CloseConnection(QUIC_INVALID_HEADERS_STREAM_DATA, _, _))
+      .Times(1);
+  ProcessHeaders(true, trailers_block);
+}
+
+TEST_P(QuicSpdyStreamTest, ClosingStreamWithNoTrailers) {
+  // Verify that a stream receiving headers, body, and no trailers is correctly
+  // marked as done reading on consumption of headers and body.
+  Initialize(kShouldProcessData);
+
+  // Receive and consume initial headers with FIN not set.
+  auto h = AsHeaderList(headers_);
+  stream_->OnStreamHeaderList(/*fin=*/false, h.uncompressed_header_bytes(), h);
+  stream_->ConsumeHeaderList();
+
+  // Receive and consume body with FIN set, and no trailers.
+  QuicString body(1024, 'x');
+  std::unique_ptr<char[]> buf;
+  QuicByteCount header_length =
+      encoder_.SerializeDataFrameHeader(body.length(), &buf);
+  QuicString header = QuicString(buf.get(), header_length);
+  QuicString data = HasFrameHeader() ? header + body : body;
+
+  QuicStreamFrame frame(GetNthClientInitiatedBidirectionalId(0), /*fin=*/true,
+                        0, data);
+  stream_->OnStreamFrame(frame);
+
+  EXPECT_TRUE(stream_->IsDoneReading());
+}
+
+TEST_P(QuicSpdyStreamTest, WritingTrailersSendsAFin) {
+  // Test that writing trailers will send a FIN, as Trailers are the last thing
+  // to be sent on a stream.
+  Initialize(kShouldProcessData);
+
+  // Write the initial headers, without a FIN.
+  EXPECT_CALL(*stream_, WriteHeadersMock(false));
+  stream_->WriteHeaders(SpdyHeaderBlock(), /*fin=*/false, nullptr);
+
+  // Writing trailers implicitly sends a FIN.
+  SpdyHeaderBlock trailers;
+  trailers["trailer key"] = "trailer value";
+  EXPECT_CALL(*stream_, WriteHeadersMock(true));
+  stream_->WriteTrailers(std::move(trailers), nullptr);
+  EXPECT_TRUE(stream_->fin_sent());
+}
+
+TEST_P(QuicSpdyStreamTest, WritingTrailersFinalOffset) {
+  // Test that when writing trailers, the trailers that are actually sent to the
+  // peer contain the final offset field indicating last byte of data.
+  Initialize(kShouldProcessData);
+
+  // Write the initial headers.
+  EXPECT_CALL(*stream_, WriteHeadersMock(false));
+  stream_->WriteHeaders(SpdyHeaderBlock(), /*fin=*/false, nullptr);
+
+  // Write non-zero body data to force a non-zero final offset.
+  EXPECT_CALL(*session_, WritevData(_, _, _, _, _)).Times(AtLeast(1));
+  QuicString body(1024, 'x');  // 1 kB
+  QuicByteCount header_length = 0;
+  if (HasFrameHeader()) {
+    std::unique_ptr<char[]> buf;
+    header_length = encoder_.SerializeDataFrameHeader(body.length(), &buf);
+  }
+
+  stream_->WriteOrBufferBody(body, false);
+
+  // The final offset field in the trailing headers is populated with the
+  // number of body bytes written (including queued bytes).
+  SpdyHeaderBlock trailers;
+  trailers["trailer key"] = "trailer value";
+  SpdyHeaderBlock trailers_with_offset(trailers.Clone());
+  trailers_with_offset[kFinalOffsetHeaderKey] =
+      QuicTextUtils::Uint64ToString(body.length() + header_length);
+  EXPECT_CALL(*stream_, WriteHeadersMock(true));
+  stream_->WriteTrailers(std::move(trailers), nullptr);
+  EXPECT_EQ(trailers_with_offset, stream_->saved_headers());
+}
+
+TEST_P(QuicSpdyStreamTest, WritingTrailersClosesWriteSide) {
+  // Test that if trailers are written after all other data has been written
+  // (headers and body), that this closes the stream for writing.
+  Initialize(kShouldProcessData);
+
+  // Write the initial headers.
+  EXPECT_CALL(*stream_, WriteHeadersMock(false));
+  stream_->WriteHeaders(SpdyHeaderBlock(), /*fin=*/false, nullptr);
+
+  // Write non-zero body data.
+  EXPECT_CALL(*session_, WritevData(_, _, _, _, _)).Times(AtLeast(1));
+  const int kBodySize = 1 * 1024;  // 1 kB
+  stream_->WriteOrBufferBody(QuicString(kBodySize, 'x'), false);
+  EXPECT_EQ(0u, stream_->BufferedDataBytes());
+
+  // Headers and body have been fully written, there is no queued data. Writing
+  // trailers marks the end of this stream, and thus the write side is closed.
+  EXPECT_CALL(*stream_, WriteHeadersMock(true));
+  stream_->WriteTrailers(SpdyHeaderBlock(), nullptr);
+  EXPECT_TRUE(stream_->write_side_closed());
+}
+
+TEST_P(QuicSpdyStreamTest, WritingTrailersWithQueuedBytes) {
+  // Test that the stream is not closed for writing when trailers are sent
+  // while there are still body bytes queued.
+  testing::InSequence seq;
+  Initialize(kShouldProcessData);
+
+  // Write the initial headers.
+  EXPECT_CALL(*stream_, WriteHeadersMock(false));
+  stream_->WriteHeaders(SpdyHeaderBlock(), /*fin=*/false, nullptr);
+
+  // Write non-zero body data, but only consume partially, ensuring queueing.
+  const int kBodySize = 1 * 1024;  // 1 kB
+  if (HasFrameHeader()) {
+    EXPECT_CALL(*session_, WritevData(_, _, 3, _, NO_FIN));
+  }
+  EXPECT_CALL(*session_, WritevData(_, _, kBodySize, _, NO_FIN))
+      .WillOnce(Return(QuicConsumedData(kBodySize - 1, false)));
+  stream_->WriteOrBufferBody(QuicString(kBodySize, 'x'), false);
+  EXPECT_EQ(1u, stream_->BufferedDataBytes());
+
+  // Writing trailers will send a FIN, but not close the write side of the
+  // stream as there are queued bytes.
+  EXPECT_CALL(*stream_, WriteHeadersMock(true));
+  stream_->WriteTrailers(SpdyHeaderBlock(), nullptr);
+  EXPECT_TRUE(stream_->fin_sent());
+  EXPECT_FALSE(stream_->write_side_closed());
+
+  // Writing the queued bytes will close the write side of the stream.
+  EXPECT_CALL(*session_, WritevData(_, _, 1, _, NO_FIN));
+  stream_->OnCanWrite();
+  EXPECT_TRUE(stream_->write_side_closed());
+}
+
+TEST_P(QuicSpdyStreamTest, WritingTrailersAfterFIN) {
+  // EXPECT_QUIC_BUG tests are expensive so only run one instance of them.
+  if (GetParam() != AllSupportedVersions()[0]) {
+    return;
+  }
+
+  // Test that it is not possible to write Trailers after a FIN has been sent.
+  Initialize(kShouldProcessData);
+
+  // Write the initial headers, with a FIN.
+  EXPECT_CALL(*stream_, WriteHeadersMock(true));
+  stream_->WriteHeaders(SpdyHeaderBlock(), /*fin=*/true, nullptr);
+  EXPECT_TRUE(stream_->fin_sent());
+
+  // Writing Trailers should fail, as the FIN has already been sent.
+  // populated with the number of body bytes written.
+  EXPECT_QUIC_BUG(stream_->WriteTrailers(SpdyHeaderBlock(), nullptr),
+                  "Trailers cannot be sent after a FIN");
+}
+
+TEST_P(QuicSpdyStreamTest, HeaderStreamNotiferCorrespondingSpdyStream) {
+  Initialize(kShouldProcessData);
+  EXPECT_CALL(*session_, WritevData(_, _, _, _, _)).Times(AtLeast(1));
+  testing::InSequence s;
+  QuicReferenceCountedPointer<MockAckListener> ack_listener1(
+      new MockAckListener());
+  QuicReferenceCountedPointer<MockAckListener> ack_listener2(
+      new MockAckListener());
+  stream_->set_ack_listener(ack_listener1);
+  stream2_->set_ack_listener(ack_listener2);
+
+  session_->headers_stream()->WriteOrBufferData("Header1", false,
+                                                ack_listener1);
+  stream_->WriteOrBufferBody("Test1", true);
+
+  session_->headers_stream()->WriteOrBufferData("Header2", false,
+                                                ack_listener2);
+  stream2_->WriteOrBufferBody("Test2", false);
+
+  QuicStreamFrame frame1(
+      QuicUtils::GetHeadersStreamId(connection_->transport_version()), false, 0,
+      "Header1");
+  QuicString header = "";
+  if (HasFrameHeader()) {
+    std::unique_ptr<char[]> buffer;
+    QuicByteCount header_length = encoder_.SerializeDataFrameHeader(5, &buffer);
+    header = QuicString(buffer.get(), header_length);
+  }
+  QuicStreamFrame frame2(stream_->id(), true, 0, header + "Test1");
+  QuicStreamFrame frame3(
+      QuicUtils::GetHeadersStreamId(connection_->transport_version()), false, 7,
+      "Header2");
+  QuicStreamFrame frame4(stream2_->id(), false, 0, header + "Test2");
+
+  EXPECT_CALL(*ack_listener1, OnPacketRetransmitted(7));
+  session_->OnStreamFrameRetransmitted(frame1);
+
+  EXPECT_CALL(*ack_listener1, OnPacketAcked(7, _));
+  EXPECT_TRUE(
+      session_->OnFrameAcked(QuicFrame(frame1), QuicTime::Delta::Zero()));
+  EXPECT_CALL(*ack_listener1, OnPacketAcked(5, _));
+  EXPECT_TRUE(
+      session_->OnFrameAcked(QuicFrame(frame2), QuicTime::Delta::Zero()));
+  EXPECT_CALL(*ack_listener2, OnPacketAcked(7, _));
+  EXPECT_TRUE(
+      session_->OnFrameAcked(QuicFrame(frame3), QuicTime::Delta::Zero()));
+  EXPECT_CALL(*ack_listener2, OnPacketAcked(5, _));
+  EXPECT_TRUE(
+      session_->OnFrameAcked(QuicFrame(frame4), QuicTime::Delta::Zero()));
+}
+
+TEST_P(QuicSpdyStreamTest, StreamBecomesZombieWithWriteThatCloses) {
+  Initialize(kShouldProcessData);
+  EXPECT_CALL(*session_, WritevData(_, _, _, _, _)).Times(AtLeast(1));
+  QuicStreamPeer::CloseReadSide(stream_);
+  // This write causes stream to be closed.
+  stream_->WriteOrBufferBody("Test1", true);
+  // stream_ has unacked data and should become zombie.
+  EXPECT_TRUE(QuicContainsKey(QuicSessionPeer::zombie_streams(session_.get()),
+                              stream_->id()));
+  EXPECT_TRUE(QuicSessionPeer::closed_streams(session_.get()).empty());
+}
+
+TEST_P(QuicSpdyStreamTest, OnPriorityFrame) {
+  Initialize(kShouldProcessData);
+  stream_->OnPriorityFrame(kV3HighestPriority);
+  EXPECT_EQ(kV3HighestPriority, stream_->priority());
+}
+
+TEST_P(QuicSpdyStreamTest, OnPriorityFrameAfterSendingData) {
+  testing::InSequence seq;
+  Initialize(kShouldProcessData);
+
+  if (HasFrameHeader()) {
+    EXPECT_CALL(*session_, WritevData(_, _, 2, _, NO_FIN));
+  }
+  EXPECT_CALL(*session_, WritevData(_, _, 4, _, FIN));
+  stream_->WriteOrBufferBody("data", true);
+  stream_->OnPriorityFrame(kV3HighestPriority);
+  EXPECT_EQ(kV3HighestPriority, stream_->priority());
+}
+
+TEST_P(QuicSpdyStreamTest, SetPriorityBeforeUpdateStreamPriority) {
+  MockQuicConnection* connection = new StrictMock<MockQuicConnection>(
+      &helper_, &alarm_factory_, Perspective::IS_SERVER,
+      SupportedVersions(GetParam()));
+  std::unique_ptr<TestMockUpdateStreamSession> session(
+      new StrictMock<TestMockUpdateStreamSession>(connection));
+  auto stream = new StrictMock<TestStream>(
+      GetNthClientInitiatedBidirectionalStreamId(
+          session->connection()->transport_version(), 0),
+      session.get(),
+      /*should_process_data=*/true);
+  session->ActivateStream(QuicWrapUnique(stream));
+
+  // QuicSpdyStream::SetPriority() should eventually call UpdateStreamPriority()
+  // on the session. Make sure stream->priority() returns the updated priority
+  // if called within UpdateStreamPriority(). This expectation is enforced in
+  // TestMockUpdateStreamSession::UpdateStreamPriority().
+  session->SetExpectedStream(stream);
+  session->SetExpectedPriority(kV3HighestPriority);
+  stream->SetPriority(kV3HighestPriority);
+
+  session->SetExpectedPriority(kV3LowestPriority);
+  stream->SetPriority(kV3LowestPriority);
+}
+
+TEST_P(QuicSpdyStreamTest, StreamWaitsForAcks) {
+  Initialize(kShouldProcessData);
+  QuicReferenceCountedPointer<MockAckListener> mock_ack_listener(
+      new StrictMock<MockAckListener>);
+  stream_->set_ack_listener(mock_ack_listener);
+  EXPECT_CALL(*session_, WritevData(_, _, _, _, _)).Times(AtLeast(1));
+  // Stream is not waiting for acks initially.
+  EXPECT_FALSE(stream_->IsWaitingForAcks());
+  EXPECT_EQ(0u, QuicStreamPeer::SendBuffer(stream_).size());
+
+  // Send kData1.
+  stream_->WriteOrBufferData("FooAndBar", false, nullptr);
+  EXPECT_EQ(1u, QuicStreamPeer::SendBuffer(stream_).size());
+  EXPECT_TRUE(stream_->IsWaitingForAcks());
+  EXPECT_CALL(*mock_ack_listener, OnPacketAcked(9, _));
+  QuicByteCount newly_acked_length = 0;
+  EXPECT_TRUE(stream_->OnStreamFrameAcked(0, 9, false, QuicTime::Delta::Zero(),
+                                          &newly_acked_length));
+  // Stream is not waiting for acks as all sent data is acked.
+  EXPECT_FALSE(stream_->IsWaitingForAcks());
+  EXPECT_EQ(0u, QuicStreamPeer::SendBuffer(stream_).size());
+
+  // Send kData2.
+  stream_->WriteOrBufferData("FooAndBar", false, nullptr);
+  EXPECT_TRUE(stream_->IsWaitingForAcks());
+  EXPECT_EQ(1u, QuicStreamPeer::SendBuffer(stream_).size());
+  // Send FIN.
+  stream_->WriteOrBufferData("", true, nullptr);
+  // Fin only frame is not stored in send buffer.
+  EXPECT_EQ(1u, QuicStreamPeer::SendBuffer(stream_).size());
+
+  // kData2 is retransmitted.
+  EXPECT_CALL(*mock_ack_listener, OnPacketRetransmitted(9));
+  stream_->OnStreamFrameRetransmitted(9, 9, false);
+
+  // kData2 is acked.
+  EXPECT_CALL(*mock_ack_listener, OnPacketAcked(9, _));
+  EXPECT_TRUE(stream_->OnStreamFrameAcked(9, 9, false, QuicTime::Delta::Zero(),
+                                          &newly_acked_length));
+  // Stream is waiting for acks as FIN is not acked.
+  EXPECT_TRUE(stream_->IsWaitingForAcks());
+  EXPECT_EQ(0u, QuicStreamPeer::SendBuffer(stream_).size());
+
+  // FIN is acked.
+  EXPECT_CALL(*mock_ack_listener, OnPacketAcked(0, _));
+  EXPECT_TRUE(stream_->OnStreamFrameAcked(18, 0, true, QuicTime::Delta::Zero(),
+                                          &newly_acked_length));
+  EXPECT_FALSE(stream_->IsWaitingForAcks());
+  EXPECT_EQ(0u, QuicStreamPeer::SendBuffer(stream_).size());
+}
+
+TEST_P(QuicSpdyStreamTest, StreamDataGetAckedMultipleTimes) {
+  Initialize(kShouldProcessData);
+  QuicReferenceCountedPointer<MockAckListener> mock_ack_listener(
+      new StrictMock<MockAckListener>);
+  stream_->set_ack_listener(mock_ack_listener);
+  EXPECT_CALL(*session_, WritevData(_, _, _, _, _)).Times(AtLeast(1));
+  // Send [0, 27) and fin.
+  stream_->WriteOrBufferData("FooAndBar", false, nullptr);
+  stream_->WriteOrBufferData("FooAndBar", false, nullptr);
+  stream_->WriteOrBufferData("FooAndBar", true, nullptr);
+
+  // Ack [0, 9), [5, 22) and [18, 26)
+  // Verify [0, 9) 9 bytes are acked.
+  QuicByteCount newly_acked_length = 0;
+  EXPECT_CALL(*mock_ack_listener, OnPacketAcked(9, _));
+  EXPECT_TRUE(stream_->OnStreamFrameAcked(0, 9, false, QuicTime::Delta::Zero(),
+                                          &newly_acked_length));
+  EXPECT_EQ(2u, QuicStreamPeer::SendBuffer(stream_).size());
+  // Verify [9, 22) 13 bytes are acked.
+  EXPECT_CALL(*mock_ack_listener, OnPacketAcked(13, _));
+  EXPECT_TRUE(stream_->OnStreamFrameAcked(5, 17, false, QuicTime::Delta::Zero(),
+                                          &newly_acked_length));
+  EXPECT_EQ(1u, QuicStreamPeer::SendBuffer(stream_).size());
+  // Verify [22, 26) 4 bytes are acked.
+  EXPECT_CALL(*mock_ack_listener, OnPacketAcked(4, _));
+  EXPECT_TRUE(stream_->OnStreamFrameAcked(18, 8, false, QuicTime::Delta::Zero(),
+                                          &newly_acked_length));
+  EXPECT_EQ(1u, QuicStreamPeer::SendBuffer(stream_).size());
+  EXPECT_TRUE(stream_->IsWaitingForAcks());
+
+  // Ack [0, 27).
+  // Verify [26, 27) 1 byte is acked.
+  EXPECT_CALL(*mock_ack_listener, OnPacketAcked(1, _));
+  EXPECT_TRUE(stream_->OnStreamFrameAcked(26, 1, false, QuicTime::Delta::Zero(),
+                                          &newly_acked_length));
+  EXPECT_EQ(0u, QuicStreamPeer::SendBuffer(stream_).size());
+  EXPECT_TRUE(stream_->IsWaitingForAcks());
+
+  // Ack Fin. Verify OnPacketAcked is called.
+  EXPECT_CALL(*mock_ack_listener, OnPacketAcked(0, _));
+  EXPECT_TRUE(stream_->OnStreamFrameAcked(27, 0, true, QuicTime::Delta::Zero(),
+                                          &newly_acked_length));
+  EXPECT_EQ(0u, QuicStreamPeer::SendBuffer(stream_).size());
+  EXPECT_FALSE(stream_->IsWaitingForAcks());
+
+  // Ack [10, 27) and fin.
+  // No new data is acked, verify OnPacketAcked is not called.
+  EXPECT_CALL(*mock_ack_listener, OnPacketAcked(_, _)).Times(0);
+  EXPECT_FALSE(stream_->OnStreamFrameAcked(
+      10, 17, true, QuicTime::Delta::Zero(), &newly_acked_length));
+  EXPECT_EQ(0u, QuicStreamPeer::SendBuffer(stream_).size());
+  EXPECT_FALSE(stream_->IsWaitingForAcks());
+}
+
+// HTTP/3 only.
+TEST_P(QuicSpdyStreamTest, HeadersAckNotReportedWriteOrBufferBody) {
+  Initialize(kShouldProcessData);
+  if (!HasFrameHeader()) {
+    return;
+  }
+  QuicReferenceCountedPointer<MockAckListener> mock_ack_listener(
+      new StrictMock<MockAckListener>);
+  stream_->set_ack_listener(mock_ack_listener);
+  QuicString body = "Test1";
+  QuicString body2(100, 'x');
+
+  EXPECT_CALL(*session_, WritevData(_, _, _, _, _)).Times(AtLeast(1));
+  stream_->WriteOrBufferBody(body, false);
+  stream_->WriteOrBufferBody(body2, true);
+
+  std::unique_ptr<char[]> buffer;
+  QuicByteCount header_length =
+      encoder_.SerializeDataFrameHeader(body.length(), &buffer);
+  QuicString header = QuicString(buffer.get(), header_length);
+
+  header_length = encoder_.SerializeDataFrameHeader(body2.length(), &buffer);
+  QuicString header2 = QuicString(buffer.get(), header_length);
+
+  EXPECT_CALL(*mock_ack_listener, OnPacketAcked(body.length(), _));
+  QuicStreamFrame frame(stream_->id(), false, 0, header + body);
+  EXPECT_TRUE(
+      session_->OnFrameAcked(QuicFrame(frame), QuicTime::Delta::Zero()));
+
+  EXPECT_CALL(*mock_ack_listener, OnPacketAcked(0, _));
+  QuicStreamFrame frame2(stream_->id(), false, (header + body).length(),
+                         header2);
+  EXPECT_TRUE(
+      session_->OnFrameAcked(QuicFrame(frame2), QuicTime::Delta::Zero()));
+
+  EXPECT_CALL(*mock_ack_listener, OnPacketAcked(body2.length(), _));
+  QuicStreamFrame frame3(stream_->id(), true,
+                         (header + body).length() + header2.length(), body2);
+  EXPECT_TRUE(
+      session_->OnFrameAcked(QuicFrame(frame3), QuicTime::Delta::Zero()));
+
+  EXPECT_TRUE(
+      QuicSpdyStreamPeer::unacked_frame_headers_offsets(stream_).Empty());
+}
+
+// HTTP/3 only.
+TEST_P(QuicSpdyStreamTest, HeadersAckNotReportedWriteBodySlices) {
+  Initialize(kShouldProcessData);
+  if (!HasFrameHeader()) {
+    return;
+  }
+  QuicReferenceCountedPointer<MockAckListener> mock_ack_listener(
+      new StrictMock<MockAckListener>);
+  stream_->set_ack_listener(mock_ack_listener);
+  QuicString body = "Test1";
+  QuicString body2(100, 'x');
+  struct iovec body1_iov = {const_cast<char*>(body.data()), body.length()};
+  struct iovec body2_iov = {const_cast<char*>(body2.data()), body2.length()};
+  QuicMemSliceStorage storage(&body1_iov, 1,
+                              helper_.GetStreamSendBufferAllocator(), 1024);
+  QuicMemSliceStorage storage2(&body2_iov, 1,
+                               helper_.GetStreamSendBufferAllocator(), 1024);
+  EXPECT_CALL(*session_, WritevData(_, _, _, _, _)).Times(AtLeast(1));
+  stream_->WriteBodySlices(storage.ToSpan(), false);
+  stream_->WriteBodySlices(storage2.ToSpan(), true);
+
+  std::unique_ptr<char[]> buffer;
+  QuicByteCount header_length =
+      encoder_.SerializeDataFrameHeader(body.length(), &buffer);
+  QuicString header = QuicString(buffer.get(), header_length);
+
+  header_length = encoder_.SerializeDataFrameHeader(body2.length(), &buffer);
+  QuicString header2 = QuicString(buffer.get(), header_length);
+
+  EXPECT_CALL(*mock_ack_listener,
+              OnPacketAcked(body.length() + body2.length(), _));
+  QuicStreamFrame frame(stream_->id(), true, 0,
+                        header + body + header2 + body2);
+  EXPECT_TRUE(
+      session_->OnFrameAcked(QuicFrame(frame), QuicTime::Delta::Zero()));
+
+  EXPECT_TRUE(
+      QuicSpdyStreamPeer::unacked_frame_headers_offsets(stream_).Empty());
+}
+
+// HTTP/3 only.
+TEST_P(QuicSpdyStreamTest, HeaderBytesNotReportedOnRetransmission) {
+  Initialize(kShouldProcessData);
+  if (!HasFrameHeader()) {
+    return;
+  }
+  QuicReferenceCountedPointer<MockAckListener> mock_ack_listener(
+      new StrictMock<MockAckListener>);
+  stream_->set_ack_listener(mock_ack_listener);
+  QuicString body = "Test1";
+  QuicString body2(100, 'x');
+
+  EXPECT_CALL(*session_, WritevData(_, _, _, _, _)).Times(AtLeast(1));
+  stream_->WriteOrBufferBody(body, false);
+  stream_->WriteOrBufferBody(body2, true);
+
+  std::unique_ptr<char[]> buffer;
+  QuicByteCount header_length =
+      encoder_.SerializeDataFrameHeader(body.length(), &buffer);
+  QuicString header = QuicString(buffer.get(), header_length);
+
+  header_length = encoder_.SerializeDataFrameHeader(body2.length(), &buffer);
+  QuicString header2 = QuicString(buffer.get(), header_length);
+
+  EXPECT_CALL(*mock_ack_listener, OnPacketRetransmitted(body.length()));
+  QuicStreamFrame frame(stream_->id(), false, 0, header + body);
+  session_->OnStreamFrameRetransmitted(frame);
+
+  EXPECT_CALL(*mock_ack_listener, OnPacketRetransmitted(body2.length()));
+  QuicStreamFrame frame2(stream_->id(), true, (header + body).length(),
+                         header2 + body2);
+  session_->OnStreamFrameRetransmitted(frame2);
+
+  EXPECT_FALSE(
+      QuicSpdyStreamPeer::unacked_frame_headers_offsets(stream_).Empty());
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quic/core/http/spdy_utils.cc b/quic/core/http/spdy_utils.cc
new file mode 100644
index 0000000..7022ae2
--- /dev/null
+++ b/quic/core/http/spdy_utils.cc
@@ -0,0 +1,353 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/third_party/quiche/src/quic/core/http/spdy_utils.h"
+
+#include <memory>
+#include <vector>
+
+#include "url/gurl.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_flag_utils.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_flags.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_logging.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_map_util.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_string.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_string_piece.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_text_utils.h"
+#include "net/third_party/quiche/src/spdy/core/spdy_frame_builder.h"
+#include "net/third_party/quiche/src/spdy/core/spdy_framer.h"
+#include "net/third_party/quiche/src/spdy/core/spdy_protocol.h"
+
+using spdy::SpdyHeaderBlock;
+
+namespace quic {
+
+// static
+bool SpdyUtils::ExtractContentLengthFromHeaders(int64_t* content_length,
+                                                SpdyHeaderBlock* headers) {
+  auto it = headers->find("content-length");
+  if (it == headers->end()) {
+    return false;
+  } else {
+    // Check whether multiple values are consistent.
+    QuicStringPiece content_length_header = it->second;
+    std::vector<QuicStringPiece> values =
+        QuicTextUtils::Split(content_length_header, '\0');
+    for (const QuicStringPiece& value : values) {
+      uint64_t new_value;
+      if (!QuicTextUtils::StringToUint64(value, &new_value)) {
+        QUIC_DLOG(ERROR)
+            << "Content length was either unparseable or negative.";
+        return false;
+      }
+      if (*content_length < 0) {
+        *content_length = new_value;
+        continue;
+      }
+      if (new_value != static_cast<uint64_t>(*content_length)) {
+        QUIC_DLOG(ERROR)
+            << "Parsed content length " << new_value << " is "
+            << "inconsistent with previously detected content length "
+            << *content_length;
+        return false;
+      }
+    }
+    return true;
+  }
+}
+
+bool SpdyUtils::CopyAndValidateHeaders(const QuicHeaderList& header_list,
+                                       int64_t* content_length,
+                                       SpdyHeaderBlock* headers) {
+  for (const auto& p : header_list) {
+    const QuicString& name = p.first;
+    if (name.empty()) {
+      QUIC_DLOG(ERROR) << "Header name must not be empty.";
+      return false;
+    }
+
+    if (QuicTextUtils::ContainsUpperCase(name)) {
+      QUIC_DLOG(ERROR) << "Malformed header: Header name " << name
+                       << " contains upper-case characters.";
+      return false;
+    }
+
+    headers->AppendValueOrAddHeader(name, p.second);
+  }
+
+  if (QuicContainsKey(*headers, "content-length") &&
+      !ExtractContentLengthFromHeaders(content_length, headers)) {
+    return false;
+  }
+
+  QUIC_DVLOG(1) << "Successfully parsed headers: " << headers->DebugString();
+  return true;
+}
+
+bool SpdyUtils::CopyAndValidateTrailers(const QuicHeaderList& header_list,
+                                        size_t* final_byte_offset,
+                                        SpdyHeaderBlock* trailers) {
+  bool found_final_byte_offset = false;
+  for (const auto& p : header_list) {
+    const QuicString& name = p.first;
+
+    // Pull out the final offset pseudo header which indicates the number of
+    // response body bytes expected.
+    if (!found_final_byte_offset && name == kFinalOffsetHeaderKey &&
+        QuicTextUtils::StringToSizeT(p.second, final_byte_offset)) {
+      found_final_byte_offset = true;
+      continue;
+    }
+
+    if (name.empty() || name[0] == ':') {
+      QUIC_DLOG(ERROR)
+          << "Trailers must not be empty, and must not contain pseudo-"
+          << "headers. Found: '" << name << "'";
+      return false;
+    }
+
+    if (QuicTextUtils::ContainsUpperCase(name)) {
+      QUIC_DLOG(ERROR) << "Malformed header: Header name " << name
+                       << " contains upper-case characters.";
+      return false;
+    }
+
+    trailers->AppendValueOrAddHeader(name, p.second);
+  }
+
+  if (!found_final_byte_offset) {
+    QUIC_DLOG(ERROR) << "Required key '" << kFinalOffsetHeaderKey
+                     << "' not present";
+    return false;
+  }
+
+  // TODO(rjshade): Check for other forbidden keys, following the HTTP/2 spec.
+
+  QUIC_DVLOG(1) << "Successfully parsed Trailers: " << trailers->DebugString();
+  return true;
+}
+
+// static
+QuicString SpdyUtils::GetPromisedUrlFromHeaders(
+    const SpdyHeaderBlock& headers) {
+  // RFC 7540, Section 8.1.2.3: All HTTP/2 requests MUST include exactly
+  // one valid value for the ":method", ":scheme", and ":path" pseudo-header
+  // fields, unless it is a CONNECT request.
+
+  // RFC 7540, Section  8.2.1:  The header fields in PUSH_PROMISE and any
+  // subsequent CONTINUATION frames MUST be a valid and complete set of request
+  // header fields (Section 8.1.2.3).  The server MUST include a method in the
+  // ":method" pseudo-header field that is safe and cacheable.
+  //
+  // RFC 7231, Section  4.2.1: Of the request methods defined by this
+  // specification, the GET, HEAD, OPTIONS, and TRACE methods are defined to be
+  // safe.
+  //
+  // RFC 7231, Section  4.2.1: ... this specification defines GET, HEAD, and
+  // POST as cacheable, ...
+  //
+  // So the only methods allowed in a PUSH_PROMISE are GET and HEAD.
+  SpdyHeaderBlock::const_iterator it = headers.find(":method");
+  if (it == headers.end() || (it->second != "GET" && it->second != "HEAD")) {
+    return QuicString();
+  }
+
+  it = headers.find(":scheme");
+  if (it == headers.end() || it->second.empty()) {
+    return QuicString();
+  }
+  QuicStringPiece scheme = it->second;
+
+  // RFC 7540, Section 8.2: The server MUST include a value in the
+  // ":authority" pseudo-header field for which the server is authoritative
+  // (see Section 10.1).
+  it = headers.find(":authority");
+  if (it == headers.end() || it->second.empty()) {
+    return QuicString();
+  }
+  QuicStringPiece authority = it->second;
+
+  // RFC 7540, Section 8.1.2.3 requires that the ":path" pseudo-header MUST
+  // NOT be empty for "http" or "https" URIs;
+  //
+  // However, to ensure the scheme is consistently canonicalized, that check
+  // is deferred to implementations in QuicUrlUtils::GetPushPromiseUrl().
+  it = headers.find(":path");
+  if (it == headers.end()) {
+    return QuicString();
+  }
+  QuicStringPiece path = it->second;
+
+  return GetPushPromiseUrl(scheme, authority, path);
+}
+
+// static
+QuicString SpdyUtils::GetPromisedHostNameFromHeaders(
+    const SpdyHeaderBlock& headers) {
+  // TODO(fayang): Consider just checking out the value of the ":authority" key
+  // in headers.
+  return GURL(GetPromisedUrlFromHeaders(headers)).host();
+}
+
+// static
+bool SpdyUtils::PromisedUrlIsValid(const SpdyHeaderBlock& headers) {
+  QuicString url(GetPromisedUrlFromHeaders(headers));
+  return !url.empty() && GURL(url).is_valid();
+}
+
+// static
+bool SpdyUtils::PopulateHeaderBlockFromUrl(const QuicString url,
+                                           SpdyHeaderBlock* headers) {
+  (*headers)[":method"] = "GET";
+  size_t pos = url.find("://");
+  if (pos == QuicString::npos) {
+    return false;
+  }
+  (*headers)[":scheme"] = url.substr(0, pos);
+  size_t start = pos + 3;
+  pos = url.find("/", start);
+  if (pos == QuicString::npos) {
+    (*headers)[":authority"] = url.substr(start);
+    (*headers)[":path"] = "/";
+    return true;
+  }
+  (*headers)[":authority"] = url.substr(start, pos - start);
+  (*headers)[":path"] = url.substr(pos);
+  return true;
+}
+
+// static
+QuicString SpdyUtils::GetPushPromiseUrl(QuicStringPiece scheme,
+                                        QuicStringPiece authority,
+                                        QuicStringPiece path) {
+  // RFC 7540, Section 8.1.2.3: The ":path" pseudo-header field includes the
+  // path and query parts of the target URI (the "path-absolute" production
+  // and optionally a '?' character followed by the "query" production (see
+  // Sections 3.3 and 3.4 of RFC3986). A request in asterisk form includes the
+  // value '*' for the ":path" pseudo-header field.
+  //
+  // This pseudo-header field MUST NOT be empty for "http" or "https" URIs;
+  // "http" or "https" URIs that do not contain a path MUST include a value of
+  // '/'. The exception to this rule is an OPTIONS request for an "http" or
+  // "https" URI that does not include a path component; these MUST include a
+  // ":path" pseudo-header with a value of '*' (see RFC7230, Section 5.3.4).
+  //
+  // In addition to the above restriction from RFC 7540, note that RFC3986
+  // defines the "path-absolute" construction as starting with "/" but not "//".
+  //
+  // RFC 7540, Section  8.2.1:  The header fields in PUSH_PROMISE and any
+  // subsequent CONTINUATION frames MUST be a valid and complete set of request
+  // header fields (Section 8.1.2.3).  The server MUST include a method in the
+  // ":method" pseudo-header field that is safe and cacheable.
+  //
+  // RFC 7231, Section  4.2.1:
+  // ... this specification defines GET, HEAD, and POST as cacheable, ...
+  //
+  // Since the OPTIONS method is not cacheable, it cannot be the method of a
+  // PUSH_PROMISE. Therefore, the exception mentioned in RFC 7540, Section
+  // 8.1.2.3 about OPTIONS requests does not apply here (i.e. ":path" cannot be
+  // "*").
+  if (path.empty() || path[0] != '/' || (path.size() >= 2 && path[1] == '/')) {
+    return QuicString();
+  }
+
+  // Validate the scheme; this is to ensure a scheme of "foo://bar" is not
+  // parsed as a URL of "foo://bar://baz" when combined with a host of "baz".
+  std::string canonical_scheme;
+  url::StdStringCanonOutput canon_scheme_output(&canonical_scheme);
+  url::Component canon_component;
+  url::Component scheme_component(0, scheme.size());
+
+  if (!url::CanonicalizeScheme(scheme.data(), scheme_component,
+                               &canon_scheme_output, &canon_component) ||
+      !canon_component.is_nonempty() || canon_component.begin != 0) {
+    return QuicString();
+  }
+  canonical_scheme.resize(canon_component.len + 1);
+
+  // Validate the authority; this is to ensure an authority such as
+  // "host/path" is not accepted, as when combined with a scheme like
+  // "http://", could result in a URL of "http://host/path".
+  url::Component auth_component(0, authority.size());
+  url::Component username_component;
+  url::Component password_component;
+  url::Component host_component;
+  url::Component port_component;
+
+  url::ParseAuthority(authority.data(), auth_component, &username_component,
+                      &password_component, &host_component, &port_component);
+
+  // RFC 7540, Section 8.1.2.3: The authority MUST NOT include the deprecated
+  // "userinfo" subcomponent for "http" or "https" schemed URIs.
+  //
+  // Note: Although |canonical_scheme| has not yet been checked for that, as
+  // it is performed later in processing, only "http" and "https" schemed
+  // URIs are supported for PUSH.
+  if (username_component.is_valid() || password_component.is_valid()) {
+    return QuicString();
+  }
+
+  // Failed parsing or no host present. ParseAuthority() will ensure that
+  // host_component + port_component cover the entire string, if
+  // username_component and password_component are not present.
+  if (!host_component.is_nonempty()) {
+    return QuicString();
+  }
+
+  // Validate the port (if present; it's optional).
+  int parsed_port_number = url::PORT_INVALID;
+  if (port_component.is_nonempty()) {
+    parsed_port_number = url::ParsePort(authority.data(), port_component);
+    if (parsed_port_number < 0 && parsed_port_number != url::PORT_UNSPECIFIED) {
+      return QuicString();
+    }
+  }
+
+  // Validate the host by attempting to canonicalize it. Invalid characters
+  // will result in a canonicalization failure (e.g. '/')
+  std::string canon_host;
+  url::StdStringCanonOutput canon_host_output(&canon_host);
+  canon_component.reset();
+  if (!url::CanonicalizeHost(authority.data(), host_component,
+                             &canon_host_output, &canon_component) ||
+      !canon_component.is_nonempty() || canon_component.begin != 0) {
+    return QuicString();
+  }
+
+  // At this point, "authority" has been validated to either be of the form
+  // 'host:port' or 'host', with 'host' being a valid domain or IP address,
+  // and 'port' (if present), being a valid port. Attempt to construct a
+  // URL of just the (scheme, host, port), which should be safe and will not
+  // result in ambiguous parsing.
+  //
+  // This also enforces that all PUSHed URLs are either HTTP or HTTPS-schemed
+  // URIs, consistent with the other restrictions enforced above.
+  //
+  // Note: url::CanonicalizeScheme() will have added the ':' to
+  // |canonical_scheme|.
+  GURL origin_url(canonical_scheme + "//" + std::string(authority));
+  if (!origin_url.is_valid() || !origin_url.SchemeIsHTTPOrHTTPS() ||
+      // The following checks are merely defense in depth.
+      origin_url.has_username() || origin_url.has_password() ||
+      (origin_url.has_path() && origin_url.path_piece() != "/") ||
+      origin_url.has_query() || origin_url.has_ref()) {
+    return QuicString();
+  }
+
+  // Attempt to parse the path.
+  std::string spec = origin_url.GetWithEmptyPath().spec();
+  spec.pop_back();  // Remove the '/', as ":path" must contain it.
+  spec.append(std::string(path));
+
+  // Attempt to parse the full URL, with the path as well. Ensure there is no
+  // fragment to the query.
+  GURL full_url(spec);
+  if (!full_url.is_valid() || full_url.has_ref()) {
+    return QuicString();
+  }
+
+  return full_url.spec();
+}
+
+}  // namespace quic
diff --git a/quic/core/http/spdy_utils.h b/quic/core/http/spdy_utils.h
new file mode 100644
index 0000000..073eeeb
--- /dev/null
+++ b/quic/core/http/spdy_utils.h
@@ -0,0 +1,70 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_HTTP_SPDY_UTILS_H_
+#define QUICHE_QUIC_CORE_HTTP_SPDY_UTILS_H_
+
+#include <cstddef>
+#include <cstdint>
+
+#include "base/macros.h"
+#include "net/third_party/quiche/src/quic/core/http/quic_header_list.h"
+#include "net/third_party/quiche/src/quic/core/quic_packets.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_export.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_string.h"
+#include "net/third_party/quiche/src/spdy/core/spdy_framer.h"
+
+namespace quic {
+
+class QUIC_EXPORT_PRIVATE SpdyUtils {
+ public:
+  SpdyUtils() = delete;
+
+  // Populate |content length| with the value of the content-length header.
+  // Returns true on success, false if parsing fails or content-length header is
+  // missing.
+  static bool ExtractContentLengthFromHeaders(int64_t* content_length,
+                                              spdy::SpdyHeaderBlock* headers);
+
+  // Copies a list of headers to a SpdyHeaderBlock.
+  static bool CopyAndValidateHeaders(const QuicHeaderList& header_list,
+                                     int64_t* content_length,
+                                     spdy::SpdyHeaderBlock* headers);
+
+  // Copies a list of headers to a SpdyHeaderBlock.
+  static bool CopyAndValidateTrailers(const QuicHeaderList& header_list,
+                                      size_t* final_byte_offset,
+                                      spdy::SpdyHeaderBlock* trailers);
+
+  // Returns a canonicalized URL composed from the :scheme, :authority, and
+  // :path headers of a PUSH_PROMISE. Returns empty string if the headers do not
+  // conform to HTTP/2 spec or if the ":method" header contains a forbidden
+  // method for PUSH_PROMISE.
+  static QuicString GetPromisedUrlFromHeaders(
+      const spdy::SpdyHeaderBlock& headers);
+
+  // Returns hostname, or empty string if missing.
+  static QuicString GetPromisedHostNameFromHeaders(
+      const spdy::SpdyHeaderBlock& headers);
+
+  // Returns true if result of |GetPromisedUrlFromHeaders()| is non-empty
+  // and is a well-formed URL.
+  static bool PromisedUrlIsValid(const spdy::SpdyHeaderBlock& headers);
+
+  // Populates the fields of |headers| to make a GET request of |url|,
+  // which must be fully-qualified.
+  static bool PopulateHeaderBlockFromUrl(const QuicString url,
+                                         spdy::SpdyHeaderBlock* headers);
+
+  // Returns a canonical, valid URL for a PUSH_PROMISE with the specified
+  // ":scheme", ":authority", and ":path" header fields, or an empty
+  // string if the resulting URL is not valid or supported.
+  static QuicString GetPushPromiseUrl(QuicStringPiece scheme,
+                                      QuicStringPiece authority,
+                                      QuicStringPiece path);
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_HTTP_SPDY_UTILS_H_
diff --git a/quic/core/http/spdy_utils_test.cc b/quic/core/http/spdy_utils_test.cc
new file mode 100644
index 0000000..6cd2f1d
--- /dev/null
+++ b/quic/core/http/spdy_utils_test.cc
@@ -0,0 +1,519 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <memory>
+
+#include "base/macros.h"
+#include "net/third_party/quiche/src/quic/core/http/spdy_utils.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_arraysize.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_string.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_string_piece.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_test.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_text_utils.h"
+
+using spdy::SpdyHeaderBlock;
+using testing::Pair;
+using testing::UnorderedElementsAre;
+
+namespace quic {
+namespace test {
+
+static std::unique_ptr<QuicHeaderList> FromList(
+    const QuicHeaderList::ListType& src) {
+  std::unique_ptr<QuicHeaderList> headers(new QuicHeaderList);
+  headers->OnHeaderBlockStart();
+  for (const auto& p : src) {
+    headers->OnHeader(p.first, p.second);
+  }
+  headers->OnHeaderBlockEnd(0, 0);
+  return headers;
+}
+
+using CopyAndValidateHeaders = QuicTest;
+
+TEST_F(CopyAndValidateHeaders, NormalUsage) {
+  auto headers = FromList({// All cookie crumbs are joined.
+                           {"cookie", " part 1"},
+                           {"cookie", "part 2 "},
+                           {"cookie", "part3"},
+
+                           // Already-delimited headers are passed through.
+                           {"passed-through", QuicString("foo\0baz", 7)},
+
+                           // Other headers are joined on \0.
+                           {"joined", "value 1"},
+                           {"joined", "value 2"},
+
+                           // Empty headers remain empty.
+                           {"empty", ""},
+
+                           // Joined empty headers work as expected.
+                           {"empty-joined", ""},
+                           {"empty-joined", "foo"},
+                           {"empty-joined", ""},
+                           {"empty-joined", ""},
+
+                           // Non-continguous cookie crumb.
+                           {"cookie", " fin!"}});
+
+  int64_t content_length = -1;
+  SpdyHeaderBlock block;
+  ASSERT_TRUE(
+      SpdyUtils::CopyAndValidateHeaders(*headers, &content_length, &block));
+  EXPECT_THAT(block,
+              UnorderedElementsAre(
+                  Pair("cookie", " part 1; part 2 ; part3;  fin!"),
+                  Pair("passed-through", QuicStringPiece("foo\0baz", 7)),
+                  Pair("joined", QuicStringPiece("value 1\0value 2", 15)),
+                  Pair("empty", ""),
+                  Pair("empty-joined", QuicStringPiece("\0foo\0\0", 6))));
+  EXPECT_EQ(-1, content_length);
+}
+
+TEST_F(CopyAndValidateHeaders, EmptyName) {
+  auto headers = FromList({{"foo", "foovalue"}, {"", "barvalue"}, {"baz", ""}});
+  int64_t content_length = -1;
+  SpdyHeaderBlock block;
+  ASSERT_FALSE(
+      SpdyUtils::CopyAndValidateHeaders(*headers, &content_length, &block));
+}
+
+TEST_F(CopyAndValidateHeaders, UpperCaseName) {
+  auto headers =
+      FromList({{"foo", "foovalue"}, {"bar", "barvalue"}, {"bAz", ""}});
+  int64_t content_length = -1;
+  SpdyHeaderBlock block;
+  ASSERT_FALSE(
+      SpdyUtils::CopyAndValidateHeaders(*headers, &content_length, &block));
+}
+
+TEST_F(CopyAndValidateHeaders, MultipleContentLengths) {
+  auto headers = FromList({{"content-length", "9"},
+                           {"foo", "foovalue"},
+                           {"content-length", "9"},
+                           {"bar", "barvalue"},
+                           {"baz", ""}});
+  int64_t content_length = -1;
+  SpdyHeaderBlock block;
+  ASSERT_TRUE(
+      SpdyUtils::CopyAndValidateHeaders(*headers, &content_length, &block));
+  EXPECT_THAT(block, UnorderedElementsAre(
+                         Pair("foo", "foovalue"), Pair("bar", "barvalue"),
+                         Pair("content-length", QuicStringPiece("9\09", 3)),
+                         Pair("baz", "")));
+  EXPECT_EQ(9, content_length);
+}
+
+TEST_F(CopyAndValidateHeaders, InconsistentContentLengths) {
+  auto headers = FromList({{"content-length", "9"},
+                           {"foo", "foovalue"},
+                           {"content-length", "8"},
+                           {"bar", "barvalue"},
+                           {"baz", ""}});
+  int64_t content_length = -1;
+  SpdyHeaderBlock block;
+  ASSERT_FALSE(
+      SpdyUtils::CopyAndValidateHeaders(*headers, &content_length, &block));
+}
+
+TEST_F(CopyAndValidateHeaders, LargeContentLength) {
+  auto headers = FromList({{"content-length", "9000000000"},
+                           {"foo", "foovalue"},
+                           {"bar", "barvalue"},
+                           {"baz", ""}});
+  int64_t content_length = -1;
+  SpdyHeaderBlock block;
+  ASSERT_TRUE(
+      SpdyUtils::CopyAndValidateHeaders(*headers, &content_length, &block));
+  EXPECT_THAT(block, UnorderedElementsAre(
+                         Pair("foo", "foovalue"), Pair("bar", "barvalue"),
+                         Pair("content-length", QuicStringPiece("9000000000")),
+                         Pair("baz", "")));
+  EXPECT_EQ(9000000000, content_length);
+}
+
+TEST_F(CopyAndValidateHeaders, MultipleValues) {
+  auto headers = FromList({{"foo", "foovalue"},
+                           {"bar", "barvalue"},
+                           {"baz", ""},
+                           {"foo", "boo"},
+                           {"baz", "buzz"}});
+  int64_t content_length = -1;
+  SpdyHeaderBlock block;
+  ASSERT_TRUE(
+      SpdyUtils::CopyAndValidateHeaders(*headers, &content_length, &block));
+  EXPECT_THAT(block, UnorderedElementsAre(
+                         Pair("foo", QuicStringPiece("foovalue\0boo", 12)),
+                         Pair("bar", "barvalue"),
+                         Pair("baz", QuicStringPiece("\0buzz", 5))));
+  EXPECT_EQ(-1, content_length);
+}
+
+TEST_F(CopyAndValidateHeaders, MoreThanTwoValues) {
+  auto headers = FromList({{"set-cookie", "value1"},
+                           {"set-cookie", "value2"},
+                           {"set-cookie", "value3"}});
+  int64_t content_length = -1;
+  SpdyHeaderBlock block;
+  ASSERT_TRUE(
+      SpdyUtils::CopyAndValidateHeaders(*headers, &content_length, &block));
+  EXPECT_THAT(
+      block, UnorderedElementsAre(Pair(
+                 "set-cookie", QuicStringPiece("value1\0value2\0value3", 20))));
+  EXPECT_EQ(-1, content_length);
+}
+
+TEST_F(CopyAndValidateHeaders, Cookie) {
+  auto headers = FromList({{"foo", "foovalue"},
+                           {"bar", "barvalue"},
+                           {"cookie", "value1"},
+                           {"baz", ""}});
+  int64_t content_length = -1;
+  SpdyHeaderBlock block;
+  ASSERT_TRUE(
+      SpdyUtils::CopyAndValidateHeaders(*headers, &content_length, &block));
+  EXPECT_THAT(block, UnorderedElementsAre(
+                         Pair("foo", "foovalue"), Pair("bar", "barvalue"),
+                         Pair("cookie", "value1"), Pair("baz", "")));
+  EXPECT_EQ(-1, content_length);
+}
+
+TEST_F(CopyAndValidateHeaders, MultipleCookies) {
+  auto headers = FromList({{"foo", "foovalue"},
+                           {"bar", "barvalue"},
+                           {"cookie", "value1"},
+                           {"baz", ""},
+                           {"cookie", "value2"}});
+  int64_t content_length = -1;
+  SpdyHeaderBlock block;
+  ASSERT_TRUE(
+      SpdyUtils::CopyAndValidateHeaders(*headers, &content_length, &block));
+  EXPECT_THAT(block, UnorderedElementsAre(
+                         Pair("foo", "foovalue"), Pair("bar", "barvalue"),
+                         Pair("cookie", "value1; value2"), Pair("baz", "")));
+  EXPECT_EQ(-1, content_length);
+}
+
+using CopyAndValidateTrailers = QuicTest;
+
+TEST_F(CopyAndValidateTrailers, SimplestValidList) {
+  // Verify that the simplest trailers are valid: just a final byte offset that
+  // gets parsed successfully.
+  auto trailers = FromList({{kFinalOffsetHeaderKey, "1234"}});
+  size_t final_byte_offset = 0;
+  SpdyHeaderBlock block;
+  EXPECT_TRUE(SpdyUtils::CopyAndValidateTrailers(*trailers, &final_byte_offset,
+                                                 &block));
+  EXPECT_EQ(1234u, final_byte_offset);
+}
+
+TEST_F(CopyAndValidateTrailers, EmptyTrailerList) {
+  // An empty trailer list will fail as required key kFinalOffsetHeaderKey is
+  // not present.
+  QuicHeaderList trailers;
+  size_t final_byte_offset = 0;
+  SpdyHeaderBlock block;
+  EXPECT_FALSE(
+      SpdyUtils::CopyAndValidateTrailers(trailers, &final_byte_offset, &block));
+}
+
+TEST_F(CopyAndValidateTrailers, FinalByteOffsetNotPresent) {
+  // Validation fails if required kFinalOffsetHeaderKey is not present, even if
+  // the rest of the header block is valid.
+  auto trailers = FromList({{"key", "value"}});
+  size_t final_byte_offset = 0;
+  SpdyHeaderBlock block;
+  EXPECT_FALSE(SpdyUtils::CopyAndValidateTrailers(*trailers, &final_byte_offset,
+                                                  &block));
+}
+
+TEST_F(CopyAndValidateTrailers, EmptyName) {
+  // Trailer validation will fail with an empty header key, in an otherwise
+  // valid block of trailers.
+  auto trailers = FromList({{"", "value"}, {kFinalOffsetHeaderKey, "1234"}});
+  size_t final_byte_offset = 0;
+  SpdyHeaderBlock block;
+  EXPECT_FALSE(SpdyUtils::CopyAndValidateTrailers(*trailers, &final_byte_offset,
+                                                  &block));
+}
+
+TEST_F(CopyAndValidateTrailers, PseudoHeaderInTrailers) {
+  // Pseudo headers are illegal in trailers.
+  auto trailers =
+      FromList({{":pseudo_key", "value"}, {kFinalOffsetHeaderKey, "1234"}});
+  size_t final_byte_offset = 0;
+  SpdyHeaderBlock block;
+  EXPECT_FALSE(SpdyUtils::CopyAndValidateTrailers(*trailers, &final_byte_offset,
+                                                  &block));
+}
+
+TEST_F(CopyAndValidateTrailers, DuplicateTrailers) {
+  // Duplicate trailers are allowed, and their values are concatenated into a
+  // single string delimted with '\0'. Some of the duplicate headers
+  // deliberately have an empty value.
+  auto trailers = FromList({{"key", "value0"},
+                            {"key", "value1"},
+                            {"key", ""},
+                            {"key", ""},
+                            {"key", "value2"},
+                            {"key", ""},
+                            {kFinalOffsetHeaderKey, "1234"},
+                            {"other_key", "value"},
+                            {"key", "non_contiguous_duplicate"}});
+  size_t final_byte_offset = 0;
+  SpdyHeaderBlock block;
+  EXPECT_TRUE(SpdyUtils::CopyAndValidateTrailers(*trailers, &final_byte_offset,
+                                                 &block));
+  EXPECT_THAT(
+      block,
+      UnorderedElementsAre(
+          Pair("key",
+               QuicStringPiece(
+                   "value0\0value1\0\0\0value2\0\0non_contiguous_duplicate",
+                   48)),
+          Pair("other_key", "value")));
+}
+
+TEST_F(CopyAndValidateTrailers, DuplicateCookies) {
+  // Duplicate cookie headers in trailers should be concatenated into a single
+  //  "; " delimted string.
+  auto headers = FromList({{"cookie", " part 1"},
+                           {"cookie", "part 2 "},
+                           {"cookie", "part3"},
+                           {"key", "value"},
+                           {kFinalOffsetHeaderKey, "1234"},
+                           {"cookie", " non_contiguous_cookie!"}});
+
+  size_t final_byte_offset = 0;
+  SpdyHeaderBlock block;
+  EXPECT_TRUE(
+      SpdyUtils::CopyAndValidateTrailers(*headers, &final_byte_offset, &block));
+  EXPECT_THAT(
+      block,
+      UnorderedElementsAre(
+          Pair("cookie", " part 1; part 2 ; part3;  non_contiguous_cookie!"),
+          Pair("key", "value")));
+}
+
+using GetPromisedUrlFromHeaders = QuicTest;
+
+TEST_F(GetPromisedUrlFromHeaders, Basic) {
+  SpdyHeaderBlock headers;
+  headers[":method"] = "GET";
+  EXPECT_EQ(SpdyUtils::GetPromisedUrlFromHeaders(headers), "");
+  headers[":scheme"] = "https";
+  EXPECT_EQ(SpdyUtils::GetPromisedUrlFromHeaders(headers), "");
+  headers[":authority"] = "www.google.com";
+  EXPECT_EQ(SpdyUtils::GetPromisedUrlFromHeaders(headers), "");
+  headers[":path"] = "/index.html";
+  EXPECT_EQ(SpdyUtils::GetPromisedUrlFromHeaders(headers),
+            "https://www.google.com/index.html");
+  headers["key1"] = "value1";
+  headers["key2"] = "value2";
+  EXPECT_EQ(SpdyUtils::GetPromisedUrlFromHeaders(headers),
+            "https://www.google.com/index.html");
+}
+
+TEST_F(GetPromisedUrlFromHeaders, Connect) {
+  SpdyHeaderBlock headers;
+  headers[":method"] = "CONNECT";
+  EXPECT_EQ(SpdyUtils::GetPromisedUrlFromHeaders(headers), "");
+  headers[":authority"] = "www.google.com";
+  EXPECT_EQ(SpdyUtils::GetPromisedUrlFromHeaders(headers), "");
+  headers[":scheme"] = "https";
+  EXPECT_EQ(SpdyUtils::GetPromisedUrlFromHeaders(headers), "");
+  headers[":path"] = "https";
+  EXPECT_EQ(SpdyUtils::GetPromisedUrlFromHeaders(headers), "");
+}
+
+TEST_F(GetPromisedUrlFromHeaders, InvalidUserinfo) {
+  SpdyHeaderBlock headers;
+  headers[":method"] = "GET";
+  headers[":authority"] = "user@www.google.com";
+  headers[":scheme"] = "https";
+  headers[":path"] = "/";
+  EXPECT_EQ(SpdyUtils::GetPromisedUrlFromHeaders(headers), "");
+}
+
+TEST_F(GetPromisedUrlFromHeaders, InvalidPath) {
+  SpdyHeaderBlock headers;
+  headers[":method"] = "GET";
+  headers[":authority"] = "www.google.com";
+  headers[":scheme"] = "https";
+  headers[":path"] = "";
+  EXPECT_EQ(SpdyUtils::GetPromisedUrlFromHeaders(headers), "");
+}
+
+using GetPromisedHostNameFromHeaders = QuicTest;
+
+TEST_F(GetPromisedHostNameFromHeaders, NormalUsage) {
+  SpdyHeaderBlock headers;
+  headers[":method"] = "GET";
+  EXPECT_EQ(SpdyUtils::GetPromisedHostNameFromHeaders(headers), "");
+  headers[":scheme"] = "https";
+  EXPECT_EQ(SpdyUtils::GetPromisedHostNameFromHeaders(headers), "");
+  headers[":authority"] = "www.google.com";
+  EXPECT_EQ(SpdyUtils::GetPromisedHostNameFromHeaders(headers), "");
+  headers[":path"] = "/index.html";
+  EXPECT_EQ(SpdyUtils::GetPromisedHostNameFromHeaders(headers),
+            "www.google.com");
+  headers["key1"] = "value1";
+  headers["key2"] = "value2";
+  EXPECT_EQ(SpdyUtils::GetPromisedHostNameFromHeaders(headers),
+            "www.google.com");
+  headers[":authority"] = "www.google.com:6666";
+  EXPECT_EQ(SpdyUtils::GetPromisedHostNameFromHeaders(headers),
+            "www.google.com");
+  headers[":authority"] = "192.168.1.1";
+  EXPECT_EQ(SpdyUtils::GetPromisedHostNameFromHeaders(headers), "192.168.1.1");
+  headers[":authority"] = "192.168.1.1:6666";
+  EXPECT_EQ(SpdyUtils::GetPromisedHostNameFromHeaders(headers), "192.168.1.1");
+}
+
+using PopulateHeaderBlockFromUrl = QuicTest;
+
+TEST_F(PopulateHeaderBlockFromUrl, NormalUsage) {
+  QuicString url = "https://www.google.com/index.html";
+  SpdyHeaderBlock headers;
+  EXPECT_TRUE(SpdyUtils::PopulateHeaderBlockFromUrl(url, &headers));
+  EXPECT_EQ("https", headers[":scheme"].as_string());
+  EXPECT_EQ("www.google.com", headers[":authority"].as_string());
+  EXPECT_EQ("/index.html", headers[":path"].as_string());
+}
+
+TEST_F(PopulateHeaderBlockFromUrl, UrlWithNoPath) {
+  QuicString url = "https://www.google.com";
+  SpdyHeaderBlock headers;
+  EXPECT_TRUE(SpdyUtils::PopulateHeaderBlockFromUrl(url, &headers));
+  EXPECT_EQ("https", headers[":scheme"].as_string());
+  EXPECT_EQ("www.google.com", headers[":authority"].as_string());
+  EXPECT_EQ("/", headers[":path"].as_string());
+}
+
+TEST_F(PopulateHeaderBlockFromUrl, Failure) {
+  SpdyHeaderBlock headers;
+  EXPECT_FALSE(SpdyUtils::PopulateHeaderBlockFromUrl("/", &headers));
+  EXPECT_FALSE(SpdyUtils::PopulateHeaderBlockFromUrl("/index.html", &headers));
+  EXPECT_FALSE(
+      SpdyUtils::PopulateHeaderBlockFromUrl("www.google.com/", &headers));
+}
+
+using PushPromiseUrlTest = QuicTest;
+
+TEST_F(PushPromiseUrlTest, GetPushPromiseUrl) {
+  // Test rejection of various inputs.
+  EXPECT_EQ("",
+            SpdyUtils::GetPushPromiseUrl("file", "localhost", "/etc/password"));
+  EXPECT_EQ("", SpdyUtils::GetPushPromiseUrl("file", "",
+                                             "/C:/Windows/System32/Config/"));
+  EXPECT_EQ("",
+            SpdyUtils::GetPushPromiseUrl("", "https://www.google.com", "/"));
+
+  EXPECT_EQ("", SpdyUtils::GetPushPromiseUrl("https://www.google.com",
+                                             "www.google.com", "/"));
+  EXPECT_EQ("",
+            SpdyUtils::GetPushPromiseUrl("https://", "www.google.com", "/"));
+  EXPECT_EQ("", SpdyUtils::GetPushPromiseUrl("https", "", "/"));
+  EXPECT_EQ("", SpdyUtils::GetPushPromiseUrl("https", "", "www.google.com/"));
+  EXPECT_EQ("", SpdyUtils::GetPushPromiseUrl("https", "www.google.com/", "/"));
+  EXPECT_EQ("", SpdyUtils::GetPushPromiseUrl("https", "www.google.com", ""));
+  EXPECT_EQ("", SpdyUtils::GetPushPromiseUrl("https", "www.google", ".com/"));
+
+  // Test acception/rejection of various input combinations.
+  // |input_headers| is an array of pairs. The first value of each pair is a
+  // string that will be used as one of the inputs of GetPushPromiseUrl(). The
+  // second value of each pair is a bitfield where the lowest 3 bits indicate
+  // for which headers that string is valid (in a PUSH_PROMISE). For example,
+  // the string "http" would be valid for both the ":scheme" and ":authority"
+  // headers, so the bitfield paired with it is set to SCHEME | AUTH.
+  const unsigned char SCHEME = (1u << 0);
+  const unsigned char AUTH = (1u << 1);
+  const unsigned char PATH = (1u << 2);
+  const std::pair<const char*, unsigned char> input_headers[] = {
+      {"http", SCHEME | AUTH},
+      {"https", SCHEME | AUTH},
+      {"hTtP", SCHEME | AUTH},
+      {"HTTPS", SCHEME | AUTH},
+      {"www.google.com", AUTH},
+      {"90af90e0", AUTH},
+      {"12foo%20-bar:00001233", AUTH},
+      {"GOO\u200b\u2060\ufeffgoo", AUTH},
+      {"192.168.0.5", AUTH},
+      {"[::ffff:192.168.0.1.]", AUTH},
+      {"http:", AUTH},
+      {"bife l", AUTH},
+      {"/", PATH},
+      {"/foo/bar/baz", PATH},
+      {"/%20-2DVdkj.cie/foe_.iif/", PATH},
+      {"http://", 0},
+      {":443", 0},
+      {":80/eddd", 0},
+      {"google.com:-0", 0},
+      {"google.com:65536", 0},
+      {"http://google.com", 0},
+      {"http://google.com:39", 0},
+      {"//google.com/foo", 0},
+      {".com/", 0},
+      {"http://www.google.com/", 0},
+      {"http://foo:439", 0},
+      {"[::ffff:192.168", 0},
+      {"]/", 0},
+      {"//", 0}};
+  for (size_t i = 0; i < QUIC_ARRAYSIZE(input_headers); ++i) {
+    bool should_accept = (input_headers[i].second & SCHEME);
+    for (size_t j = 0; j < QUIC_ARRAYSIZE(input_headers); ++j) {
+      bool should_accept_2 = should_accept && (input_headers[j].second & AUTH);
+      for (size_t k = 0; k < QUIC_ARRAYSIZE(input_headers); ++k) {
+        // |should_accept_3| indicates whether or not GetPushPromiseUrl() is
+        // expected to accept this input combination.
+        bool should_accept_3 =
+            should_accept_2 && (input_headers[k].second & PATH);
+
+        std::string url = SpdyUtils::GetPushPromiseUrl(input_headers[i].first,
+                                                       input_headers[j].first,
+                                                       input_headers[k].first);
+
+        ::testing::AssertionResult result = ::testing::AssertionSuccess();
+        if (url.empty() == should_accept_3) {
+          result = ::testing::AssertionFailure()
+                   << "GetPushPromiseUrl() accepted/rejected the inputs when "
+                      "it shouldn't have."
+                   << std::endl
+                   << "     scheme: " << input_headers[i].first << std::endl
+                   << "  authority: " << input_headers[j].first << std::endl
+                   << "       path: " << input_headers[k].first << std::endl
+                   << "Output: " << url << std::endl;
+        }
+        ASSERT_TRUE(result);
+      }
+    }
+  }
+
+  // Test canonicalization of various valid inputs.
+  EXPECT_EQ("http://www.google.com/",
+            SpdyUtils::GetPushPromiseUrl("http", "www.google.com", "/"));
+  EXPECT_EQ(
+      "https://www.goo-gle.com/fOOo/baRR",
+      SpdyUtils::GetPushPromiseUrl("hTtPs", "wWw.gOo-gLE.cOm", "/fOOo/baRR"));
+  EXPECT_EQ("https://www.goo-gle.com:3278/pAth/To/reSOurce",
+            SpdyUtils::GetPushPromiseUrl("hTtPs", "Www.gOo-Gle.Com:000003278",
+                                         "/pAth/To/reSOurce"));
+  EXPECT_EQ("https://foo%20bar/foo/bar/baz",
+            SpdyUtils::GetPushPromiseUrl("https", "foo bar", "/foo/bar/baz"));
+  EXPECT_EQ("http://foo.com:70/e/",
+            SpdyUtils::GetPushPromiseUrl("http", "foo.com:0000070", "/e/"));
+  EXPECT_EQ(
+      "http://192.168.0.1:70/e/",
+      SpdyUtils::GetPushPromiseUrl("http", "0300.0250.00.01:0070", "/e/"));
+  EXPECT_EQ("http://192.168.0.1/e/",
+            SpdyUtils::GetPushPromiseUrl("http", "0xC0a80001", "/e/"));
+  EXPECT_EQ("http://[::c0a8:1]/",
+            SpdyUtils::GetPushPromiseUrl("http", "[::192.168.0.1]", "/"));
+  EXPECT_EQ(
+      "https://[::ffff:c0a8:1]/",
+      SpdyUtils::GetPushPromiseUrl("https", "[::ffff:0xC0.0Xa8.0x0.0x1]", "/"));
+}
+
+}  // namespace test
+}  // namespace quic
