eclipse-ee4j / grizzly

Grizzly
https://eclipse-ee4j.github.io/grizzly
Other
148 stars 69 forks source link

HTTP Upgrade header causes reading of payload to block, clients timeout if no upgrade filter is available #2117

Closed scholzi100 closed 1 year ago

scholzi100 commented 3 years ago

If a request with a payload and Upgrade header is received but the server has no filter to handle this specific upgrade the connection times out. This is also reflected in issue #1972, specific to h2c. But it does also work with random header values like 123.

This is not the expected behavior as defined in RFC 7230. If the protocol can not be switched:

A server MAY choose to ignore the order of preference indicated by the client and select the new protocol(s) based on other factors, such as the nature of the request or the current load on the server. RFC 7230: 6.7 Upgrade

If the server decides to upgrade the connection, it sends back a 101 Switching Protocols response status with an Upgrade header that specifies the protocol(s) being switched to. If it does not (or cannot) upgrade the connection, it ignores the Upgrade header and sends back a regular response (for example, a 200 OK). MDN Web docs: Protocol upgrade mechanism

If no filter for a specific upgrade path is avaliable, it should use the current protocol like nothing happend.

After some testing with and without upgrade filter org.glassfish.jersey.message.internal.ReaderWriter#readFromAsString(java.io.Reader) reads the payload. But if no filter is available some how it stalls while reading from the reader.

scholzi100 commented 3 years ago

ReaderWriter#readFromAsString(java.io.Reader) does block because of the underlying Buffer. Its calls to InputBuffer#read* then InputBuffer#fill()* blocks since ignoreContentModifiers was set true in onIncomingUpgrade* and was never reset on the upgrade path.