Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

AbstractListenerReadPublisher does not call ServletOutputStream::isReady() when reading chunked data across network packets #28241

Closed
poutsma opened this issue Mar 28, 2022 · 0 comments
Assignees
Labels
in: web Issues in web modules (web, webmvc, webflux, websocket) type: bug A general bug
Milestone

Comments

@poutsma
Copy link
Contributor

poutsma commented Mar 28, 2022

When a client POSTs data using chunked encoding, and a network packet ends immediately after the chunk header, but before the chunk body, the AbstractListenerReadPublisher hangs under Tomcat, especially in constrained environments.

When the packet that ends with the chunk header is received, Tomcat calls ReadListener::onDataAvailable().
The ServletServerHttpRequest.RequestBodyPublisher calls ServletOutputStream::isReady(), which returns true.
The RequestBodyPublisher tries to read data, and Tomcat processes the chunk header (so data has been read from the network).
However, there is no actual content available (yet), so Tomcat returns 0 bytes.
The RequestBodyPublisher sees no data has been read, and switches state to DEMAND.
The RequestBodyPublisher doesn't call isReady() because it assumes the read terminated, as isReady() returned false.
No call to isReady() means the socket is not registered for read and everything hangs.

Special thanks to @markt-asf for investigating the issue, and providing the description above.

@poutsma poutsma added in: web Issues in web modules (web, webmvc, webflux, websocket) type: bug A general bug labels Mar 28, 2022
@poutsma poutsma added this to the 5.3.18 milestone Mar 28, 2022
@snicoll snicoll modified the milestones: 5.3.18, 5.3.19 Mar 31, 2022
poutsma added a commit that referenced this issue Apr 12, 2022
This commit makes sure that TomcatServerHttpRequest::readFromInputStream
follows the same contract as the method it overrides, and returns
AbstractListenerReadPublisher.EMPTY_BUFFER when 0 bytes are read.

See gh-28241
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: web Issues in web modules (web, webmvc, webflux, websocket) type: bug A general bug
Projects
None yet
Development

No branches or pull requests

3 participants