nx_hpack.nx
buildroot/runtime/nx_hpack.nx
about
nx_hpack.nx -- TUTOR-BOOTSTRAP SCAFFOLD (Claude, authored under the R4-H2
HTTP/2-transport-ladder workflow), NOT credited as team self-authoring.
R4-H2-002 of the sovereign HTTP/2 transport ladder
(knowledge/specs/2026-06-13-http2-transport-ladder.md). A minimal sovereign
HPACK (RFC 7541) header-block coder: the WIRE FORMAT (N-bit-prefix integers,
length-prefixed string literals, the static table, the 6.x field
representations) is an allowed internet-boundary requirement -- the bytes are
dictated by RFC 7541 byte-for-byte so we interoperate, exactly as
nx_tls13_ext.nx emits RFC 8446 extension bytes. The IMPLEMENTATION is pure
NishiLang via nx_cc -> nxasm_x86: no gcc, no nghttp2, no third-party HPACK.
FOUNDED ON (composes, does not reinvent -- anti-orphan law): nx_str.nx (which
transitively splices nx_syscalls.nx via syscalls.nx -- so we import nx_str.nx
ONCE and inherit sys_mmap/sys_write/sys_exit; importing nx_syscalls.nx
directly TOO would be the RC6 double-import landmine). No floating
capability: HPACK is the lowest rung; the frame codec founds on it next.
ENCODER (client request side, Huffman NOT required -- servers accept raw
literals): indexed-header-field (6.1), literal-with-incremental-indexing
indexed-name + new-name (6.2.1), literal-without-indexing (6.2.2), literal
never-indexed (6.2.3), plus the N-bit-prefix integer (5.1) and the raw
(H=0) string literal (5.2). DECODER (lenient response side): N-bit-prefix
integer decode with truncation rejection, string-literal decode with length
rejection, and a static-table reverse lookup enough to read :status / walk a
header block.
BACK-FILL: the team RE-AUTHORS this from the DATA spec via the
emitter-of-emitters (X-AUT-006c/e/f) -- this hand-authored scaffold is the
sanctioned one-time bootstrap only (meter-integrity, mirror
nx_frame_codec.nx:13-16).
GATE (main): asserts byte-exact the RFC 7541 known-answers -- ยง5.1.1 INT
N=5 value 10 (0A), N=5 value 1337 (1F 9A 0A), N=8 value 42 (2A); Appendix
C.2.1 lit-inc new-name "custom-key: custom-header"; C.2.2 lit-noindex
":path: /sample/path"; C.2.3 lit-never "password: secret"; C.2.4 indexed
":method: GET" (82); C.3.1 first request (82 86 84 41 0f www.example.com);
decode round-trips; static-table lookups -- PLUS two TAMPER cases (a
truncated integer continuation and an over-long string length) that MUST be
rejected with a negative return.
dependencies 2 imports · 1 importers
imports: nx_str.nxnx_itoa_lib.nx
imported by: nx_h2_frame.nx
call flow from main pre-order; caps 40 nodes / depth 6 declared; ↻ = already shown
structs
| none |
consts
| 48 | const K_MAGIC_1337: i64 = 1337 |
functions
| 51 | func hp_puts(s: *u8) -> i64 |
| 61 | func hp_putn(v: i64) -> i64 { nxi_out(v); return 0 } |
| 68 | func hp_fdn(fd: i64, v: i64) -> i64 { nxi_fd(fd, v); return 0 } |
| 69 | func hp_puthex2(v: i64) -> i64 called by 1: hp_check_bytes |
| 90 | func hpack_encode_int(out: *u8, off: i64, prefix_bits: i64, flags: i64, value: i64) -> i64 |
| 122 | func hpack_decode_int(buf: *u8, off: i64, lim: i64, prefix_bits: i64, out_val: *i64) -> i64 |
| 158 | func hpack_encode_str_raw(out: *u8, off: i64, s: *u8, slen: i64) -> i64 |
| 173 | func hpack_decode_str(buf: *u8, off: i64, lim: i64, out_ptr: *i64, out_len: *i64, out_huff: *i64) -> i64 |
| 191 | func hpack_encode_indexed(out: *u8, off: i64, index: i64) -> i64 |
| 200 | func hpack_encode_lit_inc_indexed_name(out: *u8, off: i64, name_index: i64, val: *u8, vlen: i64) -> i64 |
| 207 | func hpack_encode_lit_inc_new_name(out: *u8, off: i64, name: *u8, nlen: i64, val: *u8, vlen: i64) -> i64 |
| 218 | func hpack_encode_lit_noindex_indexed_name(out: *u8, off: i64, name_index: i64, val: *u8, vlen: i64) -> i64 called by 3: h2_build_request_blockh2_build_request_block_uamain calls 2: hpack_encode_inthpack_encode_str_raw |
| 228 | func hpack_encode_lit_never_new_name(out: *u8, off: i64, name: *u8, nlen: i64, val: *u8, vlen: i64) -> i64 |
| 241 | func hp_eq_bytes(a: *u8, alen: i64, lit: *u8) -> i64 called by 1: hpack_static_index |
| 249 | func hpack_static_index(name: *u8, nlen: i64, val: *u8, vlen: i64) -> i64 |
| 284 | func hpack_decode_walk_field(buf: *u8, off: i64, lim: i64, out_status: *i64) -> i64 |
| 336 | func hp_check_bytes(name: *u8, got: *u8, glen: i64, exp: *u8, elen: i64) -> i64 |
| 359 | func main() -> i64 |