Package io.netty.handler.codec.http
Class HttpObjectDecoder
java.lang.Object
io.netty.channel.ChannelHandlerAdapter
io.netty.channel.ChannelInboundHandlerAdapter
io.netty.handler.codec.ByteToMessageDecoder
io.netty.handler.codec.http.HttpObjectDecoder
- All Implemented Interfaces:
io.netty.channel.ChannelHandler,io.netty.channel.ChannelInboundHandler
- Direct Known Subclasses:
HttpRequestDecoder,HttpResponseDecoder,RtspDecoder,RtspObjectDecoder
public abstract class HttpObjectDecoder
extends io.netty.handler.codec.ByteToMessageDecoder
Decodes
ByteBufs into HttpMessages and
HttpContents.
Parameters that prevents excessive memory consumption
| Name | Default value | Meaning |
|---|---|---|
maxInitialLineLength |
4096 | The maximum length of the initial line
(e.g. "GET / HTTP/1.0" or "HTTP/1.0 200 OK")
If the length of the initial line exceeds this value, a
TooLongHttpLineException will be raised. |
maxHeaderSize |
8192 | The maximum length of all headers. If the sum of the length of each
header exceeds this value, a TooLongHttpHeaderException will be raised. |
maxChunkSize |
8192 | The maximum length of the content or each chunk. If the content length
(or the length of each chunk) exceeds this value, the content or chunk
will be split into multiple HttpContents whose length is
maxChunkSize at maximum. |
Parameters that control parsing behavior
| Name | Default value | Meaning |
|---|---|---|
allowDuplicateContentLengths |
false | When set to false, will reject any messages that contain multiple Content-Length header fields.
When set to true, will allow multiple Content-Length headers only if they are all the same decimal value.
The duplicated field-values will be replaced with a single valid Content-Length field.
See RFC 7230, Section 3.3.2. |
allowPartialChunks |
true | If the length of a chunk exceeds the ByteBufs readable bytes and allowPartialChunks
is set to true, the chunk will be split into multiple HttpContents.
Otherwise, if the chunk size does not exceed maxChunkSize and allowPartialChunks
is set to false, the ByteBuf is not decoded into an HttpContent until
the readable bytes are greater or equal to the chunk size. |
Chunked Content
If the content of an HTTP message is greater thanmaxChunkSize or
the transfer encoding of the HTTP message is 'chunked', this decoder
generates one HttpMessage instance and its following
HttpContents per single HTTP message to avoid excessive memory
consumption. For example, the following HTTP message:
GET / HTTP/1.1 Transfer-Encoding: chunked 1a abcdefghijklmnopqrstuvwxyz 10 1234567890abcdef 0 Content-MD5: ... [blank line]triggers
HttpRequestDecoder to generate 3 objects:
- An
HttpRequest, - The first
HttpContentwhose content is'abcdefghijklmnopqrstuvwxyz', - The second
LastHttpContentwhose content is'1234567890abcdef', which marks the end of the content.
HttpContents by yourself for your
convenience, insert HttpObjectAggregator after this decoder in the
ChannelPipeline. However, please note that your server might not
be as memory efficient as without the aggregator.
Extensibility
Please note that this decoder is designed to be extended to implement a protocol derived from HTTP, such as RTSP and ICAP. To implement the decoder of such a derived protocol, extend this class and implement all abstract methods properly.Header Validation
It is recommended to always enable header validation.Without header validation, your system can become vulnerable to CWE-113: Improper Neutralization of CRLF Sequences in HTTP Headers ('HTTP Response Splitting') .
This recommendation stands even when both peers in the HTTP exchange are trusted, as it helps with defence-in-depth.
-
Nested Class Summary
Nested classes/interfaces inherited from class io.netty.handler.codec.ByteToMessageDecoder
io.netty.handler.codec.ByteToMessageDecoder.CumulatorNested classes/interfaces inherited from interface io.netty.channel.ChannelHandler
io.netty.channel.ChannelHandler.Sharable -
Field Summary
FieldsModifier and TypeFieldDescriptionstatic final booleanstatic final booleanstatic final booleanstatic final intstatic final intstatic final intstatic final intstatic final booleanprotected final HttpHeadersFactoryprotected final HttpHeadersFactoryprotected final booleanDeprecated.Fields inherited from class io.netty.handler.codec.ByteToMessageDecoder
COMPOSITE_CUMULATOR, MERGE_CUMULATOR -
Constructor Summary
ConstructorsModifierConstructorDescriptionprotectedCreates a new instance with the defaultmaxInitialLineLength (4096),maxHeaderSize (8192), andmaxChunkSize (8192).protectedHttpObjectDecoder(int maxInitialLineLength, int maxHeaderSize, int maxChunkSize, boolean chunkedSupported) Deprecated.protectedHttpObjectDecoder(int maxInitialLineLength, int maxHeaderSize, int maxChunkSize, boolean chunkedSupported, boolean validateHeaders) Deprecated.UseHttpObjectDecoder(HttpDecoderConfig)instead.protectedHttpObjectDecoder(int maxInitialLineLength, int maxHeaderSize, int maxChunkSize, boolean chunkedSupported, boolean validateHeaders, int initialBufferSize) Deprecated.UseHttpObjectDecoder(HttpDecoderConfig)instead.protectedHttpObjectDecoder(int maxInitialLineLength, int maxHeaderSize, int maxChunkSize, boolean chunkedSupported, boolean validateHeaders, int initialBufferSize, boolean allowDuplicateContentLengths) Deprecated.UseHttpObjectDecoder(HttpDecoderConfig)instead.protectedHttpObjectDecoder(int maxInitialLineLength, int maxHeaderSize, int maxChunkSize, boolean chunkedSupported, boolean validateHeaders, int initialBufferSize, boolean allowDuplicateContentLengths, boolean allowPartialChunks) Deprecated.UseHttpObjectDecoder(HttpDecoderConfig)instead.protectedHttpObjectDecoder(HttpDecoderConfig config) Creates a new instance with the specified configuration. -
Method Summary
Modifier and TypeMethodDescriptionprotected abstract HttpMessageprotected abstract HttpMessagecreateMessage(String[] initialLine) protected voiddecode(io.netty.channel.ChannelHandlerContext ctx, io.netty.buffer.ByteBuf buffer, List<Object> out) protected voiddecodeLast(io.netty.channel.ChannelHandlerContext ctx, io.netty.buffer.ByteBuf in, List<Object> out) protected voidhandlerRemoved0(io.netty.channel.ChannelHandlerContext ctx) protected voidInvoked when a message with both a "Transfer-Encoding: chunked" and a "Content-Length" header field is detected.protected booleanprotected abstract booleanprotected booleanReturns true if the server switched to a different protocol than HTTP/1.0 or HTTP/1.1, e.g.protected booleanisValidating(HttpHeadersFactory headersFactory) voidreset()Resets the state of the decoder so that it is ready to decode a new message.protected StringsplitFirstWordInitialLine(byte[] asciiContent, int start, int length) protected io.netty.util.AsciiStringsplitHeaderName(byte[] sb, int start, int length) protected StringsplitSecondWordInitialLine(byte[] asciiContent, int start, int length) protected StringsplitThirdWordInitialLine(byte[] asciiContent, int start, int length) voiduserEventTriggered(io.netty.channel.ChannelHandlerContext ctx, Object evt) Methods inherited from class io.netty.handler.codec.ByteToMessageDecoder
actualReadableBytes, callDecode, channelInactive, channelRead, channelReadComplete, discardSomeReadBytes, handlerRemoved, internalBuffer, isSingleDecode, setCumulator, setDiscardAfterReads, setSingleDecodeMethods inherited from class io.netty.channel.ChannelInboundHandlerAdapter
channelActive, channelRegistered, channelUnregistered, channelWritabilityChanged, exceptionCaughtMethods inherited from class io.netty.channel.ChannelHandlerAdapter
ensureNotSharable, handlerAdded, isSharableMethods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, waitMethods inherited from interface io.netty.channel.ChannelHandler
handlerAdded
-
Field Details
-
DEFAULT_MAX_INITIAL_LINE_LENGTH
public static final int DEFAULT_MAX_INITIAL_LINE_LENGTH- See Also:
-
DEFAULT_MAX_HEADER_SIZE
public static final int DEFAULT_MAX_HEADER_SIZE- See Also:
-
DEFAULT_CHUNKED_SUPPORTED
public static final boolean DEFAULT_CHUNKED_SUPPORTED- See Also:
-
DEFAULT_ALLOW_PARTIAL_CHUNKS
public static final boolean DEFAULT_ALLOW_PARTIAL_CHUNKS- See Also:
-
DEFAULT_MAX_CHUNK_SIZE
public static final int DEFAULT_MAX_CHUNK_SIZE- See Also:
-
DEFAULT_VALIDATE_HEADERS
public static final boolean DEFAULT_VALIDATE_HEADERS- See Also:
-
DEFAULT_INITIAL_BUFFER_SIZE
public static final int DEFAULT_INITIAL_BUFFER_SIZE- See Also:
-
DEFAULT_ALLOW_DUPLICATE_CONTENT_LENGTHS
public static final boolean DEFAULT_ALLOW_DUPLICATE_CONTENT_LENGTHS- See Also:
-
validateHeaders
Deprecated.This field is no longer used. It is only kept around for backwards compatibility purpose. -
headersFactory
-
trailersFactory
-
-
Constructor Details
-
HttpObjectDecoder
protected HttpObjectDecoder()Creates a new instance with the defaultmaxInitialLineLength (4096),maxHeaderSize (8192), andmaxChunkSize (8192). -
HttpObjectDecoder
@Deprecated protected HttpObjectDecoder(int maxInitialLineLength, int maxHeaderSize, int maxChunkSize, boolean chunkedSupported) Deprecated.UseHttpObjectDecoder(HttpDecoderConfig)instead.Creates a new instance with the specified parameters. -
HttpObjectDecoder
@Deprecated protected HttpObjectDecoder(int maxInitialLineLength, int maxHeaderSize, int maxChunkSize, boolean chunkedSupported, boolean validateHeaders) Deprecated.UseHttpObjectDecoder(HttpDecoderConfig)instead.Creates a new instance with the specified parameters. -
HttpObjectDecoder
@Deprecated protected HttpObjectDecoder(int maxInitialLineLength, int maxHeaderSize, int maxChunkSize, boolean chunkedSupported, boolean validateHeaders, int initialBufferSize) Deprecated.UseHttpObjectDecoder(HttpDecoderConfig)instead.Creates a new instance with the specified parameters. -
HttpObjectDecoder
@Deprecated protected HttpObjectDecoder(int maxInitialLineLength, int maxHeaderSize, int maxChunkSize, boolean chunkedSupported, boolean validateHeaders, int initialBufferSize, boolean allowDuplicateContentLengths) Deprecated.UseHttpObjectDecoder(HttpDecoderConfig)instead.Creates a new instance with the specified parameters. -
HttpObjectDecoder
@Deprecated protected HttpObjectDecoder(int maxInitialLineLength, int maxHeaderSize, int maxChunkSize, boolean chunkedSupported, boolean validateHeaders, int initialBufferSize, boolean allowDuplicateContentLengths, boolean allowPartialChunks) Deprecated.UseHttpObjectDecoder(HttpDecoderConfig)instead.Creates a new instance with the specified parameters. -
HttpObjectDecoder
Creates a new instance with the specified configuration.
-
-
Method Details
-
handlerRemoved0
- Overrides:
handlerRemoved0in classio.netty.handler.codec.ByteToMessageDecoder- Throws:
Exception
-
isValidating
-
decode
protected void decode(io.netty.channel.ChannelHandlerContext ctx, io.netty.buffer.ByteBuf buffer, List<Object> out) throws Exception - Specified by:
decodein classio.netty.handler.codec.ByteToMessageDecoder- Throws:
Exception
-
decodeLast
protected void decodeLast(io.netty.channel.ChannelHandlerContext ctx, io.netty.buffer.ByteBuf in, List<Object> out) throws Exception - Overrides:
decodeLastin classio.netty.handler.codec.ByteToMessageDecoder- Throws:
Exception
-
userEventTriggered
public void userEventTriggered(io.netty.channel.ChannelHandlerContext ctx, Object evt) throws Exception - Specified by:
userEventTriggeredin interfaceio.netty.channel.ChannelInboundHandler- Overrides:
userEventTriggeredin classio.netty.handler.codec.ByteToMessageDecoder- Throws:
Exception
-
isContentAlwaysEmpty
-
isSwitchingToNonHttp1Protocol
Returns true if the server switched to a different protocol than HTTP/1.0 or HTTP/1.1, e.g. HTTP/2 or Websocket. Returns false if the upgrade happened in a different layer, e.g. upgrade from HTTP/1.1 to HTTP/1.1 over TLS. -
reset
public void reset()Resets the state of the decoder so that it is ready to decode a new message. This method is useful for handling a rejected request withExpect: 100-continueheader. -
handleTransferEncodingChunkedWithContentLength
Invoked when a message with both a "Transfer-Encoding: chunked" and a "Content-Length" header field is detected. The default behavior is to remove the Content-Length field, but this method could be overridden to change the behavior (to, e.g., throw an exception and produce an invalid message).See: https://tools.ietf.org/html/rfc7230#section-3.3.3
If a message is received with both a Transfer-Encoding and a Content-Length header field, the Transfer-Encoding overrides the Content-Length. Such a message might indicate an attempt to perform request smuggling (Section 9.5) or response splitting (Section 9.4) and ought to be handled as an error. A sender MUST remove the received Content-Length field prior to forwarding such a message downstream.Also see: https://github.com/apache/tomcat/blob/b693d7c1981fa7f51e58bc8c8e72e3fe80b7b773/ java/org/apache/coyote/http11/Http11Processor.java#L747-L755 https://github.com/nginx/nginx/blob/0ad4393e30c119d250415cb769e3d8bc8dce5186/ src/http/ngx_http_request.c#L1946-L1953 -
isDecodingRequest
protected abstract boolean isDecodingRequest() -
createMessage
- Throws:
Exception
-
createInvalidMessage
-
splitFirstWordInitialLine
-
splitSecondWordInitialLine
-
splitThirdWordInitialLine
-
splitHeaderName
protected io.netty.util.AsciiString splitHeaderName(byte[] sb, int start, int length)
-
HttpObjectDecoder(HttpDecoderConfig)instead.