ServletOutputStream.isReady()
javadoc says the following:
Returns: true if a write to this ServletOutputStream will succeed, otherwise returns false.
In spite of that Jetty's ServletOutputStream
implementation, HttpOutput
seems to behave rather confusing in the case when the stream is in CLOSED
state. It returns true
:
case CLOSED:
return true;
Source: HttpOutput.java:1011.
Furthermore, all three write
methods in HttpOutput
throws EofException
when it's CLOSED
:
case CLOSED:
throw new EofException("Closed");
So it seems that write can never succeed. What's the reason behind this behavior?
Key Fact: A close call implies a write operation.
The CLOSED internal state indicates that usage of the stream/output is CLOSED to that dispatch (not that the stream itself is actually closed).
How did we get into this state? Something has triggered the
ServletOutputStream.close()
(and in turnHttpOutput.close()
) and now no more writes are allowed on that stream from the current dispatch.In the CLOSED state, a flush occurs.
Transfer-Encoding
layer (eg: chunked).The
HttpOutput
is also the one point of output for all nested requests, such as usinginclude()
fromRequestDispatcher
which will reopen theHttpOutput
for use during theinclude()
and then close it again.Once the
HttpOutput
is fully and completely flushed/finished (no more dispatches, no more writes, etc), then the final buffer flush is done, transfer-encodings are completed, the HttpOutput is reset, recycled, and returned to the HttpConnection for use with the next exchange.We could do a better job of javadoc'ing that in the codebase, or at least using constants and variable names that make more sense.
Opened https://github.com/eclipse/jetty.project/issues/2687
Regarding the Jetty
EofException
(not the JVMEOFException
) on write.Once the
ServletOutputStream
is CLOSED for usage on the specific dispatch, further calls towrite()
will result in a JettyEofException
.There is also a flavor of
EofException
where your committed response details were violated.Eg: you declared a response
Content-Length
of say 40MB, but wrote 41MB, you exceeded the capability of that committed response, this is an IOException. And the Servlet spec tells us to throw anIOException
in this case.Jetty will throw the Jetty internal
EofException
(which extends IOException) to indicate this specific scenario and abort the connection, breaking any connection persistence you may have wanted.