huffman#
Huffman codecs for the fixed, spec-mandated codes of wire formats.
Huffman.Hpack is the canonical Huffman code of RFC 7541 appendix B:
HPACK defines it for HTTP/2 header-field string literals, and QPACK
(HTTP/3, RFC 9204 section 4.1.2) reuses it unchanged. The code is
fixed by the specification — there is no tree construction or frequency
analysis, just the published table.
Install#
opam install huffman
If opam cannot find the package, it may not yet be released in the public
opam-repository. Add the overlay repository, then install it:
$ opam repo add samoht https://tangled.org/gazagnaire.org/opam-overlay.git
$ opam update
$ opam install huffman
Usage#
Encode and decode strings with the HPACK code:
# Huffman.Hpack.encode "www.example.com" |> String.to_seq
|> Seq.map (fun c -> Printf.sprintf "%02x" (Char.code c))
|> List.of_seq |> String.concat ""
- : string = "f1e3c2e5f23a6ba0ab90f4ff"
# Huffman.Hpack.decode (Huffman.Hpack.encode "no-cache")
- : (string, [> `Msg of string ]) result = Ok "no-cache"
Malformed input — padding that is not an EOS prefix, or an explicit EOS symbol — is an error:
# Huffman.Hpack.decode "\x00"
- : (string, [> `Msg of string ]) result =
Error (`Msg "huffman: malformed HPACK-coded string")
For zero-copy writers, encode_into fills a caller-supplied buffer and
encoded_length sizes it:
# let s = "custom-key" in
let buf = Bytes.create (Huffman.Hpack.encoded_length s) in
Huffman.Hpack.encode_into buf 0 s
- : int = 8
License#
ISC; the HPACK tables and codec are adapted from anmonteiro/ocaml-h2 (BSD-3-Clause, headers preserved).