http.h2.hpack
import http
httpexposes this ashttp.h2.hpack, soimport httpis enough and the names are called ashttp.h2.hpack.*.import http.h2.hpackreaches the same definitions directly.
HPACK, the header compression HTTP/2 uses (RFC 7541).
A header block is a sequence of representations, each of which either names an entry of a table both endpoints maintain, or spells a field out. The static table below is fixed by the RFC; the dynamic table is built as a connection runs, which is what makes the decoder stateful - a block cannot be decoded without every block that came before it on the same connection.
The encoder here uses the static table where it can and literals everywhere else, and never adds to its own dynamic table. That gives up some compression and buys a great deal: an encoder with no dynamic table cannot desynchronise from a peer’s decoder, and it cannot leak one request’s secrets into another’s compression ratio, which is the whole of the CRIME family of attacks.
Functions
encode_integer()
http.h2.hpack.encode_integer(out, value: number, prefix_bits: number, first: number)
Encodes an integer with an prefix_bits-wide prefix, per RFC 7541 §5.1.
first is whatever flag bits share that first byte.
Parameters
out(bytes)value(number)prefix_bits(number)first(number) — the flag bits, already shifted into place
decode_integer()
http.h2.hpack.decode_integer(data, offset: number, prefix_bits: number)
Decodes an integer with an prefix_bits-wide prefix, starting at
offset.
Parameters
data(bytes)offset(number)prefix_bits(number)
Returns — list: [value, next offset]
Raises ProtocolError if the encoding runs off the end or is
absurdly long
encode_string()
http.h2.hpack.encode_string(out, text: string)
Encodes a string literal, Huffman-coding it when that comes out shorter.
Parameters
out(bytes)text(string)
decode_string()
http.h2.hpack.decode_string(data, offset: number, max_length: number)
Decodes a string literal starting at offset.
Parameters
data(bytes)offset(number)max_length(number) — refuse a literal longer than this
Returns — list: [text, next offset]
Raises ProtocolError on a truncated or over-long literal
Classes
DynamicTable
class http.h2.hpack.DynamicTable
The dynamic table half of an HPACK context: the most recently inserted fields, evicted from the far end when the table would exceed the size its owner has been told to keep.
Entries are indexed from the newest, and continue the numbering where the static table stops, so index 62 is always the most recently added entry.
Constructor
http.h2.hpack.DynamicTable(capacity)
Parameters
capacity(?number) — the maximum table size in bytes; defaults to HPACK’s own default of 4096
DynamicTable.add()
http.h2.hpack.DynamicTable.add(name: string, value: string)
Adds a field, evicting from the oldest end until it fits.
An entry larger than the whole table is not an error: RFC 7541 §4.4 says to empty the table and add nothing, which is what happens here.
Parameters
name(string)value(string)
DynamicTable.get()
http.h2.hpack.DynamicTable.get(index: number)
The entry at HPACK index index, which counts the static table first.
Parameters
index(number)
Returns — list: [name, value]
Raises ProtocolError if the index names nothing
DynamicTable.set_capacity()
http.h2.hpack.DynamicTable.set_capacity(capacity: number)
Changes the table’s maximum size, evicting whatever no longer fits.
Parameters
capacity(number)
DynamicTable.capacity()
http.h2.hpack.DynamicTable.capacity() -> number
The table’s current maximum size in bytes.
Returns number
DynamicTable.size()
http.h2.hpack.DynamicTable.size() -> number
How many bytes the entries currently occupy, by HPACK’s accounting (name plus value plus 32 per entry).
Returns number
DynamicTable.length()
http.h2.hpack.DynamicTable.length() -> number
How many entries the table holds.
Returns number
Decoder
class http.h2.hpack.Decoder
Decodes header blocks for one direction of one connection.
A decoder is stateful and order-dependent: it must see every header block on its connection, in order, or its dynamic table drifts out of step with the peer’s encoder and every block after that decodes to nonsense.
Fields
| Field | Type | Description |
|---|---|---|
table | ||
max_string_length | number | The largest single string literal accepted. |
max_header_list_size | number | The largest decoded header list accepted, by HPACK’s own size accounting. |
Constructor
http.h2.hpack.Decoder(capacity)
Parameters
capacity(?number) — the initial dynamic table size
Decoder.decode()
http.h2.hpack.Decoder.decode(block) -> list
Decodes a complete header block into a list of [name, value] pairs, in
the order they appeared - which HTTP/2 depends on, as repeated fields
keep their order and Set-Cookie may appear many times.
Parameters
block(bytes)
Returns list
Raises ProtocolError on a malformed block or one that exceeds a
limit
Encoder
class http.h2.hpack.Encoder
Encodes header blocks for one direction of one connection.
Fields are matched against the static table, and anything not found there is written out as a literal without indexing - see the module note above for why the dynamic table is left empty.
Constructor
http.h2.hpack.Encoder(capacity)
Encoder.set_capacity()
http.h2.hpack.Encoder.set_capacity(capacity: number)
Notes the maximum dynamic table size the peer will accept.
Parameters
capacity(number)
Encoder.encode()
http.h2.hpack.Encoder.encode(fields: list) -> bytes
Encodes a list of [name, value] pairs into a header block.
Names must already be lowercase; HTTP/2 has no other kind.
Parameters
fields(list)
Returns bytes
2026, Richard Ore and Zuri contributors