Class HpackEncoder

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

public final class HpackEncoder extends Object
Encodes field sections into HPACK field blocks (RFC 7541). One encoder per connection direction; blocks must be sent in the order they were encoded. Not thread-safe.

 HpackEncoder hpack = new HpackEncoder();
 writer.writeHeaders(streamId, hpack.encode(fields), endStream);
 

Fields go out as an index when the static or dynamic table holds them, and otherwise as literals added to the dynamic table, except:

  • a field marked HeaderField.sensitive(), or (unless turned off) one named in SENSITIVE_NAMES, is sent as a never-indexed literal, so it never enters either side's compression context and intermediaries must forward it the same way;
  • a field larger than the whole table is sent without indexing.

Strings are Huffman-coded unless that would make them longer or setHuffman(boolean) turns it off. Names are sent as given: lower-case them first (Http2Headers does).

  • Field Details

    • SENSITIVE_NAMES

      public static final Set<String> SENSITIVE_NAMES
      Names whose fields are sent never-indexed by default: they carry credentials.
  • Constructor Details

    • HpackEncoder

      public HpackEncoder()
      An encoder with the protocol's initial table size, 4096, which it will not exceed.
    • HpackEncoder

      public HpackEncoder(int maxHeaderTableSize)
      An encoder whose dynamic table starts at maxHeaderTableSize, which both sides must already agree on (in HTTP/2, 4096). The table never grows beyond this, however large a SETTINGS_HEADER_TABLE_SIZE the peer allows.
      Parameters:
      maxHeaderTableSize - the nonnegative initial and maximum table capacity in octets
  • Method Details

    • setHuffman

      public HpackEncoder setHuffman(boolean huffman)
      Whether to Huffman-code strings that do not get longer for it (default true).
      Parameters:
      huffman - whether to use Huffman coding when it saves space
      Returns:
      this encoder
    • setNeverIndexSensitiveNames

      public HpackEncoder setNeverIndexSensitiveNames(boolean neverIndexSensitiveNames)
      Whether to send fields named in SENSITIVE_NAMES never-indexed (default true).
      Parameters:
      neverIndexSensitiveNames - whether fields with sensitive names must be sent never-indexed
      Returns:
      this encoder
    • setMaxHeaderTableSize

      public void setMaxHeaderTableSize(long peerMaxHeaderTableSize)
      Applies the peer's SETTINGS_HEADER_TABLE_SIZE. The table is resized to the smaller of that and this encoder's own limit, and the change is signalled at the start of the next block (both the smallest size and the final one, if it shrank and grew again in between).
      Parameters:
      peerMaxHeaderTableSize - the nonnegative table size allowed by the peer, in octets
    • dynamicTableSize

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

      public int dynamicTableCapacity()
      Returns the current dynamic table capacity.
      Returns:
      the table capacity in octets
    • dynamicTableLength

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

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

      public byte[] encode(List<HeaderField> fields)
      Encodes one field section into a field block.
      Parameters:
      fields - the fields to encode in wire order
      Returns:
      the encoded HPACK field block
    • encode

      public void encode(List<HeaderField> fields, ByteArrayOutputStream out)
      Encodes one field section, appending the field block to out.
      Parameters:
      fields - the fields to encode in wire order
      out - the output buffer to append to
      Throws:
      IllegalArgumentException - if a name or value has a char above U+00FF (not an octet)