Class Http2FrameCodec

All Implemented Interfaces:
ChannelHandler, ChannelInboundHandler, ChannelOutboundHandler, Http2LifecycleManager
Direct Known Subclasses:
Http2MultiplexCodec

public class Http2FrameCodec extends Http2ConnectionHandler

This API is very immature. The Http2Connection-based API is currently preferred over this API. This API is targeted to eventually replace or reduce the need for the Http2ConnectionHandler API.

An HTTP/2 handler that maps HTTP/2 frames to Http2Frame objects and vice versa. For every incoming HTTP/2 frame, an Http2Frame object is created and propagated via ByteToMessageDecoder.channelRead(io.netty.channel.ChannelHandlerContext, java.lang.Object). Outbound Http2Frame objects received via write(io.netty.channel.ChannelHandlerContext, java.lang.Object, io.netty.channel.ChannelPromise) are converted to the HTTP/2 wire format. HTTP/2 frames specific to a stream implement the Http2StreamFrame interface. The Http2FrameCodec is instantiated using the Http2FrameCodecBuilder. It's recommended for channel handlers to inherit from the Http2ChannelDuplexHandler, as it provides additional functionality like iterating over all active streams or creating outbound streams.

Stream Lifecycle

The frame codec delivers and writes frames for active streams. An active stream is closed when either side sends a RST_STREAM frame or both sides send a frame with the END_STREAM flag set. Each Http2StreamFrame has a Http2FrameStream object attached that uniquely identifies a particular stream.

Http2StreamFrames read from the channel always a Http2FrameStream object set, while when writing a Http2StreamFrame the application code needs to set a Http2FrameStream object using Http2StreamFrame.stream(Http2FrameStream).

Flow control

The frame codec automatically increments stream and connection flow control windows.

Incoming flow controlled frames need to be consumed by writing a Http2WindowUpdateFrame with the consumed number of bytes and the corresponding stream identifier set to the frame codec.

The local stream-level flow control window can be changed by writing a Http2SettingsFrame with the Http2Settings.initialWindowSize() set to the targeted value.

The connection-level flow control window can be changed by writing a Http2WindowUpdateFrame with the desired window size increment in bytes and the stream identifier set to 0. By default the initial connection-level flow control window is the same as initial stream-level flow control window.

New inbound Streams

The first frame of an HTTP/2 stream must be an Http2HeadersFrame, which will have an Http2FrameStream object attached.

New outbound Streams

A outbound HTTP/2 stream can be created by first instantiating a new Http2FrameStream object via Http2ChannelDuplexHandler.newStream(), and then writing a Http2HeadersFrame object with the stream attached.

 
     final Http2Stream2 stream = handler.newStream();
     ctx.write(headersFrame.stream(stream)).addListener(new ChannelFutureListener() {

         @Override
         public void operationComplete(ChannelFuture f) {
             if (f.isSuccess()) {
                 // Stream is active and stream.id() returns a valid stream identifier.
                 System.out.println("New stream with id " + stream.id() + " created.");
             } else {
                 // Stream failed to become active. Handle error.
                 if (f.cause() instanceof Http2NoMoreStreamIdsException) {

                 } else if (f.cause() instanceof Http2GoAwayException) {

                 } else {

                 }
             }
         }
     }
     
 

If a new stream cannot be created due to stream id exhaustion of the endpoint, the ChannelPromise of the HEADERS frame will fail with a Http2NoMoreStreamIdsException.

The HTTP/2 standard allows for an endpoint to limit the maximum number of concurrently active streams via the SETTINGS_MAX_CONCURRENT_STREAMS setting. When this limit is reached, no new streams can be created. However, the Http2FrameCodec can be build with Http2FrameCodecBuilder.encoderEnforceMaxConcurrentStreams(boolean) enabled, in which case a new stream and its associated frames will be buffered until either the limit is increased or an active stream is closed. It's, however, possible that a buffered stream will never become active. That is, the channel might get closed or a GO_AWAY frame might be received. In the first case, all writes of buffered streams will fail with a StreamBufferingEncoder.Http2ChannelClosedException. In the second case, all writes of buffered streams with an identifier less than the last stream identifier of the GO_AWAY frame will fail with a StreamBufferingEncoder.Http2GoAwayException.

Error Handling

Exceptions and errors are propagated via ChannelInboundHandler.exceptionCaught(io.netty.channel.ChannelHandlerContext, java.lang.Throwable). Exceptions that apply to a specific HTTP/2 stream are wrapped in a Http2FrameStreamException and have the corresponding Http2FrameStream object attached.

Reference Counting

Some Http2StreamFrames implement the ReferenceCounted interface, as they carry reference counted objects (e.g. ByteBufs). The frame codec will call ReferenceCounted.retain() before propagating a reference counted object through the pipeline, and thus an application handler needs to release such an object after having consumed it. For more information on reference counting take a look at Reference counted objects

HTTP Upgrade

Server-side HTTP to HTTP/2 upgrade is supported in conjunction with Http2ServerUpgradeCodec; the necessary HTTP-to-HTTP/2 conversion is performed automatically.