Hey,
I was working on a web server implemented with undertow and came across
a weird inconsistency. When setting the response content length of an
exchange and then writing to its output stream, normally the output
self-closes as soon as the proper content length is hit. However, it
turns out that this does not happen when content length is zero. This
leads to the response remaining open if you've previously dispatch()ed it.
The code in question is here:
https://github.com/yawkat/aggressive-cache/blob/fcd59ef0d35d8cd6102eceed1...
- the relevant bit goes as follows:
exchange.startBlocking();
exchange.dispatch();
... later ...
exchange.setResponseContentLength(body.length);
exchange.getOutputStream().write(r.body);
(I'm aware that I should avoid no-arg dispatch, and that I should be
closing the output stream - this was a rushed side project)
I've tracked down the issue to this class:
https://github.com/undertow-io/undertow/blob/master/core/src/main/java/io...
Normally, updateWritten(long) checks whether the content length has been
reached and if so, closes the stream and writes the response. However,
when passing an empty array to write(byte[], int, int), we run into a
length check and updateWritten is never executed, and thus the stream is
never closed.
Is this a bug? I know the issue came from me using undertow improperly,
but it certainly is inconsistent. To me it seems like the idea here is
to close the stream when the response is done, which does not happen
when writing a 0-length array. However it could also be argued that
outputstream.write(new byte[0]) should never do anything.
If this is a bug, I'll happily make an issue and a PR for it if that's
better for you - it doesn't look like it's that much work.
Thank you,
- Jonas