Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

http.h2.hpack

import http

http exposes this as http.h2.hpack, so import http is enough and the names are called as http.h2.hpack.*. import http.h2.hpack reaches 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

FieldTypeDescription
table
max_string_lengthnumberThe largest single string literal accepted.
max_header_list_sizenumberThe 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