It occurs to me on Debian I have Nginx in front of Undertow, so it's almost certainly Nginx causing the behavior. I'll dig into that now. Thanks for listening anyway! Undertow has been very nice to use so far, kudos!


On Wed, Jun 17, 2020 at 1:49 AM Nate <nate@n4te.com> wrote:
On Wed, Jun 17, 2020 at 1:02 AM Stuart Douglas <sdouglas@redhat.com> wrote:
Is there a way I can know when the client has received all the data, even if it is buffered at the system level?

If you call flush() on the OutputStream is won't return until the client has recieved and acked the data AFAIK.

Alright, I tried this:

System.out.println("start");
PooledByteBuffer poolBuffer = exchange.getConnection().getByteBufferPool().getArrayBackedPool().allocate();
byte[] buffer = poolBuffer.getBuffer().array(); // buffer.length is 16KB.
exchange.startBlocking();
OutputStream output = exchange.getOutputStream();
try (var input = new FileInputStream(file)) {
    while (true) {
        int count = input.read(buffer);
        if (count == -1) break;
        output.flush(); // Before write() to avoid flushing a closed OutputStream.
        output.write(buffer, 0, count);
    }
}
exchange.endExchange();
System.out.println("end");

When I hit the URL, I see "start" and "end" printed immediately in the server log even though the curl download takes much, much longer at 10 bytes/sec.

That was on Debian. Next I tried the same on Windows 10 and there I see only "start" while the download is in progress. That is true even if I remove the flush.

So it seems it is something specific about Debian or its configuration. Any idea what is happening, or other ideas on how I can know when the client has really received the data?

Cheers,
-Nate