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

      protected final int getHeaderWorkspaceLimit()
      Obtain the maximum size to which the header encoding workspace may be expanded. HPACK reserves space using uncompressed header lengths before attempting Huffman encoding. The shortest Huffman codes use five bits per octet, so literals may need up to 8/5 of their encoded size as workspace. Twice the peer's maximum frame payload size allows for this estimate and encoding overhead. Indexed fields still need space for this estimate even though their encoded representation is only a few bytes. Allow at least the peer's dynamic table capacity so existing entries remain usable after a frame size reduction. The 32-byte overhead of a table entry exceeds the encoder's 12-byte estimate overhead. This is only a workspace limit: frame payloads are checked separately against the peer's advertised maximum before they are written.
      Returns:
      the workspace limit in bytes
    • 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 void 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