Class HttpObjectDecoder

  • All Implemented Interfaces:
    ChannelHandler
    Direct Known Subclasses:
    HttpRequestDecoder, HttpResponseDecoder, RtspDecoder

    public abstract class HttpObjectDecoder
    extends ByteToMessageDecoder
    Decodes Buffers into HttpMessages and HttpContents.

    Parameters that prevents excessive memory consumption

    NameDefault valueMeaning
    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.

    Parameters that control parsing behavior

    NameDefault valueMeaning
    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.

    Chunked Content

    If the content of an HTTP message is greater than maxChunkSize 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:
    1. An HttpRequest,
    2. The first HttpContent whose content is 'abcdefghijklmnopqrstuvwxyz',
    3. The second LastHttpContent whose content is '1234567890abcdef', which marks the end of the content.
    If you prefer not to handle 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.
    • Field Detail

      • DEFAULT_MAX_INITIAL_LINE_LENGTH

        public static final int DEFAULT_MAX_INITIAL_LINE_LENGTH
        See Also:
        Constant Field Values
      • DEFAULT_MAX_HEADER_SIZE

        public static final int DEFAULT_MAX_HEADER_SIZE
        See Also:
        Constant Field Values
      • DEFAULT_CHUNKED_SUPPORTED

        public static final boolean DEFAULT_CHUNKED_SUPPORTED
        See Also:
        Constant Field Values
      • DEFAULT_VALIDATE_HEADERS

        public static final boolean DEFAULT_VALIDATE_HEADERS
        See Also:
        Constant Field Values
      • DEFAULT_INITIAL_BUFFER_SIZE

        public static final int DEFAULT_INITIAL_BUFFER_SIZE
        See Also:
        Constant Field Values
      • DEFAULT_ALLOW_DUPLICATE_CONTENT_LENGTHS

        public static final boolean DEFAULT_ALLOW_DUPLICATE_CONTENT_LENGTHS
        See Also:
        Constant Field Values
      • validateHeaders

        protected final boolean validateHeaders
    • Constructor Detail

      • HttpObjectDecoder

        protected HttpObjectDecoder()
        Creates a new instance with the default maxInitialLineLength (4096}, maxHeaderSize (8192), and maxChunkSize (8192).
      • HttpObjectDecoder

        protected HttpObjectDecoder​(int maxInitialLineLength,
                                    int maxHeaderSize,
                                    boolean chunkedSupported)
        Creates a new instance with the specified parameters.
      • HttpObjectDecoder

        protected HttpObjectDecoder​(int maxInitialLineLength,
                                    int maxHeaderSize,
                                    boolean chunkedSupported,
                                    boolean validateHeaders)
        Creates a new instance with the specified parameters.
      • HttpObjectDecoder

        protected HttpObjectDecoder​(int maxInitialLineLength,
                                    int maxHeaderSize,
                                    boolean chunkedSupported,
                                    boolean validateHeaders,
                                    int initialBufferSize)
        Creates a new instance with the specified parameters.
      • HttpObjectDecoder

        protected HttpObjectDecoder​(int maxInitialLineLength,
                                    int maxHeaderSize,
                                    boolean chunkedSupported,
                                    boolean validateHeaders,
                                    int initialBufferSize,
                                    boolean allowDuplicateContentLengths)
    • Method Detail

      • isContentAlwaysEmpty

        protected boolean isContentAlwaysEmpty​(HttpMessage msg)
      • isSwitchingToNonHttp1Protocol

        protected boolean isSwitchingToNonHttp1Protocol​(HttpResponse msg)
        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 with Expect: 100-continue header.
      • handleTransferEncodingChunkedWithContentLength

        protected void handleTransferEncodingChunkedWithContentLength​(HttpMessage message)
        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()