Package io.github.mahmoudimus.http2
Class HpackDecoder
java.lang.Object
io.github.mahmoudimus.http2.HpackDecoder
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 raisesHeaderListSizeException, 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
FieldsModifier and TypeFieldDescriptionstatic final longThe default decoded field section limit, including per-field overhead, in octets.static final intThe default maximum encoded or decoded string length in octets. -
Constructor Summary
ConstructorsConstructorDescriptionA 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 TypeMethodDescriptiondecode(int streamId, byte[] block) Decodes a complete HPACK field block.decode(int streamId, byte[] block, int offset, int length) Decodes one complete field block.intThe 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).intThe number of entries in the dynamic table.intThe current size of the dynamic table in octets (entries plus 32 each).longReturns the decoded field section limit.intReturns the advertised dynamic table limit.voidsetMaxHeaderListSize(long maxHeaderListSize) SETTINGS_MAX_HEADER_LIST_SIZE: the largest decoded field section accepted.voidsetMaxHeaderTableSize(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.voidsetMaxStringLength(int maxStringLength) The longest name or value accepted, in octets.
-
Field Details
-
DEFAULT_MAX_HEADER_LIST_SIZE
public static final long DEFAULT_MAX_HEADER_LIST_SIZEThe default decoded field section limit, including per-field overhead, in octets.- See Also:
-
DEFAULT_MAX_STRING_LENGTH
public static final int DEFAULT_MAX_STRING_LENGTHThe 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
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
Decodes a complete HPACK field block.- Parameters:
streamId- the stream identifier used for header list size errorsblock- 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, forHeaderListSizeExceptionblock- the byte array containing the HPACK field blockoffset- the first encoded bytelength- 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
-