Project import generated by Copybara.

PiperOrigin-RevId: 237361882
Change-Id: I109a68f44db867b20f8c6a7732b0ce657133e52a
diff --git a/quic/tools/quic_simple_server_session.h b/quic/tools/quic_simple_server_session.h
new file mode 100644
index 0000000..45c97d0
--- /dev/null
+++ b/quic/tools/quic_simple_server_session.h
@@ -0,0 +1,155 @@
+// 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 toy server specific QuicSession subclass.
+
+#ifndef QUICHE_QUIC_TOOLS_QUIC_SIMPLE_SERVER_SESSION_H_
+#define QUICHE_QUIC_TOOLS_QUIC_SIMPLE_SERVER_SESSION_H_
+
+#include <stdint.h>
+
+#include <list>
+#include <memory>
+#include <set>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include "base/macros.h"
+#include "net/third_party/quiche/src/quic/core/http/quic_server_session_base.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_containers.h"
+#include "net/third_party/quiche/src/quic/tools/quic_backend_response.h"
+#include "net/third_party/quiche/src/quic/tools/quic_simple_server_backend.h"
+#include "net/third_party/quiche/src/quic/tools/quic_simple_server_stream.h"
+
+namespace quic {
+
+namespace test {
+class QuicSimpleServerSessionPeer;
+}  // namespace test
+
+class QuicSimpleServerSession : public QuicServerSessionBase {
+ public:
+  // A PromisedStreamInfo is an element of the queue to store promised
+  // stream which hasn't been created yet. It keeps a mapping between promised
+  // stream id with its priority and the headers sent out in PUSH_PROMISE.
+  struct PromisedStreamInfo {
+   public:
+    PromisedStreamInfo(spdy::SpdyHeaderBlock request_headers,
+                       QuicStreamId stream_id,
+                       spdy::SpdyPriority priority)
+        : request_headers(std::move(request_headers)),
+          stream_id(stream_id),
+          priority(priority),
+          is_cancelled(false) {}
+    spdy::SpdyHeaderBlock request_headers;
+    QuicStreamId stream_id;
+    spdy::SpdyPriority priority;
+    bool is_cancelled;
+  };
+
+  // Takes ownership of |connection|.
+  QuicSimpleServerSession(const QuicConfig& config,
+                          const ParsedQuicVersionVector& supported_versions,
+                          QuicConnection* connection,
+                          QuicSession::Visitor* visitor,
+                          QuicCryptoServerStream::Helper* helper,
+                          const QuicCryptoServerConfig* crypto_config,
+                          QuicCompressedCertsCache* compressed_certs_cache,
+                          QuicSimpleServerBackend* quic_simple_server_backend);
+  QuicSimpleServerSession(const QuicSimpleServerSession&) = delete;
+  QuicSimpleServerSession& operator=(const QuicSimpleServerSession&) = delete;
+
+  ~QuicSimpleServerSession() override;
+
+  // Override base class to detact client sending data on server push stream.
+  void OnStreamFrame(const QuicStreamFrame& frame) override;
+
+  // Send out PUSH_PROMISE for all |resources| promised stream id in each frame
+  // will increase by 2 for each item in |resources|.
+  // And enqueue HEADERS block in those PUSH_PROMISED for sending push response
+  // later.
+  virtual void PromisePushResources(
+      const QuicString& request_url,
+      const std::list<QuicBackendResponse::ServerPushInfo>& resources,
+      QuicStreamId original_stream_id,
+      const spdy::SpdyHeaderBlock& original_request_headers);
+
+  void OnCanCreateNewOutgoingStream() override;
+
+ protected:
+  // QuicSession methods:
+  QuicSpdyStream* CreateIncomingStream(QuicStreamId id) override;
+  QuicSpdyStream* CreateIncomingStream(PendingStream pending) override;
+  QuicSimpleServerStream* CreateOutgoingBidirectionalStream() override;
+  QuicSimpleServerStream* CreateOutgoingUnidirectionalStream() override;
+  // Override to return true for locally preserved server push stream.
+  void HandleFrameOnNonexistentOutgoingStream(QuicStreamId stream_id) override;
+  // Override to handle reseting locally preserved streams.
+  void HandleRstOnValidNonexistentStream(
+      const QuicRstStreamFrame& frame) override;
+
+  // QuicServerSessionBaseMethod:
+  QuicCryptoServerStreamBase* CreateQuicCryptoServerStream(
+      const QuicCryptoServerConfig* crypto_config,
+      QuicCompressedCertsCache* compressed_certs_cache) override;
+
+  QuicSimpleServerBackend* server_backend() {
+    return quic_simple_server_backend_;
+  }
+
+ private:
+  friend class test::QuicSimpleServerSessionPeer;
+
+  // Create a server push headers block by copying request's headers block.
+  // But replace or add these pseudo-headers as they are specific to each
+  // request:
+  // :authority, :path, :method, :scheme, referer.
+  // Copying the rest headers ensures they are the same as the original
+  // request, especially cookies.
+  spdy::SpdyHeaderBlock SynthesizePushRequestHeaders(
+      QuicString request_url,
+      QuicBackendResponse::ServerPushInfo resource,
+      const spdy::SpdyHeaderBlock& original_request_headers);
+
+  // Send PUSH_PROMISE frame on headers stream.
+  void SendPushPromise(QuicStreamId original_stream_id,
+                       QuicStreamId promised_stream_id,
+                       spdy::SpdyHeaderBlock headers);
+
+  // Fetch response from cache for request headers enqueued into
+  // promised_headers_and_streams_ and send them on dedicated stream until
+  // reaches max_open_stream_ limit.
+  // Called when return value of GetNumOpenOutgoingStreams() changes:
+  //    CloseStreamInner();
+  //    StreamDraining();
+  // Note that updateFlowControlOnFinalReceivedByteOffset() won't change the
+  // return value becasue all push streams are impossible to become locally
+  // closed. Since a locally preserved stream becomes remotely closed after
+  // HandlePromisedPushRequests() starts to process it, and if it is reset
+  // locally afterwards, it will be immediately become closed and never get into
+  // locally_closed_stream_highest_offset_. So all the streams in this map
+  // are not outgoing streams.
+  void HandlePromisedPushRequests();
+
+  // Keep track of the highest stream id which has been sent in PUSH_PROMISE.
+  QuicStreamId highest_promised_stream_id_;
+
+  // Promised streams which hasn't been created yet because of max_open_stream_
+  // limit. New element is added to the end of the queue.
+  // Since outgoing stream is created in sequence, stream_id of each element in
+  // the queue also increases by 2 from previous one's. The front element's
+  // stream_id is always next_outgoing_stream_id_, and the last one is always
+  // highest_promised_stream_id_.
+  QuicDeque<PromisedStreamInfo> promised_streams_;
+
+  QuicSimpleServerBackend* quic_simple_server_backend_;  // Not owned.
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_TOOLS_QUIC_SIMPLE_SERVER_SESSION_H_