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

            Bug ID: 58659
           Summary: Http2Parser.readFrame() hanging on an unconditional
                    blocking read is necessary (TestHttp2Section_5_3 test)
           Product: Tomcat 9
           Version: 9.0.0.M1
          Hardware: PC
            Status: NEW
          Severity: normal
          Priority: P2
         Component: Catalina
          Assignee: dev@tomcat.apache.org
          Reporter: knst.koli...@gmail.com

Trunk at revision 1716783

Buildbot run:
https://ci.apache.org/builders/tomcat-trunk/builds/690

Log file:
https://ci.apache.org/projects/tomcat/tomcat9/logs/logs/1716783/TEST-org.apache.coyote.http2.TestHttp2Section_5_3.NIO.txt

In TestHttp2Section_5_3.java there is a comment on lines 127-144:

// The loop below handles 0, 1 or 2 stream being blocked
<...>
// - If 2 streams are blocked the connection window will be set to one
//   but one byte will be permitted for both streams (due to rounding in
//   the allocation). The window size should be -1 (see below). Two
//   frames (one for each stream will be written) one of which will be
//   consumed by the client. The loop will start again and the Window
//   size incremented to zero. No data will be written by the streams
//   but the second data frame written in the last iteration of the loop
//   will be read. The loop will then exit since frames from both
//   streams will have been observed.

The sequence of events in while(!seen19 || !seen21) loop (line 147) on this
test run was:
iteration 1: a body of stream 21 was read ("21-Body-1")
iteration 2: "parser.readFrame(true);" call blocks until it times out after
waiting for 30 seconds

[[[
Testcase: testWeighting took 35.576 sec
    Caused an ERROR
Read timed out
java.net.SocketTimeoutException: Read timed out
    at java.net.SocketInputStream.socketRead0(Native Method)
    at java.net.SocketInputStream.socketRead(SocketInputStream.java:116)
    at java.net.SocketInputStream.read(SocketInputStream.java:170)
    at java.net.SocketInputStream.read(SocketInputStream.java:141)
    at
org.apache.coyote.http2.Http2TestBase$TestInput.fill(Http2TestBase.java:720)
    at org.apache.coyote.http2.Http2Parser$Input.fill(Http2Parser.java:565)
    at org.apache.coyote.http2.Http2Parser.readFrame(Http2Parser.java:75)
    at org.apache.coyote.http2.Http2Parser.readFrame(Http2Parser.java:68)
    at
org.apache.coyote.http2.TestHttp2Section_5_3.testWeighting(TestHttp2Section_5_3.java:149)
]]]

My concern is implementation of Http2Parser.readFrame() method.
It starts with unconditionally calling "input.fill(block, frameHeaderBuffer)"
regardless of whether the frame bytes have already been read. I think it shall
check whether the blocking read is necessary or if enough the data have already
been received.

The comment that I cited says "but the second data frame written in the last
iteration of the loop will be read". I think that because of unconditional call
to input.fill() the thread will block reading for data, regardless of whether
the second data frame has already been received.

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