Class H2Writer

java.lang.Object
org.bluezoo.gumdrop.http.h2.H2Writer

public class H2Writer extends Object
Streaming writer for HTTP/2 frames (RFC 9113 section 4.1) with NIO-first design.

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 Details

    • FRAME_HEADER_LENGTH

      public static final int FRAME_HEADER_LENGTH
      RFC 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

      public H2Writer(WritableByteChannel channel)
      Creates a new HTTP/2 frame writer with default buffer capacity.
      Parameters:
      channel - the channel to write to
    • H2Writer

      public H2Writer(WritableByteChannel channel, int bufferCapacity)
      Creates a new HTTP/2 frame writer with specified buffer capacity.
      Parameters:
      channel - the channel to write to
      bufferCapacity - initial buffer capacity in bytes
  • Method Details

    • writeData

      public void writeData(int streamId, ByteBuffer data, boolean endStream) throws IOException
      Writes a DATA frame.
      Parameters:
      streamId - the stream identifier (must be non-zero)
      data - the data payload
      endStream - 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 payload
      endStream - true if this is the last frame for this stream
      padLength - 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 block
      endStream - true if this is the last frame for this stream
      endHeaders - 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 block
      endStream - true if this is the last frame for this stream
      endHeaders - true if this completes the header block
      dependsOn - 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 block
      endStream - true if this is the last frame for this stream
      endHeaders - true if this completes the header block
      padLength - 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 dependency
      weight - priority weight (1-256)
      exclusive - true for exclusive dependency
      Throws:
      IOException - if there is an error writing
    • writeRstStream

      public void writeRstStream(int streamId, int errorCode) throws IOException
      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

      public void writeSettingsAck() throws IOException
      Writes an empty SETTINGS frame (acknowledgement).
      Throws:
      IOException - if there is an error writing
    • writeSettings

      public void writeSettings(Map<Integer,Integer> settings) throws IOException
      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 identifier
      headerBlock - the HPACK-encoded header block
      endHeaders - true if this completes the header block
      Throws:
      IOException - if there is an error writing
    • writePing

      public void writePing(long data, boolean ack) throws IOException
      Writes a PING frame.
      Parameters:
      data - the 8-byte opaque data
      ack - true if this is a PING acknowledgement
      Throws:
      IOException - if there is an error writing
    • writeGoaway

      public void writeGoaway(int lastStreamId, int errorCode) throws IOException
      Writes a GOAWAY frame.
      Parameters:
      lastStreamId - the last stream ID the sender will accept
      errorCode - the error code
      Throws:
      IOException - if there is an error writing
    • writeGoaway

      public void writeGoaway(int lastStreamId, int errorCode, ByteBuffer debugData) throws IOException
      Writes a GOAWAY frame (RFC 9113 section 6.8).
      Parameters:
      lastStreamId - the last stream ID the sender will accept
      errorCode - the error code
      debugData - optional debug data (may be null)
      Throws:
      IOException - if there is an error writing
    • writeWindowUpdate

      public void writeWindowUpdate(int streamId, int increment) throws IOException
      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 fragment
      endHeaders - true if this completes the header block
      Throws:
      IOException - if there is an error writing
    • flush

      public void flush() throws IOException
      Flushes any buffered data to the channel.
      Throws:
      IOException - if there is an error sending data
    • close

      public void close() throws IOException
      Flushes and closes the writer.

      Note: This does NOT close the underlying channel.

      Throws:
      IOException - if there is an error flushing data