Class HpackDecoder

java.lang.Object
io.github.mahmoudimus.http2.HpackDecoder

public final class HpackDecoder extends Object
Decodes HPACK field blocks (RFC 7541). One decoder per connection direction, fed every field block the peer sends, in order: each block can change the dynamic table the next one refers to. Not thread-safe.

 HpackDecoder hpack = new HpackDecoder();
 List<HeaderField> fields = hpack.decode(headers.streamId(), headers.fieldBlock());
 

Limits, so a peer cannot make it use much memory or time (the "HPACK bomb"):

  • setMaxHeaderTableSize(int): the SETTINGS_HEADER_TABLE_SIZE this endpoint advertised (default 4096). A dynamic table size update above it is a COMPRESSION_ERROR.
  • setMaxHeaderListSize(long): SETTINGS_MAX_HEADER_LIST_SIZE, the decoded size of a field section, counting 32 octets per field (default 64 KiB). Exceeding it raises HeaderListSizeException, a stream error, after the whole block has been processed so the dynamic table stays in step; fields past the limit are not kept.
  • setMaxStringLength(int): the longest name or value, before or after Huffman decoding (default 64 KiB); a longer one is a connection error ENHANCE_YOUR_CALM.

Any other malformed input is a connection error COMPRESSION_ERROR (RFC 9113 §4.3): an index outside the tables, an integer over 2^31-1, a string running past the block, bad Huffman padding or EOS, a size update after the first field or missing when one is required. After a connection error the decoder's state is undefined and the connection must be closed.

  • Field Summary

    Fields
    Modifier and Type
    Field
    Description
    static final long
    The default decoded field section limit, including per-field overhead, in octets.
    static final int
    The default maximum encoded or decoded string length in octets.
  • Constructor Summary

    Constructors
    Constructor
    Description
    A decoder with the protocol's initial table size, 4096.
    HpackDecoder(int maxHeaderTableSize)
    A decoder whose dynamic table starts with the given maximum size, which both sides must already agree on: in HTTP/2, 4096 (the initial SETTINGS_HEADER_TABLE_SIZE).
  • Method Summary

    Modifier and Type
    Method
    Description
    decode(int streamId, byte[] block)
    Decodes a complete HPACK field block.
    decode(int streamId, byte[] block, int offset, int length)
    Decodes one complete field block.
    int
    The current maximum size of the dynamic table, as last set by the peer's encoder.
    dynamicTableEntry(int index)
    A dynamic table entry, 1 being the newest (HPACK index 62).
    int
    The number of entries in the dynamic table.
    int
    The current size of the dynamic table in octets (entries plus 32 each).
    long
    Returns the decoded field section limit.
    int
    Returns the advertised dynamic table limit.
    void
    setMaxHeaderListSize(long maxHeaderListSize)
    SETTINGS_MAX_HEADER_LIST_SIZE: the largest decoded field section accepted.
    void
    setMaxHeaderTableSize(int maxHeaderTableSize)
    Sets the largest dynamic table the peer's encoder may use: call this when the peer acknowledges a SETTINGS frame that carried SETTINGS_HEADER_TABLE_SIZE.
    void
    setMaxStringLength(int maxStringLength)
    The longest name or value accepted, in octets.

    Methods inherited from class java.lang.Object

    clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
  • Field Details

    • DEFAULT_MAX_HEADER_LIST_SIZE

      public static final long DEFAULT_MAX_HEADER_LIST_SIZE
      The default decoded field section limit, including per-field overhead, in octets.
      See Also:
    • DEFAULT_MAX_STRING_LENGTH

      public static final int DEFAULT_MAX_STRING_LENGTH
      The default maximum encoded or decoded string length in octets.
      See Also:
  • Constructor Details

    • HpackDecoder

      public HpackDecoder()
      A decoder with the protocol's initial table size, 4096.
    • HpackDecoder

      public HpackDecoder(int maxHeaderTableSize)
      A decoder whose dynamic table starts with the given maximum size, which both sides must already agree on: in HTTP/2, 4096 (the initial SETTINGS_HEADER_TABLE_SIZE).
      Parameters:
      maxHeaderTableSize - the nonnegative initial and maximum table capacity in octets
  • Method Details

    • setMaxHeaderTableSize

      public void setMaxHeaderTableSize(int maxHeaderTableSize)
      Sets the largest dynamic table the peer's encoder may use: call this when the peer acknowledges a SETTINGS frame that carried SETTINGS_HEADER_TABLE_SIZE. If the table is now larger than allowed, the next field block must start with a size update that shrinks it.
      Parameters:
      maxHeaderTableSize - the nonnegative advertised table limit in octets
    • maxHeaderTableSize

      public int maxHeaderTableSize()
      Returns the advertised dynamic table limit.
      Returns:
      the maximum table capacity allowed, in octets
    • setMaxHeaderListSize

      public void setMaxHeaderListSize(long maxHeaderListSize)
      SETTINGS_MAX_HEADER_LIST_SIZE: the largest decoded field section accepted.
      Parameters:
      maxHeaderListSize - the nonnegative decoded field section limit in octets
    • maxHeaderListSize

      public long maxHeaderListSize()
      Returns the decoded field section limit.
      Returns:
      the maximum decoded size in octets, including per-field overhead
    • setMaxStringLength

      public void setMaxStringLength(int maxStringLength)
      The longest name or value accepted, in octets.
      Parameters:
      maxStringLength - the nonnegative encoded and decoded string limit in octets
    • dynamicTableSize

      public int dynamicTableSize()
      The current size of the dynamic table in octets (entries plus 32 each).
      Returns:
      the current table size in octets, including per-entry overhead
    • dynamicTableCapacity

      public int dynamicTableCapacity()
      The current maximum size of the dynamic table, as last set by the peer's encoder.
      Returns:
      the table capacity in octets
    • dynamicTableLength

      public int dynamicTableLength()
      The number of entries in the dynamic table.
      Returns:
      the current entry count
    • dynamicTableEntry

      public HeaderField dynamicTableEntry(int index)
      A dynamic table entry, 1 being the newest (HPACK index 62).
      Parameters:
      index - the one-based dynamic table index, with 1 the newest entry
      Returns:
      the field at that dynamic table index
    • decode

      public List<HeaderField> decode(int streamId, byte[] block) throws Http2Exception
      Decodes a complete HPACK field block.
      Parameters:
      streamId - the stream identifier used for header list size errors
      block - the complete HPACK-encoded field block
      Returns:
      the decoded fields in order, preserving never-indexed sensitivity
      Throws:
      Http2Exception - if the block is malformed or exceeds a decoding limit
    • decode

      public List<HeaderField> decode(int streamId, byte[] block, int offset, int length) throws Http2Exception
      Decodes one complete field block.
      Parameters:
      streamId - the stream the block belongs to, for HeaderListSizeException
      block - the byte array containing the HPACK field block
      offset - the first encoded byte
      length - the encoded block length in octets
      Returns:
      the fields in order; never-indexed literals come back with HeaderField.sensitive() set
      Throws:
      Http2Exception - if the block is malformed or exceeds a decoding limit