From ffdb2e2f397c484ed5b27fb358f5c31df8db8aef Mon Sep 17 00:00:00 2001 From: Brett Kail Date: Fri, 23 Mar 2018 06:54:20 -0500 Subject: [PATCH] Fix Netty for unsized large responses HttpChunkedInput needs to be flushed so that it can read input immediately. Otherwise, all writes are buffered until the response is fully written, which overflows the buffer if enough data is sent. This only partially fixes the problem since clients that are reading slower than one chunk per 10sec can still overflow the buffer, but it is often sufficient in practice. To fully fix, JerseyChunkedInput needs to be reworked to block indefinitely when there's no space but to allow the ChunkedInput.close to awaken the writer and throw an IOException. (The existing close implements both the OutputStream and ChunkedInput, but it appears to be implemented as the latter only, so the removeLast/add appears to race with concurrent writes.) --- .../jersey/netty/httpserver/NettyResponseWriter.java | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/containers/netty-http/src/main/java/org/glassfish/jersey/netty/httpserver/NettyResponseWriter.java b/containers/netty-http/src/main/java/org/glassfish/jersey/netty/httpserver/NettyResponseWriter.java index 19de6c171f..9258bea686 100644 --- a/containers/netty-http/src/main/java/org/glassfish/jersey/netty/httpserver/NettyResponseWriter.java +++ b/containers/netty-http/src/main/java/org/glassfish/jersey/netty/httpserver/NettyResponseWriter.java @@ -142,12 +142,7 @@ public synchronized OutputStream writeResponseStatusAndHeaders(long contentLengt if (req.method() != HttpMethod.HEAD && (contentLength > 0 || contentLength == -1)) { JerseyChunkedInput jerseyChunkedInput = new JerseyChunkedInput(ctx.channel()); - - if (HttpUtil.isTransferEncodingChunked(response)) { - ctx.write(new HttpChunkedInput(jerseyChunkedInput)).addListener(FLUSH_FUTURE); - } else { - ctx.write(new HttpChunkedInput(jerseyChunkedInput)).addListener(FLUSH_FUTURE); - } + ctx.writeAndFlush(new HttpChunkedInput(jerseyChunkedInput)); return jerseyChunkedInput; } else {