Fix a potential Http2WriteQueue overflow scenario.

This CL addresses the overflow scenario described in cl/608648082 by adding two
bytes of HPACK per-header overhead when estimating the serialized size in bytes
of a HEADERS frame. In particular, the length of a header name will be expected
to fit within 2 bytes (vs. 1 byte before), and the length of a header value
will be expected to fit within 3 bytes (vs. 2 bytes before).

Protected by FLAGS_gfe2_reloadable_flag_http2_add_hpack_overhead_bytes.

PiperOrigin-RevId: 610447560
diff --git a/quiche/quic/core/quic_flags_list.h b/quiche/quic/core/quic_flags_list.h
index 9c116cb..e565066 100644
--- a/quiche/quic/core/quic_flags_list.h
+++ b/quiche/quic/core/quic_flags_list.h
@@ -35,6 +35,8 @@
 QUIC_FLAG(quic_reloadable_flag_quic_block_until_settings_received_copt, true)
 // If trrue, early return before write control frame in OnCanWrite() if the connection is already closed.
 QUIC_FLAG(quic_reloadable_flag_quic_no_write_control_frame_upon_connection_close, true)
+// If true, HTTP/2 HEADERS frames will use two additional bytes of HPACK overhead per header in their SpdyFrameIR::size() estimate.
+QUIC_FLAG(quic_reloadable_flag_http2_add_hpack_overhead_bytes, true)
 // If true, QUIC server will not respond to gQUIC probing packet(PING + PADDING) but treat it as a regular packet.
 QUIC_FLAG(quic_reloadable_flag_quic_ignore_gquic_probing, true)
 // If true, QUIC will default enable MTU discovery at server, with a target of 1450 bytes.
diff --git a/quiche/spdy/core/spdy_protocol.cc b/quiche/spdy/core/spdy_protocol.cc
index fc5f43d..1e5dd9e 100644
--- a/quiche/spdy/core/spdy_protocol.cc
+++ b/quiche/spdy/core/spdy_protocol.cc
@@ -15,6 +15,8 @@
 #include "absl/strings/str_cat.h"
 #include "absl/strings/string_view.h"
 #include "quiche/common/platform/api/quiche_bug_tracker.h"
+#include "quiche/common/platform/api/quiche_flag_utils.h"
+#include "quiche/common/platform/api/quiche_flags.h"
 #include "quiche/common/platform/api/quiche_logging.h"
 #include "quiche/spdy/core/http2_header_block.h"
 #include "quiche/spdy/core/spdy_alt_svc_wire_format.h"
@@ -473,9 +475,16 @@
     size += 5;
   }
 
+  // TODO(b/322146543): Remove `hpack_overhead` with deprecation of
+  // --gfe2_reloadable_flag_http2_add_hpack_overhead_bytes.
+  size_t hpack_overhead = kPerHeaderHpackOverheadOld;
+  if (GetQuicheReloadableFlag(http2, http2_add_hpack_overhead_bytes)) {
+    QUICHE_RELOADABLE_FLAG_COUNT(http2_add_hpack_overhead_bytes);
+    hpack_overhead = kPerHeaderHpackOverheadNew;
+  }
   // Assume no hpack encoding is applied.
-  size += header_block().TotalBytesUsed() +
-          header_block().size() * kPerHeaderHpackOverhead;
+  size +=
+      header_block().TotalBytesUsed() + header_block().size() * hpack_overhead;
   if (size > kHttp2MaxControlFrameSendSize) {
     size += GetNumberRequiredContinuationFrames(size) *
             kContinuationFrameMinimumSize;
diff --git a/quiche/spdy/core/spdy_protocol.h b/quiche/spdy/core/spdy_protocol.h
index 36268b0..8501c94 100644
--- a/quiche/spdy/core/spdy_protocol.h
+++ b/quiche/spdy/core/spdy_protocol.h
@@ -331,10 +331,21 @@
 inline constexpr int32_t kInitialSessionWindowSize = 64 * 1024 - 1;
 // The NPN string for HTTP2, "h2".
 QUICHE_EXPORT extern const char* const kHttp2Npn;
+// An estimate of the HPACK overhead for each header field in bytes, intended to
+// be no smaller than actual overhead, based on the literal header field
+// representation in RFC 7541 Section 6.2 (with or without indexing):
+//   - 1 byte for the opcode.
+//   - 2 bytes for the name length (assuming new name).
+//   - 3 bytes for the value length.
+// TODO(b/322146543): Remove the `New` suffix with deprecation of
+// --gfe2_reloadable_flag_http2_add_hpack_overhead_bytes.
+inline constexpr size_t kPerHeaderHpackOverheadNew = 6;
 // An estimate size of the HPACK overhead for each header field. 1 bytes for
 // indexed literal, 1 bytes for key literal and length encoding, and 2 bytes for
 // value literal and length encoding.
-inline constexpr size_t kPerHeaderHpackOverhead = 4;
+// TODO(b/322146543): Remove with deprecation of
+// --gfe2_reloadable_flag_http2_add_hpack_overhead_bytes.
+inline constexpr size_t kPerHeaderHpackOverheadOld = 4;
 
 // Names of pseudo-headers defined for HTTP/2 requests.
 QUICHE_EXPORT extern const char* const kHttp2AuthorityHeader;