moonbitstack/moonhttp/hpack does not have a README file

    Refused

    pub(all) suberror Refused {
    Malformed(String)
    Index(got~ : Int)
    Exceeded(limit~ : Int, got~ : Int)
    } derive(Eq,
    Debug
    )

    Why a header block was refused (RFC 7541 §6): a representation that does not parse, an index naming nothing, or a size update past what the peer allowed.

    Every one of them is a connection error in HTTP/2 (RFC 9113 §4.3), because the two ends' dynamic tables have gone out of step and nothing after this point can be read.
    impl Show for Refused

    Refused::equal

    fn Refused::equal(Refused, Refused) -> Bool

    Refused::not_equal

    fn Refused::not_equal(x : Refused, y : Refused) -> Bool

    Refused::output

    fn Refused::output(self : Refused, logger : &Logger) -> Unit

    Refused::to_repr

    Refused::to_string

    fn Refused::to_string(self : Refused) -> String

    Decoder

    pub(all) struct Decoder {
    table : Table
    limit : Int
    }

    A stateful HPACK decoder: it owns a dynamic table that persists across the header blocks of a connection. limit is the peer-agreed hard cap (SETTINGS_HEADER_TABLE_SIZE) a size update may not exceed.

    Decoder::decode

    fn Decoder::decode(self : Decoder, block : BytesView) -> Array[
    Header
    ] raise Refused

    Decode one complete header block into its header list (RFC 7541 §6), mutating the dynamic table for incrementally indexed fields and size updates. Raises Malformed/Malformed on any malformed representation.

    Decoder::new

    fn Decoder::new(limit? : Int) -> Decoder

    A new decoder whose dynamic table is bounded by limit octets (also the hard cap enforced on dynamic table size updates).

    Encoder

    pub(all) struct Encoder {
    table : Table
    huffman : Bool
    }

    A stateful HPACK encoder: it owns a dynamic table mirroring the decoder's, and prefers indexed representations. huffman selects Huffman string literals when they are shorter.

    Encoder::encode

    Encode a header list into a header block (RFC 7541 §6), using indexed fields where possible and literal-with-incremental-indexing otherwise (mutating the dynamic table to mirror what the peer decoder will build). The output decodes back to the same header list via Decoder.

    Encoder::new

    fn Encoder::new(limit? : Int, huffman? : Bool) -> Encoder

    A new encoder bounded by limit octets; huffman (default true) enables the shorter-of-two string-literal heuristic.

    Table

    pub(all) struct Table {
    entries : Array[(Bytes, Bytes)]
    size : Int
    limit : Int
    }

    The HPACK dynamic table: a FIFO of recently seen (name, value) entries, newest first (entries[0]), bounded by limit octets where each entry costs name.len + value.len + 32 (RFC 7541 §4.1). Adding evicts the oldest entries until the newcomer fits; an entry larger than limit empties the table and is not stored (§4.4).

    Table::add

    fn Table::add(self : Table, name : Bytes, value : Bytes) -> Unit

    Insert (name, value) at the front, evicting oldest entries to make room. If the entry alone exceeds limit the table ends up empty (RFC 7541 §4.4).

    Table::count

    fn Table::count(self : Table) -> Int

    The number of entries currently in the dynamic table.

    Table::get

    fn Table::get(self : Table, index : Int) ->
    Header
    ?

    The field an HPACK index names, across the static and dynamic tables together (RFC 7541 §2.3.3): one through sixty-one are the static table, and everything above is this table, newest first. None when the index names nothing.

    Table::limit

    fn Table::limit(self : Table) -> Int

    The ceiling this table evicts to keep under, in octets.

    Table::new

    fn Table::new(limit? : Int) -> Table

    A new empty dynamic table bounded by limit octets (default 4096, the HTTP/2 initial SETTINGS_HEADER_TABLE_SIZE).

    Table::resize

    fn Table::resize(self : Table, limit : Int) -> Unit

    Resize the table (a dynamic table size update, RFC 7541 §4.2), evicting to fit.

    Table::size

    fn Table::size(self : Table) -> Int

    The current total size of the dynamic table in octets (§4.1 accounting).

    entry

    Look up an HPACK static-table entry by its 1-based RFC index (1..=61), returning (name, value) or None when the index is out of range.

    limit

    let limit : Int

    How many octets a dynamic table holds by default.

    Four kibibytes is the value HTTP/2 gives SETTINGS_HEADER_TABLE_SIZE before either end has said otherwise (RFC 9113 §6.5.2), so it is what both tables start at.

    read_literal

    fn read_literal(data : BytesView, offset : Int) -> (Bytes, Int) raise Refused

    Decode an HPACK string literal from data at offset, returning (octets,bytes_consumed). The length is read as a 7-bit-prefix integer (the H bit is masked off); this is the inverse of string for H = 0. Huffman decoding is not applied here, so ask @prefix.flagged first if the literal may be coded.

    read_string

    fn read_string(data : BytesView, offset : Int) -> (Bytes, Int) raise Refused

    Read an HPACK string literal at offset, resolving Huffman coding when the H bit is set, returning (octets, bytes_consumed). Unlike read_literal, this applies Huffman decoding. Raises on bad Huffman.

    size_update

    fn size_update(limit : Int) -> Bytes

    Encode a dynamic table size update (RFC 7541 §6.3): 001 prefix with the new maximum size as a 5-bit-prefix integer.

    static_table

    The static table as (name, value) octet pairs, in RFC index order (index 1 at position 0). Derived once from static_table.

    string

    fn string(octets : BytesView, huffman? : Bool) -> Bytes

    A string literal (RFC 7541 §5.2): the length as a seven-bit-prefix integer, then the octets, with the H bit saying whether they are Huffman-coded.

    huffman takes the shorter of the two forms, which is what an encoder does; false writes the octets as they are, which is what a test with a published block needs.

    A tie goes to the coded form, which is what RFC 7541's own examples do: it costs nothing and leaves less of the value legible to anything reading the connection.

    Source Files