Class Http2FrameCodec
- All Implemented Interfaces:
ChannelHandler, ChannelInboundHandler, ChannelOutboundHandler, Http2LifecycleManager
- Direct Known Subclasses:
Http2MultiplexCodec
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(ChannelHandlerContext, Object). Outbound Http2Frame
objects received via write(ChannelHandlerContext, Object, 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(ChannelHandlerContext, 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.
-
Nested Class Summary
Nested classes/interfaces inherited from class ByteToMessageDecoder
ByteToMessageDecoder.CumulatorNested classes/interfaces inherited from interface ChannelHandler
ChannelHandler.Sharable -
Field Summary
FieldsFields inherited from class ByteToMessageDecoder
COMPOSITE_CUMULATOR, MERGE_CUMULATOR -
Constructor Summary
ConstructorsModifierConstructorDescriptionprotectedHttp2FrameCodec(Http2ConnectionEncoder encoder, Http2ConnectionDecoder decoder, Http2Settings initialSettings, boolean decoupleCloseAndGoAway, boolean flushPreface) -
Method Summary
Modifier and TypeMethodDescriptionfinal voidDo nothing by default, sub-classes may override this method.protected final booleanCalled by the graceful shutdown logic to determine when it is safe to close the connection.protected Http2StreamFramenewHttp2UnknownFrame(byte frameType, int streamId, Http2Flags flags, ByteBuf payload) Create a Http2UnknownFrame.protected voidonConnectionError(ChannelHandlerContext ctx, boolean outbound, Throwable cause, Http2Exception http2Ex) Handler for a connection error.protected final voidonStreamError(ChannelHandlerContext ctx, boolean outbound, Throwable cause, Http2Exception.StreamException streamException) Exceptions for unknown streams, that is streams that have noHttp2FrameStreamobject attached are simply logged and replied to by sending a RST_STREAM frame.final voiduserEventTriggered(ChannelHandlerContext ctx, Object evt) Handles the cleartext HTTP upgrade event.voidwrite(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) Processes allHttp2Frames.Methods inherited from class Http2ConnectionHandler
bind, channelActive, channelInactive, channelReadComplete, channelWritabilityChanged, close, closeStream, closeStreamLocal, closeStreamRemote, connect, connection, decode, decoder, deregister, disconnect, encoder, exceptionCaught, flush, frameWriter, goAway, gracefulShutdownTimeoutMillis, gracefulShutdownTimeoutMillis, handlerRemoved0, handleServerHeaderDecodeSizeError, onError, onHttpClientUpgrade, onHttpServerUpgrade, read, resetStreamMethods inherited from class ByteToMessageDecoder
actualReadableBytes, callDecode, channelRead, decodeLast, discardSomeReadBytes, handlerRemoved, internalBuffer, isSingleDecode, setCumulator, setDiscardAfterReads, setSingleDecodeMethods inherited from class ChannelInboundHandlerAdapter
channelRegistered, channelUnregisteredMethods inherited from class ChannelHandlerAdapter
ensureNotSharable, isSharableMethods inherited from class Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, waitMethods inherited from interface ChannelHandler
handlerRemoved
-
Field Details
-
streamKey
-
-
Constructor Details
-
Http2FrameCodec
protected Http2FrameCodec(Http2ConnectionEncoder encoder, Http2ConnectionDecoder decoder, Http2Settings initialSettings, boolean decoupleCloseAndGoAway, boolean flushPreface)
-
-
Method Details
-
handlerAdded
Description copied from class:ChannelHandlerAdapterDo nothing by default, sub-classes may override this method.- Specified by:
handlerAddedin interfaceChannelHandler- Overrides:
handlerAddedin classHttp2ConnectionHandler- Throws:
Exception
-
userEventTriggered
Handles the cleartext HTTP upgrade event. If an upgrade occurred, sends a simple response via HTTP/2 on stream 1 (the stream specifically reserved for cleartext HTTP upgrade).- Specified by:
userEventTriggeredin interfaceChannelInboundHandler- Overrides:
userEventTriggeredin classByteToMessageDecoder- Throws:
Exception
-
write
Processes allHttp2Frames.Http2StreamFrames may only originate in child streams.- Specified by:
writein interfaceChannelOutboundHandler- Overrides:
writein classHttp2ConnectionHandler- Parameters:
ctx- theChannelHandlerContextfor which the write operation is mademsg- the message to writepromise- theChannelPromiseto notify once the operation completes
-
onConnectionError
protected void onConnectionError(ChannelHandlerContext ctx, boolean outbound, Throwable cause, Http2Exception http2Ex) Description copied from class:Http2ConnectionHandlerHandler for a connection error. Sends a GO_AWAY frame to the remote endpoint. Once all streams are closed, the connection is shut down.- Overrides:
onConnectionErrorin classHttp2ConnectionHandler- Parameters:
ctx- the channel contextoutbound-trueif the error was caused by an outbound operation.cause- the exception that was caughthttp2Ex- theHttp2Exceptionthat is embedded in the causality chain. This may benullif it's an unknown exception.
-
onStreamError
protected final void onStreamError(ChannelHandlerContext ctx, boolean outbound, Throwable cause, Http2Exception.StreamException streamException) Exceptions for unknown streams, that is streams that have noHttp2FrameStreamobject attached are simply logged and replied to by sending a RST_STREAM frame.- Overrides:
onStreamErrorin classHttp2ConnectionHandler- Parameters:
ctx- the channel contextoutbound-trueif the error was caused by an outbound operation.cause- the exception that was caughtstreamException- theHttp2Exception.StreamExceptionthat is embedded in the causality chain.
-
isGracefulShutdownComplete
protected final boolean isGracefulShutdownComplete()Description copied from class:Http2ConnectionHandlerCalled by the graceful shutdown logic to determine when it is safe to close the connection. Returnstrueif the graceful shutdown has completed and the connection can be safely closed. This implementation just guarantees that there are no active streams. Subclasses may override to provide additional checks.- Overrides:
isGracefulShutdownCompletein classHttp2ConnectionHandler
-
newHttp2UnknownFrame
protected Http2StreamFrame newHttp2UnknownFrame(byte frameType, int streamId, Http2Flags flags, ByteBuf payload) Create a Http2UnknownFrame. The ownership of theByteBufis transferred.
-