Package org.apache.coyote.http2
Class Http2AsyncUpgradeHandler
- java.lang.Object
-
- org.apache.coyote.http2.Http2AsyncUpgradeHandler
-
- All Implemented Interfaces:
HttpUpgradeHandler,InternalHttpUpgradeHandler
public class Http2AsyncUpgradeHandler extends java.lang.ObjectAsynchronous HTTP/2 upgrade handler that uses non-blocking I/O for all operations.
-
-
Nested Class Summary
Nested Classes Modifier and Type Class Description protected classHttp2AsyncUpgradeHandler.AsyncPingManagerAsynchronous ping manager for HTTP/2 connections.protected classHttp2AsyncUpgradeHandler.SendfileCompletionHandlerCompletion handler for asynchronous sendfile operations.
-
Field Summary
Fields Modifier and Type Field Description protected java.util.concurrent.atomic.AtomicIntegeractiveRemoteStreamCountCount of currently active remote-initiated streams.protected java.lang.StringconnectionIdUnique identifier for this connection.protected static intFLAG_END_OF_HEADERSFlag indicating the end of headers.protected static intFLAG_END_OF_STREAMFlag indicating the end of a stream.protected static byte[]GOAWAYGOAWAY frame header with zero stream ID.protected static org.apache.coyote.http2.HeaderSinkHEADER_SINKDefault header sink for HPACK decoding.protected org.apache.coyote.http2.ConnectionSettingsLocallocalSettingsLocal settings are settings defined by Tomcat and sent to the client that the client must use when communicating with Tomcat.protected static LoglogLogger for this class.protected static byte[]PINGPING frame with zero payload length and zero stream ID.protected static byte[]PING_ACKPING ACK frame with zero payload length and zero stream ID.protected Http2ProtocolprotocolThe HTTP/2 protocol configuration.protected static byte[]SETTINGS_ACKSETTINGS ACK frame with zero payload length and zero stream ID.protected static StringManagersmString manager for error messages.protected SocketWrapperBase<?>socketWrapperThe socket wrapper for the underlying connection.protected static UserDataHelperuserDataHelperHelper for user data logging with rate limiting.protected java.util.concurrent.locks.ConditionwindowAllocationAvailableCondition signaled when window allocation is available.protected java.util.concurrent.locks.LockwindowAllocationLockLock for window allocation operations.
-
Constructor Summary
Constructors Constructor Description Http2AsyncUpgradeHandler(Http2Protocol protocol, Adapter adapter, Request coyoteRequest, SocketWrapperBase<?> socketWrapper)Creates a new async HTTP/2 upgrade handler.
-
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 voiddecrementActiveRemoteStreamCount(org.apache.coyote.http2.Stream stream)Decrements the active remote stream count and updates the connection timeout accordingly.voiddestroy()This method is called after the upgraded connection has been closed.protected org.apache.coyote.http2.Http2UpgradeHandler.HeaderFrameBuffersdoWriteHeaders(org.apache.coyote.http2.Stream stream, int pushedStreamId, MimeHeaders mimeHeaders, boolean endOfStream, int payloadSize)Write headers for a stream without synchronizing on socketWrapper.voidendRequestBodyFrame(int streamId, int dataLength)default booleanfill(boolean block, byte[] data)Convenience overload that fills the entire byte array.booleanfill(boolean block, byte[] data, int offset, int length)default booleanfill(boolean block, java.nio.ByteBuffer data, int len)Convenience overload that fills aByteBuffer.protected java.lang.StringgetConnectionId()protected org.apache.coyote.http2.Http2UpgradeHandler.HeaderFrameBuffersgetHeaderFrameBuffers(int initialPayloadSize)Creates header frame buffers for writing headers.HpackDecodergetHpackDecoder()protected org.apache.coyote.http2.HpackEncodergetHpackEncoder()Gets the HPACK encoder for this connection, creating it if necessary.intgetMaxFrameSize()protected org.apache.coyote.http2.Http2ParsergetParser(java.lang.String connectionId)Creates the HTTP/2 parser for this connection.protected org.apache.coyote.http2.Http2UpgradeHandler.PingManagergetPingManager()Creates the ping manager instance for this connection.ServletConnectiongetServletConnection()Gets the servlet connection for this HTTP/2 connection.voidgoaway(int lastStreamId, long errorCode, java.lang.String debugData)protected voidhandleAppInitiatedIOException(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).booleanhasAsyncIO()Checks if the handler is able to process asynchronous IO.voidheadersContinue(int payloadSize, boolean endOfHeaders)voidheadersEnd(int streamId, boolean endOfStream)org.apache.coyote.http2.HpackDecoder.HeaderEmitterheadersStart(int streamId, boolean headersEndStream)voidincreaseOverheadCount(org.apache.coyote.http2.FrameType frameType)protected voidincreaseOverheadCount(org.apache.coyote.http2.FrameType frameType, int increment)Used to increase the overhead for frames that don't use theoverheadCountFactor(CONTINUATION,DATA,WINDOW_UPDATEandRESET).protected voidincrementWindowSize(int increment)voidincrementWindowSize(int streamId, int increment)voidinit(WebConnection webConnection)This method is called once the request/response pair whereHttpServletRequest.upgrade(Class)is called has completed processing and is the point where control of the connection passes from the container to theHttpUpgradeHandler.voidonSwallowedDataFramePayload(int streamId, int swallowedDataBytesCount)voidonSwallowedUnknownFrame(int streamId, int frameTypeId, int flags, int size)voidpause()Pause processing for the connection.voidpingReceive(byte[] payload, boolean ack)voidpriorityUpdate(int prioritizedStreamID, Priority p)protected voidprocessConnection(WebConnection webConnection, org.apache.coyote.http2.Stream stream)Process the connection initialization, sending initial ping and processing the first stream.protected SendfileStateprocessSendfile(org.apache.coyote.http2.SendfileData sendfile)Process send file (if supported) for the given stream.protected voidprocessStreamOnContainerThread(org.apache.coyote.http2.Stream stream)Process a stream on a container thread.protected voidprocessWrites()Process pending writes, flushing the socket and potentially sending a ping.voidreceivedEndOfStream(int streamId)voidreprioritise(int streamId, int parentStreamId, boolean exclusive, int weight)Deprecated.Unused.voidreset(int streamId, long errorCode)protected voidsentEndOfStream(org.apache.coyote.http2.Stream stream)Handle the end of stream for a given stream, updating active stream counts.protected voidsetConnectionTimeoutForStreamCount(int streamCount)Sets the connection timeout based on the current number of active streams.voidsetSocketWrapper(SocketWrapperBase<?> wrapper)Associate with the specified socket.voidsetSslSupport(SSLSupport sslSupport)Associate with the specified SSL support.voidsetting(org.apache.coyote.http2.Setting setting, long value)voidsettingsEnd(boolean ack)java.nio.ByteBufferstartRequestBodyFrame(int streamId, int dataLength, boolean endOfStream)voidtimeoutAsync(long now)Check for a possible timeout.AbstractEndpoint.Handler.SocketStateupgradeDispatch(SocketEvent status)Process the specified event.protected voidwriteGoAwayFrame(int maxStreamId, long errorCode, byte[] debugMsg)Write a GOAWAY frame to signal the peer that no more streams will be accepted.protected voidwriteSettings()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
-
Methods inherited from interface org.apache.coyote.http11.upgrade.InternalHttpUpgradeHandler
getUpgradeInfo
-
-
-
-
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 handleradapter- the adapter to pass requests tocoyoteRequest- the initial HTTP/1.1 requestsocketWrapper- 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:InternalHttpUpgradeHandlerChecks if the handler is able to process asynchronous IO.- Returns:
trueif able to process asynchronous IO, default isfalse
-
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/2stream- 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.IOExceptionWrite a GOAWAY frame to signal the peer that no more streams will be accepted.- Parameters:
maxStreamId- the maximum stream ID processederrorCode- the error codedebugMsg- 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
-
init
public void init(WebConnection webConnection)
Description copied from interface:jakarta.servlet.http.HttpUpgradeHandlerThis method is called once the request/response pair whereHttpServletRequest.upgrade(Class)is called has completed processing and is the point where control of the connection passes from the container to theHttpUpgradeHandler.- Specified by:
initin interfaceHttpUpgradeHandler- 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:InternalHttpUpgradeHandlerAssociate with the specified socket.- Specified by:
setSocketWrapperin interfaceInternalHttpUpgradeHandler- Parameters:
wrapper- the socket
-
setSslSupport
public void setSslSupport(SSLSupport sslSupport)
Description copied from interface:InternalHttpUpgradeHandlerAssociate with the specified SSL support.- Specified by:
setSslSupportin interfaceInternalHttpUpgradeHandler- Parameters:
sslSupport- the SSL support
-
upgradeDispatch
public AbstractEndpoint.Handler.SocketState upgradeDispatch(SocketEvent status)
Description copied from interface:InternalHttpUpgradeHandlerProcess the specified event.- Specified by:
upgradeDispatchin interfaceInternalHttpUpgradeHandler- 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:InternalHttpUpgradeHandlerCheck for a possible timeout.- Specified by:
timeoutAsyncin interfaceInternalHttpUpgradeHandler- Parameters:
now- the time to use for the timeout check
-
pause
public void pause()
Description copied from interface:InternalHttpUpgradeHandlerPause processing for the connection.- Specified by:
pausein interfaceInternalHttpUpgradeHandler
-
destroy
public void destroy()
Description copied from interface:jakarta.servlet.http.HttpUpgradeHandlerThis method is called after the upgraded connection has been closed.- Specified by:
destroyin interfaceHttpUpgradeHandler
-
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.IOExceptionWrite 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 formimeHeaders- the headers to writeendOfStream- whether this is the end of the streampayloadSize- 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.IOExceptionHandles 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.IOExceptionProcess 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 theoverheadCountFactor(CONTINUATION,DATA,WINDOW_UPDATEandRESET).- Parameters:
frameType- The frame type triggering the overhead increaseincrement- 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()
-
getHpackDecoder
public HpackDecoder getHpackDecoder()
-
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.Http2Exceptionjava.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.Http2Exceptionjava.io.IOException
-
reprioritise
@Deprecated public void reprioritise(int streamId, int parentStreamId, boolean exclusive, int weight) throws org.apache.coyote.http2.Http2ExceptionDeprecated.Unused. Will be removed in Tomcat 11 onwards.Unused - NO-OP.- Parameters:
streamId- UnusedparentStreamId- Unusedexclusive- Unusedweight- 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.IOExceptionConvenience overload that fills the entire byte array.- Parameters:
block- Should the first read into the provided buffer be a blocking read or notdata- Buffer to fill- Returns:
trueif the buffer was filled otherwisefalse- 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.IOExceptionConvenience overload that fills aByteBuffer.- Parameters:
block- Should the first read into the provided buffer be a blocking read or notdata- Buffer to filllen- Number of bytes to read- Returns:
trueif the buffer was filled otherwisefalse- Throws:
java.io.IOException- If an I/O occurred while obtaining data with which to fill the buffer
-
-