http: HPACK, the header compression of HTTP/2 (step 1 of #72) #563
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Goal
Step 1 of #72 (HTTP/2): HPACK (RFC 7541), the header compression of HTTP/2, as a codec of its own in
std/http, with no connection, no frames and no change to what aClientor aServerdoes. Every later step of #72 reads and writes header blocks through it.Rules
A new module
std/http/src/hpack.trb(internal to the package, imported by relative path likeparse.trb):EOSincluded). Decoding refusesEOSinside a string, padding of more than 7 bits, padding that is not the most significant bits ofEOS, and an integer that does not fit in 32 bits (refused as soon as it overflows, not after reading all its continuation octets).name + value + 32octets, eviction oldest first, an entry larger than the table empties it and is not added.HpackDecoder(of(maxTableSize, maxListSize)):decode(block): Result<List<(name: String, value: String)>, HpackError>reads the representations of section 6 (indexed, literal with incremental indexing, without indexing, never indexed, dynamic table size update). Refused as a compression error: index 0, an index past the tables, a size update above the limit the decoder was given or after the first header of a block, a string that is cut off, and a decoded list overmaxListSize(the sum ofname + value + 32per RFC 9113 section 6.5.2, counted while decoding so a large block does not allocate first).setMaxTableSize(size)is how a SETTINGS change reaches it (the shrink is applied at once, the encoder must announce it).HpackEncoder(of(maxTableSize)):encode(fields): Buffer<UInt8>. Encoder policy, decided by the loop: a full match in a table is an indexed field; otherwise a literal with incremental indexing, exceptauthorization,proxy-authorization,cookieandset-cookie, which are sent never indexed (section 7.1.3, as Go'snet/http2does); a string is Huffman-coded only where that is shorter. Names are lower-cased by the caller's contract (RFC 9113 section 8.2.1): the encoder refuses an upper-case name withHpackError.setMaxTableSize(size)shrinks the table and emits the required size update at the start of the next block (the smallest size in between first, then the final one, section 4.2).HpackErroris a type of its own withisCompressionError(); mapping it toCOMPRESSION_ERROR(a connection error, RFC 9113 section 4.3) is the connection's job in a later step.Acceptance criteria
std/http/tests/hpack.test.trb(VM and--native, as the otherstd/http/tests):setMaxTableSizeshrinking with the pending update, a size update above the limit refused.(name, value)is enough for the callers of later steps, the flag is a documented, tested detail ofHpackDecoder).maxListSizestops a decode of an oversized block before the whole list exists.tools/gates.sh aandbgreen in forge CI. NETWORK.md section 12 gets an "as built" paragraph for HPACK and slice 12's row says "Partly done: HPACK (step 1 of #72)"; FIRST-PARTY.md gap 25 gets the same note (it stays open);skills/regenerated if the docs change reaches them.Design record / seed
Implements NETWORK.md slice 12 (HTTP/2). Seed: no (std only, no syntax, no native, no string lookup by the compiler).
Size
One PR, two Conventional Commits:
feat(http): HPACK integers, strings and the Huffman code, thenfeat(http): HPACK header blocks with the dynamic table(with the docs).Dependencies
#118 (landed). Part of #72; steps 2 to 6 of #72 follow just in time.
[loop:torbscript] claim implement by session:loop-torbscript-20261029 until 2026-10-29T09:50:16Z
[loop:torbscript] implement: HPACK (std/http/src/hpack.trb, two commits) is up as #564 (Closes #563). Locally clean in the nightly VM (64 tests, format, doc and panics checks, skills up to date); on forge CI the commit-message, scope, runner, pdisc and bootstrap jobs are green, gates and tier A were still queued after 25 minutes. Decision to check in review: encode answers Result<Bytes, HpackError> because of the upper-case-name refusal, and a Huffman string is used only where strictly shorter. next: waiting (forge CI on PR #564: gates, tier A)