Add HttpEncoder::SerializeMetadataFrameHeader().
Add HTTP/3 SETTING_ENABLE_METADATA.
Add HTTP/3 METADATA frame type.
Add HttpEncoder::SerializeMetadataFrameHeader() method to serialize METADATA frame header.
Setting identifier and frame type match HTTP/2 ones, see
quiche/spdy/core/metadata_extension.cc.
See https://github.com/envoyproxy/envoy/issues/2394 and design document linked
therein for HTTP/2 METADATA. HTTP/3 implementation will be very similar.
PiperOrigin-RevId: 457048873
diff --git a/quiche/quic/core/http/http_constants.cc b/quiche/quic/core/http/http_constants.cc
index a22620d..e429678 100644
--- a/quiche/quic/core/http/http_constants.cc
+++ b/quiche/quic/core/http/http_constants.cc
@@ -21,6 +21,7 @@
RETURN_STRING_LITERAL(SETTINGS_H3_DATAGRAM_DRAFT09);
RETURN_STRING_LITERAL(SETTINGS_WEBTRANS_DRAFT00);
RETURN_STRING_LITERAL(SETTINGS_ENABLE_CONNECT_PROTOCOL);
+ RETURN_STRING_LITERAL(SETTINGS_ENABLE_METADATA);
}
return absl::StrCat("UNSUPPORTED_SETTINGS_TYPE(", identifier, ")");
}
diff --git a/quiche/quic/core/http/http_constants.h b/quiche/quic/core/http/http_constants.h
index 9e1a696..b5dc19b 100644
--- a/quiche/quic/core/http/http_constants.h
+++ b/quiche/quic/core/http/http_constants.h
@@ -46,6 +46,7 @@
SETTINGS_WEBTRANS_DRAFT00 = 0x2b603742,
// draft-ietf-httpbis-h3-websockets
SETTINGS_ENABLE_CONNECT_PROTOCOL = 0x08,
+ SETTINGS_ENABLE_METADATA = 0x4d44,
};
// Returns HTTP/3 SETTINGS identifier as a string.
diff --git a/quiche/quic/core/http/http_encoder.cc b/quiche/quic/core/http/http_encoder.cc
index 66de89e..8091a20 100644
--- a/quiche/quic/core/http/http_encoder.cc
+++ b/quiche/quic/core/http/http_encoder.cc
@@ -261,4 +261,24 @@
return 0;
}
+QuicByteCount HttpEncoder::SerializeMetadataFrameHeader(
+ QuicByteCount payload_length, std::unique_ptr<char[]>* output) {
+ QUICHE_DCHECK_NE(0u, payload_length);
+ QuicByteCount header_length =
+ QuicDataWriter::GetVarInt62Len(payload_length) +
+ QuicDataWriter::GetVarInt62Len(
+ static_cast<uint64_t>(HttpFrameType::METADATA));
+
+ *output = std::make_unique<char[]>(header_length);
+ QuicDataWriter writer(header_length, output->get());
+
+ if (WriteFrameHeader(payload_length, HttpFrameType::METADATA, &writer)) {
+ return header_length;
+ }
+ QUIC_DLOG(ERROR)
+ << "Http encoder failed when attempting to serialize METADATA "
+ "frame header.";
+ return 0;
+}
+
} // namespace quic
diff --git a/quiche/quic/core/http/http_encoder.h b/quiche/quic/core/http/http_encoder.h
index fc5987f..0d03e69 100644
--- a/quiche/quic/core/http/http_encoder.h
+++ b/quiche/quic/core/http/http_encoder.h
@@ -65,6 +65,11 @@
// https://www.ietf.org/archive/id/draft-ietf-webtrans-http3-00.html#name-client-initiated-bidirectio
static QuicByteCount SerializeWebTransportStreamFrameHeader(
WebTransportSessionId session_id, std::unique_ptr<char[]>* output);
+
+ // Serializes a METADATA frame header into a new buffer stored in |output|.
+ // Returns the length of the buffer on success, or 0 otherwise.
+ static QuicByteCount SerializeMetadataFrameHeader(
+ QuicByteCount payload_length, std::unique_ptr<char[]>* output);
};
} // namespace quic
diff --git a/quiche/quic/core/http/http_encoder_test.cc b/quiche/quic/core/http/http_encoder_test.cc
index b6d8844..7394ab8 100644
--- a/quiche/quic/core/http/http_encoder_test.cc
+++ b/quiche/quic/core/http/http_encoder_test.cc
@@ -123,5 +123,16 @@
"WEBTRANSPORT_STREAM", buffer.get(), length, output, sizeof(output));
}
+TEST(HttpEncoderTest, SerializeMetadataFrameHeader) {
+ std::unique_ptr<char[]> buffer;
+ uint64_t length = HttpEncoder::SerializeMetadataFrameHeader(
+ /* payload_length = */ 7, &buffer);
+ char output[] = {0x40, 0x4d, // type (METADATA, 0x4d, varint encoded)
+ 0x07}; // length
+ EXPECT_EQ(ABSL_ARRAYSIZE(output), length);
+ quiche::test::CompareCharArraysWithHexError("METADATA", buffer.get(), length,
+ output, ABSL_ARRAYSIZE(output));
+}
+
} // namespace test
} // namespace quic
diff --git a/quiche/quic/core/http/http_frames.h b/quiche/quic/core/http/http_frames.h
index b96c5fb..f55881a 100644
--- a/quiche/quic/core/http/http_frames.h
+++ b/quiche/quic/core/http/http_frames.h
@@ -34,6 +34,7 @@
PRIORITY_UPDATE_REQUEST_STREAM = 0xF0700,
// https://www.ietf.org/archive/id/draft-ietf-webtrans-http3-00.html
WEBTRANSPORT_STREAM = 0x41,
+ METADATA = 0x4d,
};
// 7.2.1. DATA