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

            Bug ID: 70248
           Summary: Uploads fail over HTTP/2: Tomcat closes the connection
                    with "payload is [16777215] bytes long but the maximum
                    frame size is [16384]"
           Product: Tomcat 9
           Version: 9.0.122
          Hardware: Other
                OS: Linux
            Status: NEW
          Severity: regression
          Priority: P2
         Component: Connectors
          Assignee: [email protected]
          Reporter: [email protected]
  Target Milestone: -----

Environment
- Server: Apache Tomcat 9.0.122 on Linux (kernel 5.15.0-3.60.5.1.el8uek), Java
1.8.0_472 (Red Hat OpenJDK)
- Connector: https-jsse-nio-8282 (NIO, JSSE/TLS, no Tomcat Native/OpenSSL),
HTTP/2 enabled via UpgradeProtocol and negotiated as h2 via ALPN

Analysis
- 16777215 (0xFFFFFF) is the largest value an HTTP/2 frame's 3-byte length
field can hold. Browsers don't send frames larger than the server allows (16384
by default), so this isn't a real frame. Tomcat is reading bytes from the
middle of the data stream as if they were a frame header, meaning it has lost
track of where frames start and end.
- TLS ends at Tomcat, and TLS guarantees the bytes aren't changed on the way.
So either Tomcat's HTTP/2 reader loses its place, or something between the
browser and Tomcat that decrypts and re-encrypts HTTPS garbles the traffic.
- The error is raised in Http2AsyncParser, which Tomcat uses only when async
I/O is on (useAsyncIO="true", the default).
- Ruled out:
  - Tomcat's HTTP/2 overhead protection: no ENHANCE_YOUR_CALM in the log.
  - Upload size limits: no size-exceeded errors. The Grails limits are
maxFileSize/maxRequestSize = 100 MB.

Configuration of error case in server.xml:
<Connector port="8282" protocol="org.apache.coyote.http11.Http11NioProtocol" 
                           maxThreads="100"
                           scheme="https" 
                           secure="true" 
                           SSLEnabled="true" 
                           maxPartCount="1000"   >

<UpgradeProtocol className="org.apache.coyote.http2.Http2Protocol"
                     overheadDataThreshold="0"
                     overheadWindowUpdateThreshold="0" />

<SSLHostConfig>
            <Certificate
certificateKeystoreFile="/opt/keystore/certificates.pfx"
certificateKeystorePassword="ChangeIt"/>
</SSLHostConfig>
</Connector>


Workaround:
Set useAsyncIO="false" on the 8282 connector so Tomcat uses its other HTTP/2
reader

-- 
You are receiving this mail because:
You are the assignee for the bug.
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to