Undertow read-timeout can cause closing a connection for a long-running request even if the request processing is not reading any request data.
This issue can happen notably and easily. However, this can rarely happen with a normal request. (For example, when channel.read(buffer) returns 0 and HttpReadListener.handleFailedRead() triggers ReadTimeoutStreamSourceConduit through channel.resumeReads().)
As per Flavia's analysis, it appears that HttpReadListener is skipping the call to channel.suspendReads() (= ReadTimeoutStreamSourceConduit.suspendReads()) that would cancel the read-timeout expiration.
—
The following is a detailed scenario of when the issue happens with the KeepAlive connection.
When read-timeout is configured on Undertow http-listener, ReadTimeoutStreamSourceConduit's timeoutCommand is registered to executeAfter on an I/O thread for KeepAlive connection at HttpReadListener.exchangeComplete().
In the next request which comes through the KeepAlive connection, expireTime will be updated when reading data from the channel. However, timeoutCommand is still registered, so it can be invoked in the middle of the long-running request processing that is not reading any request data.
read-timeout should only affect the request processing which is reading request data that takes longer time than the specified value.
In addition, the access-log will log the request returned as "200 OK" from I/O thread in such a case. That is not correct.
- clones
-
JBEAP-21266 [GSS](7.4.z) UNDERTOW-1856 UNDERTOW-1858 - Undertow read-timeout can cause closing a connection for long running request even if the request processing is not reading any request data
- Closed
- is cloned by
-
UNDERTOW-1856 Undertow read-timeout can cause closing a connection for long running request even if the request processing is not reading any request data
- Resolved
- is incorporated by
-
JBEAP-22200 (7.3.z) Upgrade Undertow from 2.0.38.SP1-redhat-00001 to 2.0.39-SP1-redhat-00001
- Closed