Hi,

<snip/>

I've debugged further with Wireshark:

1) Golang: https://pasteboard.co/Jsnvx1z.png  (SETTINGS, HEADERS+DATA)
2) Nodejs: https://pasteboard.co/JsnwRNV.png (SETTINGS, HEADERS+PARTIAL
DATA, DATA)
3) Rust: https://pasteboard.co/JsnxvKGU.png  (SETTINGS, HEADERS+PARTIAL
DATA+DATA)
4) Netty: https://pasteboard.co/JsnxYJp.png (SETTINGS+HEADERS+DATA)
5) Tomcat: https://pasteboard.co/JsnyjpA.png (SETTINGS, HEADERS, DATA)

>From the images above you can see that only Tomcat sends two separate
packets for HEADERS and DATA frames. All others put several frames into one
packet.
Netty puts the SETTINGS, the HEADERS and the DATA into one TCP packet. I
guess this is the reason for the high throughput
Node.js writes the HEADERS and PARTIAL DATA in one packet and the actual
DATA in a separate one
Rust also uses PARTIAL DATA but puts the actual one in the same TCP packet
Tomcat's way is spec compliant but most probably is also a reason for the
lower throughput.

More findings:
I've debugged Netty code and it never receives RST_STREAM with CANCEL error
at
https://github.com/martin-g/http2-server-perf-tests/blob/2f628c407e2ea29be99e756a61e555d88addaa01/java/netty-http2-test/src/main/java/com/example/netty/http2/Http2ServerResponseHandler.java#L30
I've looked at Golang net code and found that it will send RST_STREAM with
CANCEL if there is a problem reading the body:
https://github.com/tsenart/vegeta/issues/540#issuecomment-696757695
It is not clear to me whether this is about the request body or response
body. But since the unit test uses Transport.RoundTrip() I think it is
about the response body.
So, it looks like Tomcat sends a DATA frame which is not liked by Golang
net package code and Golang sends this CANCEL error that causes the
problems.
The DATA frames in Wireshark look good to me, but I've made them by using
Firefox as a client to be able to decrypt TLS in Wireshark (SSLKEYLOGFILE)

Martin

Reply via email to