ProtoCore v1.0.16
Deterministic, zero-heap network stack for embedded targets
Loading...
Searching...
No Matches
qpack.h
Go to the documentation of this file.
1// ProtoCore v1.0.16 - Copyright (C) 2026 Douglas Quigg (dstroy0) <dquigg123@gmail.com>
2// SPDX-License-Identifier: AGPL-3.0-or-later
3
4#ifndef PROTOCORE_QPACK_H
5#define PROTOCORE_QPACK_H
6
7#include "protocore_config.h" // the entry point: protocore_types.h for the widths
8
10
11/**
12 * @file qpack.h
13 * @brief QPACK field-section compression for HTTP/3 (RFC 9204).
14 *
15 * QPACK is HTTP/3's header compression. It reuses RFC 7541's prefix-integer coding and Huffman
16 * code (shared here via protocore_hpack_prim.h) and adds a 99-entry static table, an encoded field-section
17 * prefix, and its own field-line representations.
18 *
19 * This codec is static-table-only and needs no per-connection state: the encoder emits indexed /
20 * literal representations against the static table (never inserting into a dynamic table), and it
21 * advertises SETTINGS_QPACK_MAX_TABLE_CAPACITY = 0, so a conformant peer's encoder never sends a
22 * dynamic-table reference. The decoder therefore rejects (returns false) any representation that
23 * references the dynamic table or a non-zero Required Insert Count. Pure, zero heap, host-tested
24 * against the RFC 9204 Appendix B.1 worked example.
25 *
26 * @c work is bytes the CALLER holds. This module reads none of them: it carries nothing
27 * between calls, so there is no state to keep and nothing to wipe. The parameter is there so
28 * a caller drives every namespace the same way.
29 *
30 * @author Douglas Quigg (dstroy0)
31 * @date 2026
32 */
33
34// PROTOCORE_QPACK_BORROW - the bytes this module runs out of - is stated in protocore_config.h, which sums
35// it into its arena. Its size and its offset are each a static_assert, so a feature
36// combination that does not fit fails to compile rather than overrunning at run time.
37
38/** @brief Callback invoked for each decoded header; return false to abort the decode. */
39typedef proto_bool (*QpackEmitFn)(void *ctx, const char *name, size_t name_len, const char *value, size_t value_len);
40
41/** @brief Dispatch table. Addressed by offset, so the layout is asserted below. */
42typedef struct
43{
44 size_t (*encode_prefix)(uint8_t *, uint8_t *, size_t);
45 size_t (*encode_header)(uint8_t *, uint8_t *, size_t, const char *, size_t, const char *, size_t);
46 proto_bool (*decode)(uint8_t *, const uint8_t *, size_t, char *, size_t, QpackEmitFn, void *);
47} QpackNs;
48PROTOCORE_NS_LAYOUT(QpackNs, encode_prefix, encode_header, decode);
49
50/**
51 * @brief Write the encoded field-section prefix for a static-only section. .
52 * @param work PROTOCORE_QPACK_BORROW bytes the caller took. Not held past the call.
53 * @param out Out
54 * @param cap Cap
55 * @return The size_t.
56 */
57size_t protocore_qpack_encode_prefix(uint8_t *work, uint8_t *out, size_t cap);
58/**
59 * @brief Encode one header field (server side): a full static match -> .
60 * @param work PROTOCORE_QPACK_BORROW bytes the caller took. Not held past the call.
61 * @param out Out
62 * @param cap Cap
63 * @param name Name
64 * @param name_len Name len
65 * @param value Value
66 * @param value_len Value len
67 * @return The size_t.
68 */
69size_t protocore_qpack_encode_header(uint8_t *work, uint8_t *out, size_t cap, const char *name, size_t name_len,
70 const char *value, size_t value_len);
71/**
72 * @brief Decode a whole QPACK field section (prefix + representations), .
73 * @param work PROTOCORE_QPACK_BORROW bytes the caller took. Not held past the call.
74 * @param block Block
75 * @param len Len
76 * @param scratch caller buffer holding one header's name+value during each emit call
77 * @param scratch_cap Scratch cap
78 * @param emit Emit
79 * @param ctx Ctx
80 * @return PROTO_TRUE on success.
81 */
82proto_bool protocore_qpack_decode(uint8_t *work, const uint8_t *block, size_t len, char *scratch, size_t scratch_cap,
83 QpackEmitFn emit, void *ctx);
84
85/** @brief Callback invoked for each decoded header; return false to abort the decode. */
86typedef proto_bool (*QpackEmitFn)(void *ctx, const char *name, size_t name_len, const char *value, size_t value_len);
87
88/** @brief Module namespace. */
92
94
95#endif // PROTOCORE_QPACK_H
#define PROTOCORE_NS_LAYOUT(T,...)
Pin every dispatch slot of a table that is nothing but function pointers.
#define PROTOCORE_NS
Storage for a dispatch table. The const is load bearing.
proto_bool protocore_qpack_decode(uint8_t *work, const uint8_t *block, size_t len, char *scratch, size_t scratch_cap, QpackEmitFn emit, void *ctx)
Decode a whole QPACK field section (prefix + representations), .
PROTOCORE_NS QpackNs Qpack PROTOCORE_UNUSED
Module namespace.
Definition qpack.h:89
size_t protocore_qpack_encode_header(uint8_t *work, uint8_t *out, size_t cap, const char *name, size_t name_len, const char *value, size_t value_len)
Encode one header field (server side): a full static match -> .
size_t protocore_qpack_encode_prefix(uint8_t *work, uint8_t *out, size_t cap)
Write the encoded field-section prefix for a static-only section. .
proto_bool(* QpackEmitFn)(void *ctx, const char *name, size_t name_len, const char *value, size_t value_len)
Callback invoked for each decoded header; return false to abort the decode.
Definition qpack.h:39
Dispatch table. Addressed by offset, so the layout is asserted below.
Definition qpack.h:43
size_t(* encode_prefix)(uint8_t *, uint8_t *, size_t)
Definition qpack.h:44
#define PROTOCORE_BEGIN_DECLS
Give a header's declarations C linkage, so their symbol names carry no parameter types.
Definition types.h:96
_Bool proto_bool
The truth value.
Definition types.h:64
#define PROTOCORE_END_DECLS
Definition types.h:97