Class Http2AsyncUpgradeHandler

  • All Implemented Interfaces:
    HttpUpgradeHandler, InternalHttpUpgradeHandler

    public class Http2AsyncUpgradeHandler
    extends java.lang.Object
    Asynchronous HTTP/2 upgrade handler that uses non-blocking I/O for all operations.
    • Field Summary

      Fields 
      Modifier and Type Field Description
      protected java.util.concurrent.atomic.AtomicInteger activeRemoteStreamCount
      Count of currently active remote-initiated streams.
      protected java.lang.String connectionId
      Unique identifier for this connection.
      protected static int FLAG_END_OF_HEADERS
      Flag indicating the end of headers.
      protected static int FLAG_END_OF_STREAM
      Flag indicating the end of a stream.
      protected static byte[] GOAWAY
      GOAWAY frame header with zero stream ID.
      protected static org.apache.coyote.http2.HeaderSink HEADER_SINK
      Default header sink for HPACK decoding.
      protected org.apache.coyote.http2.ConnectionSettingsLocal localSettings
      Local settings are settings defined by Tomcat and sent to the client that the client must use when communicating with Tomcat.
      protected static Log log
      Logger for this class.
      protected static byte[] PING
      PING frame with zero payload length and zero stream ID.
      protected static byte[] PING_ACK
      PING ACK frame with zero payload length and zero stream ID.
      protected Http2Protocol protocol
      The HTTP/2 protocol configuration.
      protected static byte[] SETTINGS_ACK
      SETTINGS ACK frame with zero payload length and zero stream ID.
      protected static StringManager sm
      String manager for error messages.
      protected SocketWrapperBase<?> socketWrapper
      The socket wrapper for the underlying connection.
      protected static UserDataHelper userDataHelper
      Helper for user data logging with rate limiting.
      protected java.util.concurrent.locks.Condition windowAllocationAvailable
      Condition signaled when window allocation is available.
      protected java.util.concurrent.locks.Lock windowAllocationLock
      Lock for window allocation operations.
    • Method Summary

      All Methods Instance Methods Concrete Methods Default Methods Deprecated Methods 
      Modifier and Type Method Description
      protected byte[] createWindowUpdateForSettings()
      Creates a WINDOW_UPDATE frame if the initial window size exceeds the default.
      protected void decrementActiveRemoteStreamCount​(org.apache.coyote.http2.Stream stream)
      Decrements the active remote stream count and updates the connection timeout accordingly.
      void destroy()
      This method is called after the upgraded connection has been closed.
      protected org.apache.coyote.http2.Http2UpgradeHandler.HeaderFrameBuffers doWriteHeaders​(org.apache.coyote.http2.Stream stream, int pushedStreamId, MimeHeaders mimeHeaders, boolean endOfStream, int payloadSize)
      Write headers for a stream without synchronizing on socketWrapper.
      void endRequestBodyFrame​(int streamId, int dataLength)  
      default boolean fill​(boolean block, byte[] data)
      Convenience overload that fills the entire byte array.
      boolean fill​(boolean block, byte[] data, int offset, int length)  
      default boolean fill​(boolean block, java.nio.ByteBuffer data, int len)
      Convenience overload that fills a ByteBuffer.
      protected java.lang.String getConnectionId()  
      protected org.apache.coyote.http2.Http2UpgradeHandler.HeaderFrameBuffers getHeaderFrameBuffers​(int initialPayloadSize)
      Creates header frame buffers for writing headers.
      HpackDecoder getHpackDecoder()  
      protected org.apache.coyote.http2.HpackEncoder getHpackEncoder()
      Gets the HPACK encoder for this connection, creating it if necessary.
      int getMaxFrameSize()  
      protected org.apache.coyote.http2.Http2Parser getParser​(java.lang.String connectionId)
      Creates the HTTP/2 parser for this connection.
      protected org.apache.coyote.http2.Http2UpgradeHandler.PingManager getPingManager()
      Creates the ping manager instance for this connection.
      ServletConnection getServletConnection()
      Gets the servlet connection for this HTTP/2 connection.
      void goaway​(int lastStreamId, long errorCode, java.lang.String debugData)  
      protected void handleAppInitiatedIOException​(java.io.IOException ioe)
      Handles an I/O error on the socket underlying the HTTP/2 connection when it is triggered by application code (usually reading the request or writing the response).
      boolean hasAsyncIO()
      Checks if the handler is able to process asynchronous IO.
      void headersContinue​(int payloadSize, boolean endOfHeaders)  
      void headersEnd​(int streamId, boolean endOfStream)  
      org.apache.coyote.http2.HpackDecoder.HeaderEmitter headersStart​(int streamId, boolean headersEndStream)  
      void increaseOverheadCount​(org.apache.coyote.http2.FrameType frameType)  
      protected void increaseOverheadCount​(org.apache.coyote.http2.FrameType frameType, int increment)
      Used to increase the overhead for frames that don't use the overheadCountFactor (CONTINUATION, DATA, WINDOW_UPDATE and RESET).
      protected void incrementWindowSize​(int increment)  
      void incrementWindowSize​(int streamId, int increment)  
      void init​(WebConnection webConnection)
      This method is called once the request/response pair where HttpServletRequest.upgrade(Class) is called has completed processing and is the point where control of the connection passes from the container to the HttpUpgradeHandler.
      void onSwallowedDataFramePayload​(int streamId, int swallowedDataBytesCount)  
      void onSwallowedUnknownFrame​(int streamId, int frameTypeId, int flags, int size)  
      void pause()
      Pause processing for the connection.
      void pingReceive​(byte[] payload, boolean ack)  
      void priorityUpdate​(int prioritizedStreamID, Priority p)  
      protected void processConnection​(WebConnection webConnection, org.apache.coyote.http2.Stream stream)
      Process the connection initialization, sending initial ping and processing the first stream.
      protected SendfileState processSendfile​(org.apache.coyote.http2.SendfileData sendfile)
      Process send file (if supported) for the given stream.
      protected void processStreamOnContainerThread​(org.apache.coyote.http2.Stream stream)
      Process a stream on a container thread.
      protected void processWrites()
      Process pending writes, flushing the socket and potentially sending a ping.
      void receivedEndOfStream​(int streamId)  
      void reprioritise​(int streamId, int parentStreamId, boolean exclusive, int weight)
      Deprecated.
      Unused.
      void reset​(int streamId, long errorCode)  
      protected void sentEndOfStream​(org.apache.coyote.http2.Stream stream)
      Handle the end of stream for a given stream, updating active stream counts.
      protected void setConnectionTimeoutForStreamCount​(int streamCount)
      Sets the connection timeout based on the current number of active streams.
      void setSocketWrapper​(SocketWrapperBase<?> wrapper)
      Associate with the specified socket.
      void setSslSupport​(SSLSupport sslSupport)
      Associate with the specified SSL support.
      void setting​(org.apache.coyote.http2.Setting setting, long value)  
      void settingsEnd​(boolean ack)  
      java.nio.ByteBuffer startRequestBodyFrame​(int streamId, int dataLength, boolean endOfStream)  
      void timeoutAsync​(long now)
      Check for a possible timeout.
      AbstractEndpoint.Handler.SocketState upgradeDispatch​(SocketEvent status)
      Process the specified event.
      protected void writeGoAwayFrame​(int maxStreamId, long errorCode, byte[] debugMsg)
      Write a GOAWAY frame to signal the peer that no more streams will be accepted.
      protected void writeSettings()
      Write the initial settings frame and any necessary supporting frames.
      • Methods inherited from class java.lang.Object

        clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
    • Field Detail

      • log

        protected static final Log log
        Logger for this class.
      • sm

        protected static final StringManager sm
        String manager for error messages.
      • FLAG_END_OF_STREAM

        protected static final int FLAG_END_OF_STREAM
        Flag indicating the end of a stream.
        See Also:
        Constant Field Values
      • FLAG_END_OF_HEADERS

        protected static final int FLAG_END_OF_HEADERS
        Flag indicating the end of headers.
        See Also:
        Constant Field Values
      • PING

        protected static final byte[] PING
        PING frame with zero payload length and zero stream ID.
      • PING_ACK

        protected static final byte[] PING_ACK
        PING ACK frame with zero payload length and zero stream ID.
      • SETTINGS_ACK

        protected static final byte[] SETTINGS_ACK
        SETTINGS ACK frame with zero payload length and zero stream ID.
      • GOAWAY

        protected static final byte[] GOAWAY
        GOAWAY frame header with zero stream ID.
      • HEADER_SINK

        protected static final org.apache.coyote.http2.HeaderSink HEADER_SINK
        Default header sink for HPACK decoding.
      • userDataHelper

        protected static final UserDataHelper userDataHelper
        Helper for user data logging with rate limiting.
      • connectionId

        protected final java.lang.String connectionId
        Unique identifier for this connection.
      • protocol

        protected final Http2Protocol protocol
        The HTTP/2 protocol configuration.
      • socketWrapper

        protected final SocketWrapperBase<?> socketWrapper
        The socket wrapper for the underlying connection.
      • localSettings

        protected final org.apache.coyote.http2.ConnectionSettingsLocal localSettings
        Local settings are settings defined by Tomcat and sent to the client that the client must use when communicating with Tomcat.
      • activeRemoteStreamCount

        protected final java.util.concurrent.atomic.AtomicInteger activeRemoteStreamCount
        Count of currently active remote-initiated streams.
      • windowAllocationLock

        protected final java.util.concurrent.locks.Lock windowAllocationLock
        Lock for window allocation operations.
      • windowAllocationAvailable

        protected final java.util.concurrent.locks.Condition windowAllocationAvailable
        Condition signaled when window allocation is available.
    • Constructor Detail

      • Http2AsyncUpgradeHandler

        public Http2AsyncUpgradeHandler​(Http2Protocol protocol,
                                        Adapter adapter,
                                        Request coyoteRequest,
                                        SocketWrapperBase<?> socketWrapper)
        Creates a new async HTTP/2 upgrade handler.
        Parameters:
        protocol - the HTTP/2 protocol handler
        adapter - the adapter to pass requests to
        coyoteRequest - the initial HTTP/1.1 request
        socketWrapper - the socket wrapper for the connection
    • Method Detail

      • getParser

        protected org.apache.coyote.http2.Http2Parser getParser​(java.lang.String connectionId)
        Creates the HTTP/2 parser for this connection.
        Parameters:
        connectionId - the connection identifier
        Returns:
        the HTTP/2 parser
      • getPingManager

        protected org.apache.coyote.http2.Http2UpgradeHandler.PingManager getPingManager()
        Creates the ping manager instance for this connection.
        Returns:
        the ping manager
      • hasAsyncIO

        public boolean hasAsyncIO()
        Description copied from interface: InternalHttpUpgradeHandler
        Checks if the handler is able to process asynchronous IO.
        Returns:
        true if able to process asynchronous IO, default is false
      • processConnection

        protected void processConnection​(WebConnection webConnection,
                                         org.apache.coyote.http2.Stream stream)
        Process the connection initialization, sending initial ping and processing the first stream.
        Parameters:
        webConnection - the web connection, may be null for direct HTTP/2
        stream - the initial stream
      • writeSettings

        protected void writeSettings()
        Write the initial settings frame and any necessary supporting frames. If the initial settings increase the initial window size, it will also be necessary to send a WINDOW_UPDATE frame to increase the size of the flow control window for the connection (stream 0).
      • writeGoAwayFrame

        protected void writeGoAwayFrame​(int maxStreamId,
                                        long errorCode,
                                        byte[] debugMsg)
                                 throws java.io.IOException
        Write a GOAWAY frame to signal the peer that no more streams will be accepted.
        Parameters:
        maxStreamId - the maximum stream ID processed
        errorCode - the error code
        debugMsg - optional debug message
        Throws:
        java.io.IOException - if an I/O error occurs
      • getHeaderFrameBuffers

        protected org.apache.coyote.http2.Http2UpgradeHandler.HeaderFrameBuffers getHeaderFrameBuffers​(int initialPayloadSize)
        Creates header frame buffers for writing headers.
        Parameters:
        initialPayloadSize - the initial payload size
        Returns:
        the header frame buffers
      • settingsEnd

        public void settingsEnd​(boolean ack)
                         throws java.io.IOException
        Throws:
        java.io.IOException
      • processSendfile

        protected SendfileState processSendfile​(org.apache.coyote.http2.SendfileData sendfile)
        Process send file (if supported) for the given stream. The appropriate request attributes should be set before calling this method.
        Parameters:
        sendfile - The stream and associated data to process
        Returns:
        The result of the send file processing
      • processStreamOnContainerThread

        protected void processStreamOnContainerThread​(org.apache.coyote.http2.Stream stream)
        Process a stream on a container thread.
        Parameters:
        stream - the stream to process
      • decrementActiveRemoteStreamCount

        protected void decrementActiveRemoteStreamCount​(org.apache.coyote.http2.Stream stream)
        Decrements the active remote stream count and updates the connection timeout accordingly.
        Parameters:
        stream - the stream that is being closed
      • setConnectionTimeoutForStreamCount

        protected void setConnectionTimeoutForStreamCount​(int streamCount)
        Sets the connection timeout based on the current number of active streams. When no streams are active, uses the keep-alive timeout. Otherwise keeps the connection open.
        Parameters:
        streamCount - the current number of active streams
      • createWindowUpdateForSettings

        protected byte[] createWindowUpdateForSettings()
        Creates a WINDOW_UPDATE frame if the initial window size exceeds the default.
        Returns:
        The WINDOW_UPDATE frame if one is required or an empty array if no WINDOW_UPDATE is required.
      • doWriteHeaders

        protected org.apache.coyote.http2.Http2UpgradeHandler.HeaderFrameBuffers doWriteHeaders​(org.apache.coyote.http2.Stream stream,
                                                                                                int pushedStreamId,
                                                                                                MimeHeaders mimeHeaders,
                                                                                                boolean endOfStream,
                                                                                                int payloadSize)
                                                                                         throws java.io.IOException
        Write headers for a stream without synchronizing on socketWrapper. Separate method to allow Http2AsyncUpgradeHandler to call this code without synchronizing on socketWrapper since it doesn't need to.
        Parameters:
        stream - the stream to write headers for
        mimeHeaders - the headers to write
        endOfStream - whether this is the end of the stream
        payloadSize - the initial payload size for the header frame
        Returns:
        the header frame buffers
        Throws:
        java.io.IOException - if an I/O error occurs
      • getHpackEncoder

        protected org.apache.coyote.http2.HpackEncoder getHpackEncoder()
        Gets the HPACK encoder for this connection, creating it if necessary.
        Returns:
        the HPACK encoder
      • sentEndOfStream

        protected void sentEndOfStream​(org.apache.coyote.http2.Stream stream)
        Handle the end of stream for a given stream, updating active stream counts.
        Parameters:
        stream - the stream that has ended
      • handleAppInitiatedIOException

        protected void handleAppInitiatedIOException​(java.io.IOException ioe)
                                              throws java.io.IOException
        Handles an I/O error on the socket underlying the HTTP/2 connection when it is triggered by application code (usually reading the request or writing the response). Such I/O errors are fatal so the connection is closed. The exception is re-thrown to make the client code aware of the problem. Note: We can not rely on this exception reaching the socket processor since the application code may swallow it.
        Parameters:
        ioe - the I/O exception
        Throws:
        java.io.IOException - the same I/O exception is re-thrown after closing the connection
      • processWrites

        protected void processWrites()
                              throws java.io.IOException
        Process pending writes, flushing the socket and potentially sending a ping.
        Throws:
        java.io.IOException - if an I/O error occurs
      • incrementWindowSize

        protected void incrementWindowSize​(int increment)
                                    throws org.apache.coyote.http2.Http2Exception
        Throws:
        org.apache.coyote.http2.Http2Exception
      • getConnectionId

        protected final java.lang.String getConnectionId()
      • increaseOverheadCount

        public void increaseOverheadCount​(org.apache.coyote.http2.FrameType frameType)
      • increaseOverheadCount

        protected void increaseOverheadCount​(org.apache.coyote.http2.FrameType frameType,
                                             int increment)
        Used to increase the overhead for frames that don't use the overheadCountFactor (CONTINUATION, DATA, WINDOW_UPDATE and RESET).
        Parameters:
        frameType - The frame type triggering the overhead increase
        increment - The amount by which the overhead is increased
      • fill

        public boolean fill​(boolean block,
                            byte[] data,
                            int offset,
                            int length)
                     throws java.io.IOException
        Throws:
        java.io.IOException
      • getMaxFrameSize

        public int getMaxFrameSize()
      • startRequestBodyFrame

        public java.nio.ByteBuffer startRequestBodyFrame​(int streamId,
                                                         int dataLength,
                                                         boolean endOfStream)
                                                  throws org.apache.coyote.http2.Http2Exception
        Throws:
        org.apache.coyote.http2.Http2Exception
      • endRequestBodyFrame

        public void endRequestBodyFrame​(int streamId,
                                        int dataLength)
                                 throws org.apache.coyote.http2.Http2Exception,
                                        java.io.IOException
        Throws:
        org.apache.coyote.http2.Http2Exception
        java.io.IOException
      • onSwallowedDataFramePayload

        public void onSwallowedDataFramePayload​(int streamId,
                                                int swallowedDataBytesCount)
                                         throws java.io.IOException
        Throws:
        java.io.IOException
      • headersStart

        public org.apache.coyote.http2.HpackDecoder.HeaderEmitter headersStart​(int streamId,
                                                                               boolean headersEndStream)
                                                                        throws org.apache.coyote.http2.Http2Exception,
                                                                               java.io.IOException
        Throws:
        org.apache.coyote.http2.Http2Exception
        java.io.IOException
      • reprioritise

        @Deprecated
        public void reprioritise​(int streamId,
                                 int parentStreamId,
                                 boolean exclusive,
                                 int weight)
                          throws org.apache.coyote.http2.Http2Exception
        Deprecated.
        Unused. Will be removed in Tomcat 11 onwards.
        Unused - NO-OP.
        Parameters:
        streamId - Unused
        parentStreamId - Unused
        exclusive - Unused
        weight - Unused
        Throws:
        org.apache.coyote.http2.Http2Exception - Never thrown
      • headersContinue

        public void headersContinue​(int payloadSize,
                                    boolean endOfHeaders)
      • headersEnd

        public void headersEnd​(int streamId,
                               boolean endOfStream)
                        throws org.apache.coyote.http2.Http2Exception
        Throws:
        org.apache.coyote.http2.Http2Exception
      • receivedEndOfStream

        public void receivedEndOfStream​(int streamId)
                                 throws org.apache.coyote.http2.Http2Exception
        Throws:
        org.apache.coyote.http2.Http2Exception
      • reset

        public void reset​(int streamId,
                          long errorCode)
                   throws org.apache.coyote.http2.Http2Exception
        Throws:
        org.apache.coyote.http2.Http2Exception
      • setting

        public void setting​(org.apache.coyote.http2.Setting setting,
                            long value)
                     throws org.apache.coyote.http2.ConnectionException
        Throws:
        org.apache.coyote.http2.ConnectionException
      • pingReceive

        public void pingReceive​(byte[] payload,
                                boolean ack)
                         throws java.io.IOException
        Throws:
        java.io.IOException
      • goaway

        public void goaway​(int lastStreamId,
                           long errorCode,
                           java.lang.String debugData)
      • incrementWindowSize

        public void incrementWindowSize​(int streamId,
                                        int increment)
                                 throws org.apache.coyote.http2.Http2Exception
        Throws:
        org.apache.coyote.http2.Http2Exception
      • priorityUpdate

        public void priorityUpdate​(int prioritizedStreamID,
                                   Priority p)
                            throws org.apache.coyote.http2.Http2Exception
        Throws:
        org.apache.coyote.http2.Http2Exception
      • onSwallowedUnknownFrame

        public void onSwallowedUnknownFrame​(int streamId,
                                            int frameTypeId,
                                            int flags,
                                            int size)
                                     throws java.io.IOException
        Throws:
        java.io.IOException
      • getServletConnection

        public ServletConnection getServletConnection()
        Gets the servlet connection for this HTTP/2 connection.
        Returns:
        the servlet connection
      • fill

        public default boolean fill​(boolean block,
                                    byte[] data)
                             throws java.io.IOException
        Convenience overload that fills the entire byte array.
        Parameters:
        block - Should the first read into the provided buffer be a blocking read or not
        data - Buffer to fill
        Returns:
        true if the buffer was filled otherwise false
        Throws:
        java.io.IOException - If an I/O occurred while obtaining data with which to fill the buffer
      • fill

        public default boolean fill​(boolean block,
                                    java.nio.ByteBuffer data,
                                    int len)
                             throws java.io.IOException
        Convenience overload that fills a ByteBuffer.
        Parameters:
        block - Should the first read into the provided buffer be a blocking read or not
        data - Buffer to fill
        len - Number of bytes to read
        Returns:
        true if the buffer was filled otherwise false
        Throws:
        java.io.IOException - If an I/O occurred while obtaining data with which to fill the buffer