DeterministicESPAsyncWebServer v6.27.1
Zero-allocation, bounded-execution async HTTP server for ESP32
Loading...
Searching...
No Matches
qpack.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 qpack.h
6 * @brief QPACK field-section compression for HTTP/3 (RFC 9204).
7 *
8 * QPACK is HTTP/3's header compression. It reuses RFC 7541's prefix-integer coding and Huffman
9 * code (shared here via hpack_prim.h) and adds a 99-entry static table, an encoded field-section
10 * prefix, and its own field-line representations.
11 *
12 * This codec is static-table-only and needs no per-connection state: the encoder emits indexed /
13 * literal representations against the static table (never inserting into a dynamic table), and it
14 * advertises SETTINGS_QPACK_MAX_TABLE_CAPACITY = 0, so a conformant peer's encoder never sends a
15 * dynamic-table reference. The decoder therefore rejects (returns false) any representation that
16 * references the dynamic table or a non-zero Required Insert Count. Pure, zero heap, host-tested
17 * against the RFC 9204 Appendix B.1 worked example.
18 *
19 * @author Douglas Quigg (dstroy0)
20 * @date 2026
21 */
22
23#ifndef DETERMINISTICESPASYNCWEBSERVER_QPACK_H
24#define DETERMINISTICESPASYNCWEBSERVER_QPACK_H
25
26#include "ServerConfig.h"
27
28#if DETWS_ENABLE_HTTP3
29
30#include <stddef.h>
31#include <stdint.h>
32
33/** @brief Callback invoked for each decoded header; return false to abort the decode. */
34typedef bool (*QpackEmitFn)(void *ctx, const char *name, size_t name_len, const char *value, size_t value_len);
35
36/**
37 * @brief Write the encoded field-section prefix for a static-only section.
38 * Required Insert Count = 0, Base = 0 -> the two bytes {0x00, 0x00} (RFC 9204 sec 4.5.1).
39 * @return bytes written (2), or 0 if @p cap < 2.
40 */
41size_t qpack_encode_prefix(uint8_t *out, size_t cap);
42
43/**
44 * @brief Encode one header field (server side): a full static match -> Indexed Field Line; a name
45 * match -> Literal Field Line with (static) Name Reference; otherwise Literal Field Line with
46 * Literal Name. Strings are Huffman-coded when that is not longer.
47 * @return bytes written, or 0 on overflow. A complete field section is qpack_encode_prefix()
48 * followed by one qpack_encode_header() per field.
49 */
50size_t qpack_encode_header(uint8_t *out, size_t cap, const char *name, size_t name_len, const char *value,
51 size_t value_len);
52
53/**
54 * @brief Decode a whole QPACK field section (prefix + representations), emitting each header.
55 * @param scratch caller buffer holding one header's name+value during each emit call.
56 * @return true if the section decoded cleanly; false on malformed input, overflow, or any
57 * dynamic-table reference (indexed/literal post-base, dynamic name/index, or non-zero RIC).
58 */
59bool qpack_decode(const uint8_t *block, size_t len, char *scratch, size_t scratch_cap, QpackEmitFn emit, void *ctx);
60
61#endif // DETWS_ENABLE_HTTP3
62#endif // DETERMINISTICESPASYNCWEBSERVER_QPACK_H
User-facing configuration for DeterministicESPAsyncWebServer.