APIdia Launch Partner
Top Description Fields Constructors Methods
jdk.internal.net.http.hpack

public Class Encoder

extends Object
Class Inheritance
Imports
jdk.internal.net.http.hpack.HPACK.Logger, java.nio.ByteBuffer, .ReadOnlyBufferException, java.util.LinkedList, .List, java.util.concurrent.atomic.AtomicLong

Encodes headers to their binary representation.

Typical lifecycle looks like this:

new Encoder (setMaxCapacity? encode)*

Suppose headers are represented by Map<String, List<String>>. A supplier and a consumer of ByteBuffers in forms of Supplier<ByteBuffer> and Consumer<ByteBuffer> respectively. Then to encode headers, the following approach might be used:

for (Map.Entry<String, List<String>> h : headers.entrySet()) {
        String name = h.getKey();
        for (String value : h.getValue()) {
            encoder.header(name, value);        // Set up header
            boolean encoded;
            do {
                ByteBuffer b = buffersSupplier.get();
                encoded = encoder.encode(b);    // Encode the header
                buffersConsumer.accept(b);
            } while (!encoded);
        }
    }

Though the specification does not define how an encoder is to be implemented, a default implementation is provided by the method header(CharSequence, CharSequence, boolean).

To provide a custom encoding implementation, Encoder has to be extended. A subclass then can access methods for encoding using specific representations (e.g. literal, indexed, etc.)

API Note

An Encoder provides an incremental way of encoding headers. encode(ByteBuffer) takes a buffer a returns a boolean indicating whether, or not, the buffer was sufficiently sized to hold the remaining of the encoded representation.

This way, there's no need to provide a buffer of a specific size, or to resize (and copy) the buffer on demand, when the remaining encoded representation will not fit in the buffer's remaining space. Instead, an array of existing buffers can be used, prepended with a frame that encloses the resulting header block afterwards.

Splitting the encoding operation into header set up and header encoding, separates long lived arguments (name, value, sensitivity, etc.) from the short lived ones (e.g. buffer), simplifying each operation itself.

Implementation Note

The default implementation does not use dynamic table. It reports to a coupled Decoder a size update with the value of 0, and never changes it afterwards.

Since
9

Field Summary

Modifier and TypeField and Description
private final BulkSizeUpdateWriter
private boolean
private boolean
private int
private static final AtomicLong
private boolean
private final HeaderTable
private final QuickHuffman.Writer
private final long
private final IndexedWriter
private int
private final LiteralNeverIndexedWriter
private final LiteralWithIndexingWriter
private final LiteralWriter
private final HPACK.Logger
private int
private long
private final SizeUpdateWriter
private BinaryRepresentationWriter

Constructor Summary

AccessConstructor and Description
public
Encoder(int
a non-negative integer
maxCapacity
)

Constructs an Encoder with the specified maximum capacity of the header table.

Method Summary

Modifier and TypeMethod and Description
protected int

Returns:

actual capacity
calculateCapacity
(int
upper bound
maxCapacity
)

Calculates actual capacity to be used by this encoder in response to a request to update maximum table size.

protected final void
public final boolean

Returns:

true if the current header has been fully encoded, false otherwise
encode
(ByteBuffer
the buffer to encode the header into, may be empty
headerBlock
)

Encodes the set up header into the given buffer.

protected final HeaderTable
protected final int
public void
header(CharSequence
the name
name
,
CharSequence
the value
value
)

Sets up the given header (name, value).

public void
header(CharSequence
the name
name
,
CharSequence
the value
value
,
boolean
whether or not the value is sensitive
sensitive
)

Sets up the given header (name, value) with possibly sensitive value.

protected final void
indexed(int index)

protected final boolean
protected final void
literal(int index, CharSequence value, boolean useHuffman)

protected final void
literal(CharSequence name, boolean nameHuffman, CharSequence value, boolean valueHuffman)

protected final void
literalNeverIndexed(int index, CharSequence value, boolean valueHuffman)

protected final void
literalNeverIndexed(CharSequence name, boolean nameHuffman, CharSequence value, boolean valueHuffman)

protected final void
literalWithIndexing(int index, CharSequence value, boolean valueHuffman)

protected final void
literalWithIndexing(CharSequence name, boolean nameHuffman, CharSequence value, boolean valueHuffman)

protected final HPACK.Logger
private boolean
public void
setMaxCapacity(int
a non-negative integer
capacity
)

Sets a maximum capacity of the header table.

private void
setMaxCapacity0(int capacity)

protected final void
sizeUpdate(int capacity)

protected final int
Inherited from java.lang.Object:
cloneequalsfinalizegetClasshashCodenotifynotifyAlltoStringwaitwaitwait

Field Detail

bulkSizeUpdateWriterback to summary
private final BulkSizeUpdateWriter bulkSizeUpdateWriter
capacityUpdateback to summary
private boolean capacityUpdate
configuredCapacityUpdateback to summary
private boolean configuredCapacityUpdate
currCapacityback to summary
private int currCapacity
ENCODERS_IDSback to summary
private static final AtomicLong ENCODERS_IDS
encodingback to summary
private boolean encoding
headerTableback to summary
private final HeaderTable headerTable
huffmanWriterback to summary
private final QuickHuffman.Writer huffmanWriter
idback to summary
private final long id
indexedWriterback to summary
private final IndexedWriter indexedWriter
lastCapacityback to summary
private int lastCapacity
literalNeverIndexedWriterback to summary
private final LiteralNeverIndexedWriter literalNeverIndexedWriter
literalWithIndexingWriterback to summary
private final LiteralWithIndexingWriter literalWithIndexingWriter
literalWriterback to summary
private final LiteralWriter literalWriter
loggerback to summary
private final HPACK.Logger logger
maxCapacityback to summary
private int maxCapacity
minCapacityback to summary
private long minCapacity
sizeUpdateWriterback to summary
private final SizeUpdateWriter sizeUpdateWriter
writerback to summary
private BinaryRepresentationWriter writer

Constructor Detail

Encoderback to summary
public Encoder(int maxCapacity)

Constructs an Encoder with the specified maximum capacity of the header table.

The value has to be agreed between decoder and encoder out-of-band, e.g. by a protocol that uses HPACK (see 4.2. Maximum Table Size).

Parameters
maxCapacity:int

a non-negative integer

Exceptions
IllegalArgumentException:
if maxCapacity is negative

Method Detail

calculateCapacityback to summary
protected int calculateCapacity(int maxCapacity)

Calculates actual capacity to be used by this encoder in response to a request to update maximum table size.

Default implementation does not add anything to the headers table, hence this method returns 0.

It is an error to return a value c, where c < 0 or c > maxCapacity.

Parameters
maxCapacity:int

upper bound

Returns:int

actual capacity

checkEncodingback to summary
protected final void checkEncoding()
encodeback to summary
public final boolean encode(ByteBuffer headerBlock)

Encodes the set up header into the given buffer.

The encoder writes as much as possible of the header's binary representation into the given buffer, starting at the buffer's position, and increments its position to reflect the bytes written. The buffer's mark and limit will not be modified.

Once the method has returned true, the current header is deemed encoded. A new header may be set up.

Parameters
headerBlock:ByteBuffer

the buffer to encode the header into, may be empty

Returns:boolean

true if the current header has been fully encoded, false otherwise

Exceptions
NullPointerException:
if the buffer is null
ReadOnlyBufferException:
if this buffer is read-only
IllegalStateException:
if there is no set up header
getHeaderTableback to summary
protected final HeaderTable getHeaderTable()
getMaxCapacityback to summary
protected final int getMaxCapacity()
headerback to summary
public void header(CharSequence name, CharSequence value) throws IllegalStateException

Sets up the given header (name, value).

Fixates name and value for the duration of encoding.

Parameters
name:CharSequence

the name

value:CharSequence

the value

Exceptions
IllegalStateException:
if the encoder hasn't fully encoded the previous header, or hasn't yet started to encode it
NullPointerException:
if any of the arguments are null
See Also
header(CharSequence, CharSequence, boolean)
headerback to summary
public void header(CharSequence name, CharSequence value, boolean sensitive) throws IllegalStateException

Sets up the given header (name, value) with possibly sensitive value.

If the value is sensitive (think security, secrecy, etc.) this encoder will compress it using a special representation (see 6.2.3. Literal Header Field Never Indexed).

Fixates name and value for the duration of encoding.

Parameters
name:CharSequence

the name

value:CharSequence

the value

sensitive:boolean

whether or not the value is sensitive

Exceptions
IllegalStateException:
if the encoder hasn't fully encoded the previous header, or hasn't yet started to encode it
NullPointerException:
if any of the arguments are null
See Also
header(CharSequence, CharSequence), DecodingCallback#onDecoded(CharSequence, CharSequence, boolean)
indexedback to summary
protected final void indexed(int index) throws IndexOutOfBoundsException
isHuffmanBetterForback to summary
protected final boolean isHuffmanBetterFor(CharSequence value)
literalback to summary
protected final void literal(int index, CharSequence value, boolean useHuffman) throws IndexOutOfBoundsException
literalback to summary
protected final void literal(CharSequence name, boolean nameHuffman, CharSequence value, boolean valueHuffman)
literalNeverIndexedback to summary
protected final void literalNeverIndexed(int index, CharSequence value, boolean valueHuffman) throws IndexOutOfBoundsException
literalNeverIndexedback to summary
protected final void literalNeverIndexed(CharSequence name, boolean nameHuffman, CharSequence value, boolean valueHuffman)
literalWithIndexingback to summary
protected final void literalWithIndexing(int index, CharSequence value, boolean valueHuffman) throws IndexOutOfBoundsException
literalWithIndexingback to summary
protected final void literalWithIndexing(CharSequence name, boolean nameHuffman, CharSequence value, boolean valueHuffman)
loggerback to summary
protected final HPACK.Logger logger()
prependWithCapacityUpdateback to summary
private boolean prependWithCapacityUpdate(ByteBuffer headerBlock)
setMaxCapacityback to summary
public void setMaxCapacity(int capacity)

Sets a maximum capacity of the header table.

The value has to be agreed between decoder and encoder out-of-band, e.g. by a protocol that uses HPACK (see 4.2. Maximum Table Size).

May be called any number of times after or before a complete header has been encoded.

If the encoder decides to change the actual capacity, an update will be encoded before a new encoding operation starts.

Parameters
capacity:int

a non-negative integer

Exceptions
IllegalArgumentException:
if capacity is negative
IllegalStateException:
if the encoder hasn't fully encoded the previous header, or hasn't yet started to encode it
setMaxCapacity0back to summary
private void setMaxCapacity0(int capacity)
sizeUpdateback to summary
protected final void sizeUpdate(int capacity) throws IllegalArgumentException
tableIndexOfback to summary
protected final int tableIndexOf(CharSequence name, CharSequence value)