https://bz.apache.org/bugzilla/show_bug.cgi?id=66385

            Bug ID: 66385
           Summary: NIO2 with HTTP/2 wrong Timeout behaviour
           Product: Tomcat 10
           Version: 10.1.4
          Hardware: PC
                OS: Linux
            Status: NEW
          Severity: normal
          Priority: P2
         Component: Connectors
          Assignee: dev@tomcat.apache.org
          Reporter: rainer.j...@kippdata.de
  Target Milestone: ------

I observe the following behavior for 10.1.4, but it might neither be a
regression nor version specific at all.

I am calling a JSP which writes a few bytes, then does "Thread.sleep(20000);"
and then writes the remaining things.

When calling it with HTTP/1.1 it works for all connector types.

When calling it with HTTP/2 it works for NIO, but not for NIO2. After a shorter
time than the 20 seconds, I get an "empty reply from server" in curl and the
browser. The request processing actually continues, but of course the stream is
closed so the trying to write the result after 20 seconds fails.

It happens for JSSE and tcnative.

The behavior seems to be related to the NIO2 readTimeout setting. The empty
reply error happens exactly after the amount of time set there and when
increasing it slightly above the sleep time in the JSP, I get the correct
result. Another possibility is, that it is the writeTimeout but that it
erroneously uses the value for the readTimeout.

Using trace logging and looking at the http2 log lines, all of those are the
same for NIO and for NIO2.

Here are the full logs for one failing request. The problem happens at the
SocketTimeout at 12:50:40.

12:51:30,382 [exec-0] util.threads.LimitLatch (LimitLatch.java:115) - Counting
up[exec-0] latch=1
12:51:30,407 [exec-0] util.net.SecureNio2Channel (SecureNio2Channel.java:432) -
The SNI host name extracted for connection
[sun.nio.ch.UnixAsynchronousSocketChannelImpl[connected local=/0.2.3.4:8244
remote=/1.2.3.1:58186]] was [myserver]
12:51:30,471 [exec-1] http11.Http11Nio2Protocol (AbstractProtocol.java:761) -
Processing socket
[org.apache.tomcat.util.net.SecureNio2Channel@39a7a1e8:sun.nio.ch.UnixAsynchronousSocketChannelImpl[connected
local=/1.2.3.4:8244 remote=/1.2.3.1:58186]] with status [OPEN_READ]
12:51:30,472 [exec-1] http11.Http11Nio2Protocol (AbstractProtocol.java:777) -
Found processor [null] for socket
[org.apache.tomcat.util.net.SecureNio2Channel@39a7a1e8:sun.nio.ch.UnixAsynchronousSocketChannelImpl[connected
local=/1.2.3.4:8244 remote=/1.2.3.1:58186]]
12:51:30,473 [exec-1] http2.ConnectionSettingsBase
(ConnectionSettingsBase.java:66) - Connection [1], Endpoint
[Local(client->server)], Parameter type [3] set to [100]
12:51:30,473 [exec-1] http2.ConnectionSettingsBase
(ConnectionSettingsBase.java:66) - Connection [1], Endpoint
[Local(client->server)], Parameter type [4] set to [65535]
12:51:30,473 [exec-1] http11.Http11Nio2Protocol (AbstractProtocol.java:812) -
Created new processor
[org.apache.coyote.http11.upgrade.UpgradeProcessorInternal@376048ac]
12:51:30,473 [exec-1] http2.Http2UpgradeHandler (Http2UpgradeHandler.java:331)
- Entry, Connection [1], SocketStatus [OPEN_READ]
12:51:30,473 [exec-1] http2.Http2UpgradeHandler (Http2UpgradeHandler.java:202)
- Connection [1], State [NEW]
12:51:30,480 [exec-1] http2.Http2Parser (Http2Parser.java:669) - Connection
[1], Stream [0], Frame type [SETTINGS], Flags [0], Payload size [18]
12:51:30,480 [exec-1] http2.Http2UpgradeHandler (Http2UpgradeHandler.java:1520)
- Connection [1], Stream [0], Frame type [SETTINGS] resulted in new overhead
count of [-90]
12:51:30,480 [exec-1] http2.ConnectionSettingsBase
(ConnectionSettingsBase.java:66) - Connection [1], Endpoint
[Remote(server->client)], Parameter type [3] set to [100]
12:51:30,481 [exec-1] http2.Http2UpgradeHandler (Http2UpgradeHandler.java:1520)
- Connection [1], Stream [0], Frame type [SETTINGS] resulted in new overhead
count of [-80]
12:51:30,481 [exec-1] http2.ConnectionSettingsBase
(ConnectionSettingsBase.java:66) - Connection [1], Endpoint
[Remote(server->client)], Parameter type [4] set to [1073741824]
12:51:30,481 [exec-1] http2.Http2UpgradeHandler (Http2UpgradeHandler.java:1520)
- Connection [1], Stream [0], Frame type [SETTINGS] resulted in new overhead
count of [-70]
12:51:30,481 [exec-1] http2.ConnectionSettingsBase
(ConnectionSettingsBase.java:66) - Connection [1], Endpoint
[Remote(server->client)], Parameter type [2] set to [0]
12:51:30,482 [exec-1] http2.Http2UpgradeHandler (Http2UpgradeHandler.java:331)
- Entry, Connection [1], SocketStatus [OPEN_READ]
12:51:30,482 [exec-1] http2.Http2UpgradeHandler (Http2UpgradeHandler.java:202)
- Connection [1], State [CONNECTED]
12:51:30,483 [exec-1] http2.Http2Parser (Http2Parser.java:669) - Connection
[1], Stream [0], Frame type [WINDOW_UPDATE], Flags [0], Payload size [4]
12:51:30,483 [exec-1] http2.Http2Parser (Http2Parser.java:430) - Connection
[1], Stream [0], Window size increment [1073676289]
12:51:30,483 [exec-1] http2.AbstractStream (AbstractStream.java:130) -
Connection [1], Stream [0], increase flow control window by [1073676289] to
[1073741824]
12:51:30,483 [exec-1] http2.Http2Parser (Http2Parser.java:669) - Connection
[1], Stream [1], Frame type [HEADERS], Flags [5], Payload size [52]
12:51:30,484 [exec-1] http2.StreamStateMachine (StreamStateMachine.java:115) -
Connection [1], Stream [1], State changed from [null] to [IDLE]
12:51:30,484 [exec-1] http2.StreamStateMachine (StreamStateMachine.java:115) -
Connection [1], Stream [1], State changed from [IDLE] to [OPEN]
12:51:30,485 [exec-1] http2.Http2Parser (Http2Parser.java:481) - Connection
[1], Stream [1], Processing headers payload of size [52]
12:51:30,485 [exec-1] http2.HpackDecoder (HpackDecoder.java:302) - Using header
from index [2] of static table
12:51:30,485 [exec-1] http2.HpackDecoder (HpackDecoder.java:443) - Emitting
header with name [:method] and value [GET]
12:51:30,485 [exec-1] http2.Stream (Stream.java:291) - Connection [1], Stream
[1], HTTP header [:method], Value [GET]
12:51:30,486 [exec-1] http2.HpackDecoder (HpackDecoder.java:443) - Emitting
header with name [:path] and value [/qs/sleep.jsp]
12:51:30,486 [exec-1] http2.Stream (Stream.java:291) - Connection [1], Stream
[1], HTTP header [:path], Value [/qs/sleep.jsp]
12:51:30,486 [exec-1] http2.HpackDecoder (HpackDecoder.java:302) - Using header
from index [7] of static table
12:51:30,486 [exec-1] http2.HpackDecoder (HpackDecoder.java:443) - Emitting
header with name [:scheme] and value [https]
12:51:30,486 [exec-1] http2.Stream (Stream.java:291) - Connection [1], Stream
[1], HTTP header [:scheme], Value [https]
12:51:30,486 [exec-1] http2.HpackDecoder (HpackDecoder.java:443) - Emitting
header with name [:authority] and value [myserver:8244]
12:51:30,487 [exec-1] http2.Stream (Stream.java:291) - Connection [1], Stream
[1], HTTP header [:authority], Value [myserver:8244]
12:51:30,487 [exec-1] http2.HpackDecoder (HpackDecoder.java:330) - Adding
header to index [0] of dynamic table with name [:authority] and value
[myserver:8244]
12:51:30,487 [exec-1] http2.HpackDecoder (HpackDecoder.java:443) - Emitting
header with name [user-agent] and value [curl/7.61.1]
12:51:30,487 [exec-1] http2.Stream (Stream.java:291) - Connection [1], Stream
[1], HTTP header [user-agent], Value [curl/7.61.1]
12:51:30,488 [exec-1] http2.HpackDecoder (HpackDecoder.java:330) - Adding
header to index [1] of dynamic table with name [user-agent] and value
[curl/7.61.1]
12:51:30,488 [exec-1] http2.HpackDecoder (HpackDecoder.java:443) - Emitting
header with name [accept] and value [*/*]
12:51:30,488 [exec-1] http2.Stream (Stream.java:291) - Connection [1], Stream
[1], HTTP header [accept], Value [*/*]
12:51:30,488 [exec-1] http2.HpackDecoder (HpackDecoder.java:330) - Adding
header to index [2] of dynamic table with name [accept] and value [*/*]
12:51:30,488 [exec-1] http2.Http2Parser (Http2Parser.java:580) - Connection
[1], Stream [1], Swallowed [0] bytes
12:51:30,489 [exec-1] http2.Http2UpgradeHandler (Http2UpgradeHandler.java:1520)
- Connection [1], Stream [0], Frame type [HEADERS] resulted in new overhead
count of [-90]
12:51:30,489 [exec-1] http2.StreamStateMachine (StreamStateMachine.java:115) -
Connection [1], Stream [1], State changed from [OPEN] to [HALF_CLOSED_REMOTE]
12:51:30,490 [exec-1] http2.Http2Parser (Http2Parser.java:669) - Connection
[1], Stream [0], Frame type [SETTINGS], Flags [1], Payload size [0]
12:51:30,490 [exec-1] http2.Http2Parser (Http2Parser.java:669) - Connection
[1], Stream [0], Frame type [PING], Flags [1], Payload size [8]
12:51:30,490 [exec-1] http2.Http2UpgradeHandler (Http2UpgradeHandler.java:2017)
- Connection [1] Round trip time measured as [8,209,582]ns
12:51:30,491 [exec-1] http2.Http2UpgradeHandler (Http2UpgradeHandler.java:451)
- Exit, Connection [1], SocketState [ASYNC_IO]
12:51:30,491 [exec-1] http2.Http2UpgradeHandler (Http2UpgradeHandler.java:266)
- Connection [1], Connection preface received from client
12:51:30,492 [exec-1] http2.Http2UpgradeHandler (Http2UpgradeHandler.java:451)
- Exit, Connection [1], SocketState [ASYNC_IO]
12:51:30,492 [exec-1] http11.upgrade.UpgradeProcessorInternal
(AbstractProcessorLight.java:75) - Socket:
[org.apache.tomcat.util.net.Nio2Endpoint$Nio2SocketWrapper@c0f9ad3:org.apache.tomcat.util.net.SecureNio2Channel@39a7a1e8:sun.nio.ch.UnixAsynchronousSocketChannelImpl[connected
local=/1.2.3.4:8244 remote=/1.2.3.1:58186]], Status in: [OPEN_READ], State out:
[ASYNC_IO]
12:51:30,491 [exec-2] util.http.Parameters (Parameters.java:106) - Set query
string encoding to UTF-8
12:51:30,493 [exec-2] authenticator.AuthenticatorBase
(AuthenticatorBase.java:504) - Security checking request GET /qs/sleep.jsp
12:51:30,494 [exec-2] realm.RealmBase (RealmBase.java:555) -   No applicable
constraints defined
12:51:30,494 [exec-2] authenticator.AuthenticatorBase
(AuthenticatorBase.java:540) - Not subject to any constraint
12:51:30,494 [exec-2] org.apache.catalina.core.StandardWrapper
(StandardWrapper.java:701) -   Returning instance
12:51:30,494 [exec-2] servlet.JspServlet (JspServlet.java:318) - JspEngine -->
/sleep.jsp
12:51:30,494 [exec-2] servlet.JspServlet (JspServlet.java:319) -     
ServletPath: /sleep.jsp
12:51:30,494 [exec-2] servlet.JspServlet (JspServlet.java:320) -      
PathInfo: null
12:51:30,495 [exec-2] servlet.JspServlet (JspServlet.java:321) -      
RealPath: /opt/instances/tomcat101-10.1.4-nio2-timeout/webapps/qs/sleep.jsp
12:51:30,495 [exec-2] servlet.JspServlet (JspServlet.java:322) -     
RequestURI: /qs/sleep.jsp
12:51:30,495 [exec-2] servlet.JspServlet (JspServlet.java:323) -     
QueryString: null
12:51:40,493 [exec-3] http2.Http2Parser (Http2AsyncParser.java:325) -
Connection [1], Stream [0], Frame type [null], Error
java.net.SocketTimeoutException: null
    at
org.apache.tomcat.util.net.SocketWrapperBase$VectoredIOCompletionHandler.failed(SocketWrapperBase.java:1124)
~[tomcat-coyote.jar:10.1.4]
    at
org.apache.tomcat.util.net.SocketWrapperBase$VectoredIOCompletionHandler.failed(SocketWrapperBase.java:1066)
~[tomcat-coyote.jar:10.1.4]
    at
org.apache.tomcat.util.net.SecureNio2Channel$2.failed(SecureNio2Channel.java:1158)
~[tomcat-coyote.jar:10.1.4]
    at sun.nio.ch.Invoker.invokeUnchecked(Invoker.java:129) ~[?:?]
    at sun.nio.ch.Invoker$2.run(Invoker.java:219) ~[?:?]
    at
sun.nio.ch.AsynchronousChannelGroupImpl$1.run(AsynchronousChannelGroupImpl.java:112)
~[?:?]
    at
org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191)
~[tomcat-util.jar:10.1.4]
    at
org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659)
~[tomcat-util.jar:10.1.4]
    at
org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
~[tomcat-util.jar:10.1.4]
    at java.lang.Thread.run(Thread.java:834) ~[?:?]
12:51:40,497 [exec-3] http2.Http2UpgradeHandler (Http2UpgradeHandler.java:331)
- Entry, Connection [1], SocketStatus [ERROR]
12:51:40,497 [exec-3] http2.Http2UpgradeHandler (Http2UpgradeHandler.java:202)
- Connection [1], State [CONNECTED]
12:51:40,497 [exec-3] http2.Stream (Stream.java:190) - Connection [1], Stream
[1], Reset received due to [8]
12:51:40,498 [exec-3] http2.StreamStateMachine (StreamStateMachine.java:115) -
Connection [1], Stream [1], State changed from [HALF_CLOSED_REMOTE] to
[CLOSED_RST_RX]
12:51:40,498 [exec-3] http2.WindowAllocationManager
(WindowAllocationManager.java:179) - Connection [1], Stream [1], Waiting type
[0], Notify type [3]
12:51:40,498 [exec-3] http11.Http11Nio2Protocol (AbstractProtocol.java:387) -
Removed processor
[org.apache.coyote.http11.upgrade.UpgradeProcessorInternal@376048ac] from
waiting processors
12:51:40,499 [exec-3] util.threads.LimitLatch (LimitLatch.java:128) - Counting
down[https-jsse-nio2-8244-exec-6] latch=1
12:51:40,500 [exec-3] util.net.Nio2Endpoint (Nio2Endpoint.java:940) - Calling
[org.apache.tomcat.util.net.Nio2Endpoint@2873d672].closeSocket([org.apache.tomcat.util.net.Nio2Endpoint$Nio2SocketWrapper@c0f9ad3:org.apache.tomcat.util.net.SecureNio2Channel@39a7a1e8:sun.nio.ch.UnixAsynchronousSocketChannelImpl[connected
local=/1.2.3.4:8244 remote=/1.2.3.1:58186]])
12:51:40,503 [exec-3] http2.Http2UpgradeHandler (Http2UpgradeHandler.java:451)
- Exit, Connection [1], SocketState [CLOSED]

-- 
You are receiving this mail because:
You are the assignee for the bug.
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org

Reply via email to