hpack
import hpack from "hpack";
import str from "str";
var d: hpack.Decoder = hpack.decoder(4096);
defer d.free();
var fields: hpack.Vec_Header = hpack.vec_Header_new();
defer fields.free();
d.decode(block, 65536, &fields) or { return 1; }; // block: a HEADERS frame's header block
for (i in 0..fields.len()) { io.println("{fields.get_ref(i).name}: {fields.get_ref(i).value}"); }
var out: str.Builder = str.builder();
defer out.free();
hpack.encode_table_reset(&out); // first block of a connection
hpack.encode(&out, ":status", "200", false);
hpack.encode(&out, "set-cookie", "id=42", true); // never indexedhpack reads and writes the header blocks of HTTP/2
(RFC 7541). You don’t need it to
make requests: http’s Client uses it through
h2. It is here for code that handles HTTP/2 frames itself, a
test server for instance.
| Function | Does |
|---|---|
decoder(limit) -> Decoder | A decoder whose dynamic table may grow to limit octets (what your SETTINGS_HEADER_TABLE_SIZE says; 4096 is the default) |
d.decode(block, max_list, out) | Decodes one whole block (HEADERS and its CONTINUATIONs), appending its fields to out in order |
d.entries(), d.table_size() | The dynamic table’s entries and size in octets |
d.free() | Releases the table |
encode(out, name, value, sensitive) | One field: a static table index when there is one for both, else a literal (never indexed when sensitive) |
encode_table_reset(out) | A table size update to 0: put it first in a connection’s first block |
huffman_encode, huffman_decode, huffman_len | The Huffman code of Appendix B |
write_int, write_string | HPACK’s integers and string literals |
pub struct Header { name: string; value: string; }
pub enum HpackError : u8 { Truncated = 1; BadIndex = 2; BadInteger = 3; BadHuffman = 4; BadTableSize = 5; TooLarge = 6; }A decoder belongs to one connection: blocks must be decoded in the order
they came, every one of them, since each may change the table the next
ones refer to. max_list limits the list as
SETTINGS_MAX_HEADER_LIST_SIZE counts it (each field’s name and value
plus 32): past it, the rest of the block is still decoded (the table stays
right) but its fields are not kept, and decode returns TooLarge. Any
other error means the table can no longer be trusted: end the connection.
The encoder keeps no table of its own, so it needs no state: each field is encoded on its own, and a string is Huffman coded when that makes it shorter. Names must be lowercase, as HTTP/2 requires.
Last modified: