Class H2Writer
This class provides efficient serialization of HTTP/2 frames to a
WritableByteChannel. It uses an internal buffer and automatically
sends data to the channel when the buffer fills beyond a threshold.
Key features:
- NIO-first - writes directly to channels
- Buffered output for efficiency
- Methods for each HTTP/2 frame type
- Handles frame header formatting
Usage:
H2Writer writer = new H2Writer(channel);
// Send SETTINGS frame
writer.writeSettings(false, settings);
// Send HEADERS frame
writer.writeHeaders(streamId, headerBlock, true, false);
// Send DATA frame
writer.writeData(streamId, data, true);
writer.flush();
Thread Safety
This class is NOT thread-safe. It is intended for use on a single thread. Callers must synchronize externally if used from multiple threads.
- Author:
- Chris Burdess
- See Also:
-
Field Summary
FieldsModifier and TypeFieldDescriptionstatic final intRFC 9113 section 4.1: frame header is always 9 octetsstatic final intstatic final intstatic final intstatic final intstatic final intstatic final int -
Constructor Summary
ConstructorsConstructorDescriptionH2Writer(WritableByteChannel channel) Creates a new HTTP/2 frame writer with default buffer capacity.H2Writer(WritableByteChannel channel, int bufferCapacity) Creates a new HTTP/2 frame writer with specified buffer capacity. -
Method Summary
Modifier and TypeMethodDescriptionvoidclose()Flushes and closes the writer.voidflush()Flushes any buffered data to the channel.voidwriteContinuation(int streamId, ByteBuffer headerBlock, boolean endHeaders) Writes a CONTINUATION frame (RFC 9113 section 6.10).voidwriteData(int streamId, ByteBuffer data, boolean endStream) Writes a DATA frame.voidwriteData(int streamId, ByteBuffer data, boolean endStream, int padLength) Writes a DATA frame with optional padding (RFC 9113 section 6.1).voidwriteGoaway(int lastStreamId, int errorCode) Writes a GOAWAY frame.voidwriteGoaway(int lastStreamId, int errorCode, ByteBuffer debugData) Writes a GOAWAY frame (RFC 9113 section 6.8).voidwriteHeaders(int streamId, ByteBuffer headerBlock, boolean endStream, boolean endHeaders) Writes a HEADERS frame.voidwriteHeaders(int streamId, ByteBuffer headerBlock, boolean endStream, boolean endHeaders, int dependsOn, int weight, boolean exclusive) Writes a HEADERS frame with priority information.voidwriteHeaders(int streamId, ByteBuffer headerBlock, boolean endStream, boolean endHeaders, int padLength, int dependsOn, int weight, boolean exclusive) Writes a HEADERS frame with all options (RFC 9113 section 6.2).voidwritePing(long data, boolean ack) Writes a PING frame.voidwritePriority(int streamId, int dependsOn, int weight, boolean exclusive) Writes a PRIORITY frame.voidwritePushPromise(int streamId, int promisedStreamId, ByteBuffer headerBlock, boolean endHeaders) Writes a PUSH_PROMISE frame.voidwriteRstStream(int streamId, int errorCode) Writes a RST_STREAM frame.voidwriteSettings(Map<Integer, Integer> settings) Writes a SETTINGS frame (RFC 9113 section 6.5).voidWrites an empty SETTINGS frame (acknowledgement).voidwriteWindowUpdate(int streamId, int increment) Writes a WINDOW_UPDATE frame (RFC 9113 section 6.9).
-
Field Details
-
FRAME_HEADER_LENGTH
public static final int FRAME_HEADER_LENGTHRFC 9113 section 4.1: frame header is always 9 octets- See Also:
-
SETTINGS_HEADER_TABLE_SIZE
public static final int SETTINGS_HEADER_TABLE_SIZE- See Also:
-
SETTINGS_ENABLE_PUSH
public static final int SETTINGS_ENABLE_PUSH- See Also:
-
SETTINGS_MAX_CONCURRENT_STREAMS
public static final int SETTINGS_MAX_CONCURRENT_STREAMS- See Also:
-
SETTINGS_INITIAL_WINDOW_SIZE
public static final int SETTINGS_INITIAL_WINDOW_SIZE- See Also:
-
SETTINGS_MAX_FRAME_SIZE
public static final int SETTINGS_MAX_FRAME_SIZE- See Also:
-
SETTINGS_MAX_HEADER_LIST_SIZE
public static final int SETTINGS_MAX_HEADER_LIST_SIZE- See Also:
-
-
Constructor Details
-
H2Writer
Creates a new HTTP/2 frame writer with default buffer capacity.- Parameters:
channel- the channel to write to
-
H2Writer
Creates a new HTTP/2 frame writer with specified buffer capacity.- Parameters:
channel- the channel to write tobufferCapacity- initial buffer capacity in bytes
-
-
Method Details
-
writeData
Writes a DATA frame.- Parameters:
streamId- the stream identifier (must be non-zero)data- the data payloadendStream- true if this is the last frame for this stream- Throws:
IOException- if there is an error writing
-
writeData
public void writeData(int streamId, ByteBuffer data, boolean endStream, int padLength) throws IOException Writes a DATA frame with optional padding (RFC 9113 section 6.1).- Parameters:
streamId- the stream identifier (must be non-zero)data- the data payloadendStream- true if this is the last frame for this streampadLength- padding length (0 for no padding)- Throws:
IOException- if there is an error writing
-
writeHeaders
public void writeHeaders(int streamId, ByteBuffer headerBlock, boolean endStream, boolean endHeaders) throws IOException Writes a HEADERS frame.- Parameters:
streamId- the stream identifier (must be non-zero)headerBlock- the HPACK-encoded header blockendStream- true if this is the last frame for this streamendHeaders- true if this completes the header block- Throws:
IOException- if there is an error writing
-
writeHeaders
public void writeHeaders(int streamId, ByteBuffer headerBlock, boolean endStream, boolean endHeaders, int dependsOn, int weight, boolean exclusive) throws IOException Writes a HEADERS frame with priority information.- Parameters:
streamId- the stream identifier (must be non-zero)headerBlock- the HPACK-encoded header blockendStream- true if this is the last frame for this streamendHeaders- true if this completes the header blockdependsOn- stream dependency (0 for none)weight- priority weight (1-256)exclusive- true for exclusive dependency- Throws:
IOException- if there is an error writing
-
writeHeaders
public void writeHeaders(int streamId, ByteBuffer headerBlock, boolean endStream, boolean endHeaders, int padLength, int dependsOn, int weight, boolean exclusive) throws IOException Writes a HEADERS frame with all options (RFC 9113 section 6.2).If the header block exceeds SETTINGS_MAX_FRAME_SIZE, callers must fragment the block across this HEADERS frame (with END_HEADERS unset) followed by CONTINUATION frames (RFC 9113 section 4.3).
- Parameters:
streamId- the stream identifier (must be non-zero)headerBlock- the HPACK-encoded header blockendStream- true if this is the last frame for this streamendHeaders- true if this completes the header blockpadLength- padding length (0 for no padding)dependsOn- stream dependency (0 for none)weight- priority weight (1-256, ignored if dependsOn is 0)exclusive- true for exclusive dependency- Throws:
IOException- if there is an error writing
-
writePriority
public void writePriority(int streamId, int dependsOn, int weight, boolean exclusive) throws IOException Writes a PRIORITY frame.- Parameters:
streamId- the stream identifier (must be non-zero)dependsOn- stream dependencyweight- priority weight (1-256)exclusive- true for exclusive dependency- Throws:
IOException- if there is an error writing
-
writeRstStream
Writes a RST_STREAM frame.- Parameters:
streamId- the stream identifier (must be non-zero)errorCode- the error code- Throws:
IOException- if there is an error writing
-
writeSettingsAck
Writes an empty SETTINGS frame (acknowledgement).- Throws:
IOException- if there is an error writing
-
writeSettings
Writes a SETTINGS frame (RFC 9113 section 6.5).- Parameters:
settings- map of setting ID to value- Throws:
IOException- if there is an error writing
-
writePushPromise
public void writePushPromise(int streamId, int promisedStreamId, ByteBuffer headerBlock, boolean endHeaders) throws IOException Writes a PUSH_PROMISE frame.- Parameters:
streamId- the stream identifier (must be non-zero)promisedStreamId- the promised stream identifierheaderBlock- the HPACK-encoded header blockendHeaders- true if this completes the header block- Throws:
IOException- if there is an error writing
-
writePing
Writes a PING frame.- Parameters:
data- the 8-byte opaque dataack- true if this is a PING acknowledgement- Throws:
IOException- if there is an error writing
-
writeGoaway
Writes a GOAWAY frame.- Parameters:
lastStreamId- the last stream ID the sender will accepterrorCode- the error code- Throws:
IOException- if there is an error writing
-
writeGoaway
Writes a GOAWAY frame (RFC 9113 section 6.8).- Parameters:
lastStreamId- the last stream ID the sender will accepterrorCode- the error codedebugData- optional debug data (may be null)- Throws:
IOException- if there is an error writing
-
writeWindowUpdate
Writes a WINDOW_UPDATE frame (RFC 9113 section 6.9).- Parameters:
streamId- the stream identifier (0 for connection-level)increment- the window size increment (1 to 2^31-1)- Throws:
IOException- if there is an error writing
-
writeContinuation
public void writeContinuation(int streamId, ByteBuffer headerBlock, boolean endHeaders) throws IOException Writes a CONTINUATION frame (RFC 9113 section 6.10).CONTINUATION frames carry additional header block fragments when the block exceeds a single HEADERS or PUSH_PROMISE frame. Per RFC 9113 section 4.3, CONTINUATION frames MUST follow immediately with no intervening frames on the connection.
- Parameters:
streamId- the stream identifier (must be non-zero)headerBlock- the HPACK-encoded header block fragmentendHeaders- true if this completes the header block- Throws:
IOException- if there is an error writing
-
flush
Flushes any buffered data to the channel.- Throws:
IOException- if there is an error sending data
-
close
Flushes and closes the writer.Note: This does NOT close the underlying channel.
- Throws:
IOException- if there is an error flushing data
-