DeterministicESPAsyncWebServer v6.27.1
Zero-allocation, bounded-execution async HTTP server for ESP32
Loading...
Searching...
No Matches
h3_frame.h
Go to the documentation of this file.
1// Copyright (C) 2026 Douglas Quigg (dstroy0) <dquigg123@gmail.com>
2// SPDX-License-Identifier: AGPL-3.0-or-later
3
4/**
5 * @file h3_frame.h
6 * @brief HTTP/3 framing (RFC 9114 sec 7) over QUIC varints.
7 *
8 * An HTTP/3 frame is `Type (varint) | Length (varint) | Frame Payload`. This module parses that
9 * header and builds the frames a server uses (DATA, HEADERS carrying a QPACK field section,
10 * SETTINGS, GOAWAY), reads a SETTINGS payload, and flags the reserved HTTP/2 frame types that
11 * must be treated as a connection error. Pure and host-tested.
12 *
13 * @author Douglas Quigg (dstroy0)
14 * @date 2026
15 */
16
17#ifndef DETERMINISTICESPASYNCWEBSERVER_H3_FRAME_H
18#define DETERMINISTICESPASYNCWEBSERVER_H3_FRAME_H
19
20#include "ServerConfig.h"
21
22#if DETWS_ENABLE_HTTP3
23
24#include <stddef.h>
25#include <stdint.h>
26
27/** @brief HTTP/3 frame types (RFC 9114 sec 7.2 / 11.2.1). */
28struct H3FrameType
29{
30 static constexpr uint8_t H3_DATA = 0x00;
31 static constexpr uint8_t H3_HEADERS = 0x01;
32 static constexpr uint8_t H3_CANCEL_PUSH = 0x03;
33 static constexpr uint8_t H3_SETTINGS = 0x04;
34 static constexpr uint8_t H3_PUSH_PROMISE = 0x05;
35 static constexpr uint8_t H3_GOAWAY = 0x07;
36 static constexpr uint8_t H3_MAX_PUSH_ID = 0x0d;
37};
38
39/** @brief SETTINGS parameter identifiers (RFC 9114 sec 7.2.4.1 + RFC 9204). */
40struct H3Setting
41{
42 static constexpr uint8_t H3_SETTINGS_QPACK_MAX_TABLE_CAPACITY = 0x01;
43 static constexpr uint8_t H3_SETTINGS_MAX_FIELD_SECTION_SIZE = 0x06;
44 static constexpr uint8_t H3_SETTINGS_QPACK_BLOCKED_STREAMS = 0x07;
45};
46
47/** @brief A parsed frame header (payload begins at buf + header_len). */
48struct H3Frame
49{
50 uint64_t type; ///< frame type
51 uint64_t length; ///< payload length
52 size_t header_len; ///< bytes of the type + length varints
53};
54
55/** @brief The settings we track, with defaults after h3_settings_defaults(). */
56struct H3Settings
57{
58 uint64_t qpack_max_table_capacity; ///< default 0
59 uint64_t max_field_section_size; ///< default "unlimited"
60 uint64_t qpack_blocked_streams; ///< default 0
61};
62
63/** @brief Parse a frame header (type + length varints) at @p buf. @return false if truncated. */
64bool h3_frame_parse(const uint8_t *buf, size_t len, H3Frame *out);
65
66/** @brief Write a frame header (type + length varints). @return bytes written, or 0 on overflow. */
67size_t h3_frame_write_header(uint8_t *out, size_t cap, uint64_t type, uint64_t length);
68
69/** @brief True if @p type is a reserved HTTP/2 frame type (0x02/0x06/0x08/0x09) - a connection error. */
70bool h3_frame_type_reserved(uint64_t type);
71
72/** @brief Fill @p s with the RFC default settings. */
73void h3_settings_defaults(H3Settings *s);
74/** @brief Apply a SETTINGS payload (id, value varint pairs) to @p s. @return false if malformed. */
75bool h3_parse_settings(const uint8_t *payload, size_t len, H3Settings *s);
76
77// --- Frame builders (write a complete frame including its header) -----------------------------
78
79/** @brief DATA frame wrapping @p data. */
80size_t h3_build_data(uint8_t *out, size_t cap, const uint8_t *data, size_t len);
81/** @brief HEADERS frame wrapping a QPACK-encoded field section @p block. */
82size_t h3_build_headers(uint8_t *out, size_t cap, const uint8_t *block, size_t len);
83/** @brief SETTINGS frame from @p n (id, value) pairs. */
84size_t h3_build_settings(uint8_t *out, size_t cap, const uint64_t *ids, const uint64_t *vals, size_t n);
85/** @brief GOAWAY frame carrying @p stream_id (RFC 9114 sec 7.2.6). */
86size_t h3_build_goaway(uint8_t *out, size_t cap, uint64_t stream_id);
87
88#endif // DETWS_ENABLE_HTTP3
89#endif // DETERMINISTICESPASYNCWEBSERVER_H3_FRAME_H
User-facing configuration for DeterministicESPAsyncWebServer.