On 29/01/2025 12:50, Rémy Maucherat wrote:
On Wed, Jan 29, 2025 at 1:14 PM Mark Thomas <ma...@apache.org> wrote:

On 29/01/2025 09:56, r...@apache.org wrote:
This is an automated email from the ASF dual-hosted git repository.

remm pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/tomcat.git


The following commit(s) were added to refs/heads/main by this push:
       new e1cde6f020 Work around available tricks
e1cde6f020 is described below

commit e1cde6f02080d4d9346d3e401f1e3c5c739eb14e
Author: remm <r...@apache.org>
AuthorDate: Wed Jan 29 10:56:09 2025 +0100

      Work around available tricks

      available() needs to be called even though the first read returned 0
      bytes.
      Going through everything it seems "normal" and there is no real
      workaround.

Thanks for the test case.

The one thing that doesn't look quite right is that isReady() returns
true but then we read zero bytes. I need to re-read the Servlet spec and
Javadoc around non-blocking reads to remind myself exactly what the
expected behaviour is.

Here onDataAvailable gets called but there are 0 bytes to read.

Agreed. Because while there are bytes on the wire, they are part of the chunk header. So data is read but it is effectively swallowed by the ChunkedInputFilter and the application sees a zero byte read.

After
that the problem is that the user still has to call available/isReady,
which would return 0 again. Since available/isReady is not called
first I would say there's not much to fix (I did make changes that I
have yet to commit to handle the chunk headers) even if it returns > 0
despite not having bytes (worst case would be a second zero bytes
read).
Is this really a problem and unexpected ? The TLS API is a bit the
same, so IMO it's simply the usual non blocking IO API problems.

Having re-read the Javadoc for ServletInputStream (it was clarified for Servlet 6.1 / Tomcat 11) I agree with you. After a read() that returns anything other than -1 to indicate EOF - including 0 - the user/application has to call isReady(). The test case wasn't doing that hence it was a bug in the test case.

So for 69545, there's no reproduction (unless it's caused by not
calling available/isReady after a zero bytes read).

Which would be an application bug.

I still don't
think the code changes in available() are causing a regression since
they don't affect this scenario.

In theory it should be possible to refactor things so the application doesn't see a zero byte read in this case but that would be a huge refactoring for little to no benefit given that applications should be making the necessary call to isReady() anyway. There zero byte read might be unexpected but there is nothing in the Javadoc that prevents it as a result of isReady() returning true or onDataAvailable() firing.

This one might need redirecting to the Spring team.

Mark


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org

Reply via email to