Class Http2AsyncUpgradeHandler

java.lang.Object
org.apache.coyote.http2.Http2AsyncUpgradeHandler
All Implemented Interfaces:
HttpUpgradeHandler, InternalHttpUpgradeHandler

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

    • 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:
    • FLAG_END_OF_HEADERS

      protected static final int FLAG_END_OF_HEADERS
      Flag indicating the end of headers.
      See Also:
    • 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 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 AtomicInteger activeRemoteStreamCount
      Count of currently active remote-initiated streams.
    • windowAllocationLock

      protected final Lock windowAllocationLock
      Lock for window allocation operations.
    • windowAllocationAvailable

      protected final Condition windowAllocationAvailable
      Condition signaled when window allocation is available.
  • Constructor Details

    • 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 Details

    • getParser

      protected org.apache.coyote.http2.Http2Parser getParser(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 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:
      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 IOException
      Throws:
      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
    • init

      public void init(WebConnection webConnection)
      Description copied from interface: jakarta.servlet.http.HttpUpgradeHandler
      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.
      Specified by:
      init in interface HttpUpgradeHandler
      Parameters:
      webConnection - The connection that has been upgraded
    • 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
    • setSocketWrapper

      public void setSocketWrapper(SocketWrapperBase<?> wrapper)
      Description copied from interface: InternalHttpUpgradeHandler
      Associate with the specified socket.
      Specified by:
      setSocketWrapper in interface InternalHttpUpgradeHandler
      Parameters:
      wrapper - the socket
    • setSslSupport

      public void setSslSupport(SSLSupport sslSupport)
      Description copied from interface: InternalHttpUpgradeHandler
      Associate with the specified SSL support.
      Specified by:
      setSslSupport in interface InternalHttpUpgradeHandler
      Parameters:
      sslSupport - the SSL support
    • upgradeDispatch

      public AbstractEndpoint.Handler.SocketState upgradeDispatch(SocketEvent status)
      Description copied from interface: InternalHttpUpgradeHandler
      Process the specified event.
      Specified by:
      upgradeDispatch in interface InternalHttpUpgradeHandler
      Parameters:
      status - the event
      Returns:
      the status following the event
    • 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
    • timeoutAsync

      public void timeoutAsync(long now)
      Description copied from interface: InternalHttpUpgradeHandler
      Check for a possible timeout.
      Specified by:
      timeoutAsync in interface InternalHttpUpgradeHandler
      Parameters:
      now - the time to use for the timeout check
    • pause

      public void pause()
      Description copied from interface: InternalHttpUpgradeHandler
      Pause processing for the connection.
      Specified by:
      pause in interface InternalHttpUpgradeHandler
    • destroy

      public void destroy()
      Description copied from interface: jakarta.servlet.http.HttpUpgradeHandler
      This method is called after the upgraded connection has been closed.
      Specified by:
      destroy in interface HttpUpgradeHandler
    • 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 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:
      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(IOException ioe) throws 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:
      IOException - the same I/O exception is re-thrown after closing the connection
    • processWrites

      protected void processWrites() throws IOException
      Process pending writes, flushing the socket and potentially sending a ping.
      Throws:
      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 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 IOException
      Throws:
      IOException
    • getMaxFrameSize

      public int getMaxFrameSize()
    • getHpackDecoder

      public HpackDecoder getHpackDecoder()
    • startRequestBodyFrame

      public 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, IOException
      Throws:
      org.apache.coyote.http2.Http2Exception
      IOException
    • onSwallowedDataFramePayload

      public void onSwallowedDataFramePayload(int streamId, int swallowedDataBytesCount) throws IOException
      Throws:
      IOException
    • headersStart

      public org.apache.coyote.http2.HpackDecoder.HeaderEmitter headersStart(int streamId, boolean headersEndStream) throws org.apache.coyote.http2.Http2Exception, IOException
      Throws:
      org.apache.coyote.http2.Http2Exception
      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 IOException
      Throws:
      IOException
    • goaway

      public void goaway(int lastStreamId, long errorCode, 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 IOException
      Throws:
      IOException
    • getServletConnection

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

      default boolean fill(boolean block, byte[] data) throws 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:
      IOException - If an I/O occurred while obtaining data with which to fill the buffer
    • fill

      default boolean fill(boolean block, ByteBuffer data, int len) throws 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:
      IOException - If an I/O occurred while obtaining data with which to fill the buffer