Hi,
I'm running jetty 9.1.1, the last invocation of ServletOutputStream.isReady() will return true in WriteListener.onWritePossible(), but after I set Content-Length response header, then it doesn't work.
test code (2 classes):
@WebServlet(name = "EchoAsyncServlet", urlPatterns = { "/echo_async" }, asyncSupported = true)
public class EchoAsyncServlet extends HttpServlet {
private static final long serialVersionUID = -8434727468202612595L;
private static final byte[] RESPONSE = "V".getBytes();
@Override
public void service(final HttpServletRequest req, final HttpServletResponse resp) throws IOException {
AsyncContext asyncCtx = req.startAsync(req, resp);
asyncCtx.setTimeout(10_000);
ServletOutputStream out = resp.getOutputStream();
out.setWriteListener(new TextWriteListener(RESPONSE, asyncCtx, out));
}
}
public class TextWriteListener implements WriteListener {
private final byte[] text;
private final AsyncContext asyncCtx;
private final ServletOutputStream out;
public TextWriteListener(byte[] text, AsyncContext asyncCtx, ServletOutputStream out) {
super();
this.text = text;
this.asyncCtx = asyncCtx;
this.out = out;
}
@Override
public void onError(Throwable t) {
t.printStackTrace();
asyncCtx.complete();
}
private boolean written;
@Override
public synchronized void onWritePossible() throws IOException {
while (true) {
final boolean ready = out.isReady();
System.out.println(String.format("onWritePossible> asyncCtx=%s, ready=%s, written=%s", asyncCtx, ready,
written));
if (!ready) {
break;
}
if (written) {
asyncCtx.complete();
return;
} else {
// comment this line to test
((HttpServletResponse) asyncCtx.getResponse()).setHeader("Content-Length", String.valueOf(text.length));
out.write(text);
written = true;
}
}
}
}
output:
onWritePossible> asyncCtx=org.eclipse.jetty.server.AsyncContextState@64e0bfc9, ready=true, written=false
onWritePossible> asyncCtx=org.eclipse.jetty.server.AsyncContextState@64e0bfc9, ready=false, written=true
org.eclipse.jetty.io.EofException: Closed
at org.eclipse.jetty.server.HttpOutput$AsyncICB.completed(HttpOutput.java:725)
at org.eclipse.jetty.util.IteratingCallback.processIterations(IteratingCallback.java:200)
at org.eclipse.jetty.util.IteratingCallback.iterate(IteratingCallback.java:126)
at org.eclipse.jetty.server.HttpOutput.write(HttpOutput.java:270)
at java.io.OutputStream.write(OutputStream.java:75)
at TextWriteListener.onWritePossible(TextWriteListener.java:43)
at org.eclipse.jetty.server.HttpOutput.run(HttpOutput.java:690)
at org.eclipse.jetty.server.handler.ContextHandler.handle(ContextHandler.java:1159)
at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:335)
at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:232)
at org.eclipse.jetty.io.AbstractConnection$1.run(AbstractConnection.java:505)
at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:607)
at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:536)
at java.lang.Thread.run(Thread.java:722)
How to set Content-Length for response correctly?
Thanks