Project import generated by Copybara.

PiperOrigin-RevId: 237361882
Change-Id: I109a68f44db867b20f8c6a7732b0ce657133e52a
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