Deprecate gfe2_reloadable_flag_quic_donot_wake_up_stream_before_finish_reading_headers_v2.

PiperOrigin-RevId: 499616916
diff --git a/build/source_list.bzl b/build/source_list.bzl
index 76eb89b..f43b662 100644
--- a/build/source_list.bzl
+++ b/build/source_list.bzl
@@ -399,6 +399,8 @@
     "spdy/core/spdy_protocol.h",
     "spdy/core/spdy_simple_arena.h",
     "spdy/core/zero_copy_output_buffer.h",
+    "web_transport/mock_web_transport.h",
+    "web_transport/web_transport.h",
 ]
 quiche_core_srcs = [
     "balsa/balsa_enums.cc",
diff --git a/build/source_list.gni b/build/source_list.gni
index 78333b6..60ff738 100644
--- a/build/source_list.gni
+++ b/build/source_list.gni
@@ -399,6 +399,8 @@
     "src/quiche/spdy/core/spdy_protocol.h",
     "src/quiche/spdy/core/spdy_simple_arena.h",
     "src/quiche/spdy/core/zero_copy_output_buffer.h",
+    "src/quiche/web_transport/mock_web_transport.h",
+    "src/quiche/web_transport/web_transport.h",
 ]
 quiche_core_srcs = [
     "src/quiche/balsa/balsa_enums.cc",
diff --git a/build/source_list.json b/build/source_list.json
index 3811e8b..c8683c8 100644
--- a/build/source_list.json
+++ b/build/source_list.json
@@ -397,7 +397,9 @@
     "quiche/spdy/core/spdy_prefixed_buffer_reader.h",
     "quiche/spdy/core/spdy_protocol.h",
     "quiche/spdy/core/spdy_simple_arena.h",
-    "quiche/spdy/core/zero_copy_output_buffer.h"
+    "quiche/spdy/core/zero_copy_output_buffer.h",
+    "quiche/web_transport/mock_web_transport.h",
+    "quiche/web_transport/web_transport.h"
   ],
   "quiche_core_srcs": [
     "quiche/balsa/balsa_enums.cc",
diff --git a/quiche/web_transport/mock_web_transport.h b/quiche/web_transport/mock_web_transport.h
new file mode 100644
index 0000000..93f3309
--- /dev/null
+++ b/quiche/web_transport/mock_web_transport.h
@@ -0,0 +1,76 @@
+// Copyright 2023 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.
+
+// Pre-defined mocks for the APIs in web_transport.h.
+
+#ifndef QUICHE_WEB_TRANSPORT_MOCK_WEB_TRANSPORT_H_
+#define QUICHE_WEB_TRANSPORT_MOCK_WEB_TRANSPORT_H_
+
+#include "quiche/common/platform/api/quiche_test.h"
+#include "quiche/web_transport/web_transport.h"
+
+namespace webtransport {
+namespace test {
+
+class QUICHE_NO_EXPORT MockStreamVisitor : public StreamVisitor {
+  MOCK_METHOD(void, OnCanRead, (), (override));
+  MOCK_METHOD(void, OnCanWrite, (), (override));
+  MOCK_METHOD(void, OnResetStreamReceived, (StreamErrorCode), (override));
+  MOCK_METHOD(void, OnStopSendingReceived, (StreamErrorCode), (override));
+  MOCK_METHOD(void, OnWriteSideInDataRecvdState, (), (override));
+};
+
+class QUICHE_NO_EXPORT MockStream : public Stream {
+  MOCK_METHOD(ReadResult, Read, (absl::Span<char> buffer), (override));
+  MOCK_METHOD(ReadResult, Read, (std::string * output), (override));
+  MOCK_METHOD(bool, Write, (absl::string_view data), (override));
+  MOCK_METHOD(bool, SendFin, (), (override));
+  MOCK_METHOD(bool, CanWrite, (), (const, override));
+  MOCK_METHOD(size_t, ReadableBytes, (), (const, override));
+  MOCK_METHOD(StreamId, GetStreamId, (), (const, override));
+  MOCK_METHOD(void, ResetWithUserCode, (StreamErrorCode error), (override));
+  MOCK_METHOD(void, SendStopSending, (StreamErrorCode error), (override));
+  MOCK_METHOD(void, ResetDueToInternalError, (), (override));
+  MOCK_METHOD(void, MaybeResetDueToStreamObjectGone, (), (override));
+  MOCK_METHOD(StreamVisitor*, visitor, (), (override));
+  MOCK_METHOD(void, SetVisitor, (std::unique_ptr<StreamVisitor> visitor),
+              (override));
+};
+
+class QUICHE_NO_EXPORT MockSessionVisitor : public SessionVisitor {
+  MOCK_METHOD(void, OnSessionReady, (const spdy::Http2HeaderBlock& headers),
+              (override));
+  MOCK_METHOD(void, OnSessionClosed,
+              (SessionErrorCode error_code, const std::string& error_message),
+              (override));
+  MOCK_METHOD(void, OnIncomingBidirectionalStreamAvailable, (), (override));
+  MOCK_METHOD(void, OnIncomingUnidirectionalStreamAvailable, (), (override));
+  MOCK_METHOD(void, OnDatagramReceived, (absl::string_view datagram),
+              (override));
+  MOCK_METHOD(void, OnCanCreateNewOutgoingBidirectionalStream, (), (override));
+  MOCK_METHOD(void, OnCanCreateNewOutgoingUnidirectionalStream, (), (override));
+};
+
+class QUICHE_NO_EXPORT MockSession : public Session {
+ public:
+  MOCK_METHOD(void, CloseSession,
+              (SessionErrorCode error_code, absl::string_view error_message),
+              (override));
+  MOCK_METHOD(Stream*, AcceptIncomingBidirectionalStream, (), (override));
+  MOCK_METHOD(Stream*, AcceptIncomingUnidirectionalStream, (), (override));
+  MOCK_METHOD(bool, CanOpenNextOutgoingBidirectionalStream, (), (override));
+  MOCK_METHOD(bool, CanOpenNextOutgoingUnidirectionalStream, (), (override));
+  MOCK_METHOD(Stream*, OpenOutgoingBidirectionalStream, (), (override));
+  MOCK_METHOD(Stream*, OpenOutgoingUnidirectionalStream, (), (override));
+  MOCK_METHOD(DatagramStatus, SendOrQueueDatagram, (absl::string_view datagram),
+              (override));
+  MOCK_METHOD(size_t, GetMaxDatagramSize, (), (const, override));
+  MOCK_METHOD(void, SetDatagramMaxTimeInQueue,
+              (absl::Duration max_time_in_queue), (override));
+};
+
+}  // namespace test
+}  // namespace webtransport
+
+#endif  // QUICHE_WEB_TRANSPORT_MOCK_WEB_TRANSPORT_H_
diff --git a/quiche/web_transport/web_transport.h b/quiche/web_transport/web_transport.h
new file mode 100644
index 0000000..ce66db5
--- /dev/null
+++ b/quiche/web_transport/web_transport.h
@@ -0,0 +1,227 @@
+// Copyright (c) 2021 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.
+
+// This header contains interfaces that abstract away different backing
+// protocols for WebTransport.
+
+#ifndef QUICHE_WEB_TRANSPORT_WEB_TRANSPORT_H_
+#define QUICHE_WEB_TRANSPORT_WEB_TRANSPORT_H_
+
+#include <cstddef>
+#include <memory>
+#include <string>
+
+// The dependencies of this API should be kept minimal and independent of
+// specific transport implementations.
+#include "absl/strings/string_view.h"
+#include "absl/time/time.h"
+#include "absl/types/span.h"
+#include "quiche/common/platform/api/quiche_export.h"
+#include "quiche/spdy/core/http2_header_block.h"
+
+namespace webtransport {
+
+// A numeric ID uniquely identifying a WebTransport stream. Note that by design,
+// those IDs are not available in the Web API, and the IDs do not necessarily
+// match between client and server perspective, since there may be a proxy
+// between them.
+using StreamId = uint32_t;
+// Application-specific error code used for resetting either the read or the
+// write half of the stream.
+using StreamErrorCode = uint8_t;
+// Application-specific error code used for closing a WebTransport session.
+using SessionErrorCode = uint32_t;
+
+// An outcome of a datagram send call.
+enum class DatagramStatusCode {
+  // Datagram has been successfully sent or placed into the datagram queue.
+  kSuccess,
+  // Datagram has not been sent since the underlying QUIC connection is blocked
+  // by the congestion control.  Note that this can only happen if the queue is
+  // full.
+  kBlocked,
+  // Datagram has not been sent since it is too large to fit into a single
+  // UDP packet.
+  kTooBig,
+  // An unspecified internal error.
+  kInternalError,
+};
+
+// An outcome of a datagram send call, in both enum and human-readable form.
+struct QUICHE_EXPORT DatagramStatus {
+  explicit DatagramStatus(DatagramStatusCode code, std::string error_message)
+      : code(code), error_message(std::move(error_message)) {}
+
+  DatagramStatusCode code;
+  std::string error_message;
+};
+
+// The stream visitor is an application-provided object that gets notified about
+// events related to a WebTransport stream.  The visitor object is owned by the
+// stream itself, meaning that if the stream is ever fully closed, the visitor
+// will be garbage-collected.
+class QUICHE_EXPORT StreamVisitor {
+ public:
+  virtual ~StreamVisitor() {}
+
+  // Called whenever the stream has readable data available.
+  virtual void OnCanRead() = 0;
+  // Called whenever the stream is not write-blocked and can accept new data.
+  virtual void OnCanWrite() = 0;
+
+  // Called when RESET_STREAM is received for the stream.
+  virtual void OnResetStreamReceived(StreamErrorCode error) = 0;
+  // Called when STOP_SENDING is received for the stream.
+  virtual void OnStopSendingReceived(StreamErrorCode error) = 0;
+  // Called when the write side of the stream is closed and all of the data sent
+  // has been acknowledged ("Data Recvd" state of RFC 9000).  Primarily used by
+  // the state machine of the Web API.
+  virtual void OnWriteSideInDataRecvdState() = 0;
+};
+
+// A stream (either bidirectional or unidirectional) that is contained within a
+// WebTransport session.
+class QUICHE_EXPORT Stream {
+ public:
+  struct QUICHE_EXPORT ReadResult {
+    // Number of bytes actually read.
+    size_t bytes_read;
+    // Whether the FIN has been received; if true, no further data will arrive
+    // on the stream, and the stream object can be soon potentially garbage
+    // collected.
+    bool fin;
+  };
+
+  virtual ~Stream() {}
+
+  // Reads at most |buffer.size()| bytes into |buffer|.
+  [[nodiscard]] virtual ReadResult Read(absl::Span<char> buffer) = 0;
+  // Reads all available data and appends it to the end of |output|.
+  [[nodiscard]] virtual ReadResult Read(std::string* output) = 0;
+  // Writes |data| into the stream.  WebTransport writes are all-or-nothing: the
+  // stream will either accept all of the data (potentially buffering some of
+  // it), or reject it.  In the latter case, the method will return false, and
+  // the sender has to wait until OnCanWrite() is called.
+  [[nodiscard]] virtual bool Write(absl::string_view data) = 0;
+  // Sends the FIN on the stream.  Returns true on success.
+  [[nodiscard]] virtual bool SendFin() = 0;
+
+  // Indicates whether it is possible to write into stream right now.
+  virtual bool CanWrite() const = 0;
+  // Indicates the number of bytes that can be read from the stream.
+  virtual size_t ReadableBytes() const = 0;
+
+  // An ID that is unique within the session.  Those are not exposed to the user
+  // via the web API, but can be used internally for bookkeeping and
+  // diagnostics.
+  virtual StreamId GetStreamId() const = 0;
+
+  // Resets the read or the write side of the stream with the specified error
+  // code.
+  virtual void ResetWithUserCode(StreamErrorCode error) = 0;
+  virtual void SendStopSending(StreamErrorCode error) = 0;
+
+  // A general-purpose stream reset method that may be used when a specific
+  // error code is not available.
+  virtual void ResetDueToInternalError() = 0;
+  // If the stream has not been already reset, reset the stream. This is
+  // primarily used in the JavaScript API when the stream object has been
+  // garbage collected.
+  virtual void MaybeResetDueToStreamObjectGone() = 0;
+
+  virtual StreamVisitor* visitor() = 0;
+  virtual void SetVisitor(std::unique_ptr<StreamVisitor> visitor) = 0;
+};
+
+// Visitor that gets notified about events related to a WebTransport session.
+class QUICHE_EXPORT SessionVisitor {
+ public:
+  virtual ~SessionVisitor() {}
+
+  // Notifies the visitor when the session is ready to exchange application
+  // data.
+  virtual void OnSessionReady(const spdy::Http2HeaderBlock& headers) = 0;
+
+  // Notifies the visitor when the session has been closed.
+  virtual void OnSessionClosed(SessionErrorCode error_code,
+                               const std::string& error_message) = 0;
+
+  // Notifies the visitor when a new stream has been received.  The stream in
+  // question can be retrieved using AcceptIncomingBidirectionalStream() or
+  // AcceptIncomingUnidirectionalStream().
+  virtual void OnIncomingBidirectionalStreamAvailable() = 0;
+  virtual void OnIncomingUnidirectionalStreamAvailable() = 0;
+
+  // Notifies the visitor when a new datagram has been received.
+  virtual void OnDatagramReceived(absl::string_view datagram) = 0;
+
+  // Notifies the visitor that a new outgoing stream can now be created.
+  virtual void OnCanCreateNewOutgoingBidirectionalStream() = 0;
+  virtual void OnCanCreateNewOutgoingUnidirectionalStream() = 0;
+};
+
+// An abstract interface for a WebTransport session.
+//
+// *** AN IMPORTANT NOTE ABOUT STREAM LIFETIMES ***
+// Stream objects are managed internally by the underlying QUIC stack, and can
+// go away at any time due to the peer resetting the stream. Because of that,
+// any pointers to the stream objects returned by this class MUST NEVER be
+// retained long-term, except inside the stream visitor (the stream visitor is
+// owned by the stream object). If you need to store a reference to a stream,
+// consider one of the two following options:
+//   (1) store a stream ID,
+//   (2) store a weak pointer to the stream visitor, and then access the stream
+//       via the said visitor (the visitor is guaranteed to be alive as long as
+//       the stream is alive).
+class QUICHE_EXPORT Session {
+ public:
+  virtual ~Session() {}
+
+  // Closes the WebTransport session in question with the specified |error_code|
+  // and |error_message|.
+  virtual void CloseSession(SessionErrorCode error_code,
+                            absl::string_view error_message) = 0;
+
+  // Return the earliest incoming stream that has been received by the session
+  // but has not been accepted.  Returns nullptr if there are no incoming
+  // streams.  See the class note regarding the lifetime of the returned stream
+  // object.
+  virtual Stream* AcceptIncomingBidirectionalStream() = 0;
+  virtual Stream* AcceptIncomingUnidirectionalStream() = 0;
+
+  // Returns true if flow control allows opening a new stream.
+  //
+  // IMPORTANT: See the class note regarding the lifetime of the returned stream
+  // object.
+  virtual bool CanOpenNextOutgoingBidirectionalStream() = 0;
+  virtual bool CanOpenNextOutgoingUnidirectionalStream() = 0;
+
+  // Opens a new WebTransport stream, or returns nullptr if that is not possible
+  // due to flow control.  See the class note regarding the lifetime of the
+  // returned stream object.
+  //
+  // IMPORTANT: See the class note regarding the lifetime of the returned stream
+  // object.
+  virtual Stream* OpenOutgoingBidirectionalStream() = 0;
+  virtual Stream* OpenOutgoingUnidirectionalStream() = 0;
+
+  // Returns the WebTransport stream with the corresponding ID.
+  //
+  // IMPORTANT: See the class note regarding the lifetime of the returned stream
+  // object.
+  // TODO(vasilvv): implement this in a follow-up CL.
+  // virtual Stream* GetStreamById(StreamId id) = 0;
+
+  virtual DatagramStatus SendOrQueueDatagram(absl::string_view datagram) = 0;
+  // Returns a conservative estimate of the largest datagram size that the
+  // session would be able to send.
+  virtual uint64_t GetMaxDatagramSize() const = 0;
+  // Sets the largest duration that a datagram can spend in the queue before
+  // being silently dropped.
+  virtual void SetDatagramMaxTimeInQueue(absl::Duration max_time_in_queue) = 0;
+};
+
+}  // namespace webtransport
+
+#endif  // QUICHE_WEB_TRANSPORT_WEB_TRANSPORT_H_