Skip to content

Commit

Permalink
Do not fail when compressing empty HttpContent (#13655)
Browse files Browse the repository at this point in the history
Motivation:

HttpContentCompressor fails with an exception when trying to write an
empty HttpContent:

```
io.netty.handler.codec.EncoderException: MessageToMessageCodec$1 must produce at least one message.
	at io.netty.handler.codec.MessageToMessageEncoder.write(MessageToMessageEncoder.java:99)
	at io.netty.handler.codec.MessageToMessageCodec.write(MessageToMessageCodec.java:116)
	at io.netty.channel.AbstractChannelHandlerContext.invokeWrite0(AbstractChannelHandlerContext.java:879)
	at io.netty.channel.AbstractChannelHandlerContext.invokeWrite(AbstractChannelHandlerContext.java:863)
	at io.netty.channel.AbstractChannelHandlerContext.write(AbstractChannelHandlerContext.java:968)
	at io.netty.channel.AbstractChannelHandlerContext.write(AbstractChannelHandlerContext.java:856)
	at io.netty.channel.ChannelDuplexHandler.write(ChannelDuplexHandler.java:115)
```

Modification:

If the compression has no output, write an empty dummy HttpContent. This
is not an ideal solution, but this should not happen often anyway.

Result:

HttpContentCompressor does not fail anymore.

---------

Co-authored-by: Norman Maurer <norman_maurer@apple.com>
  • Loading branch information
yawkat and normanmaurer committed Oct 10, 2023
1 parent caca5e5 commit 4911448
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufHolder;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.embedded.EmbeddedChannel;
import io.netty.handler.codec.DecoderResult;
Expand Down Expand Up @@ -208,6 +209,9 @@ protected void encode(ChannelHandlerContext ctx, HttpObject msg, List<Object> ou
ensureContent(msg);
if (encodeContent((HttpContent) msg, out)) {
state = State.AWAIT_HEADERS;
} else if (out.isEmpty()) {
// MessageToMessageCodec needs at least one output message
out.add(new DefaultHttpContent(Unpooled.EMPTY_BUFFER));
}
break;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -973,6 +973,21 @@ public void testMultipleAcceptEncodingHeaders() {
assertTrue(ch.finishAndReleaseAll());
}

@Test
public void testEmpty() {
EmbeddedChannel ch = new EmbeddedChannel(new HttpContentCompressor());
assertTrue(ch.writeInbound(newRequest()));

DefaultHttpResponse response = new DefaultHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK);
response.headers().add(HttpHeaderNames.CONTENT_LENGTH, 0);
assertTrue(ch.writeOutbound(response));
assertTrue(ch.writeOutbound(new DefaultHttpContent(Unpooled.EMPTY_BUFFER)));
assertTrue(ch.writeOutbound(DefaultLastHttpContent.EMPTY_LAST_CONTENT));

ch.checkException();
ch.finishAndReleaseAll();
}

private static FullHttpRequest newRequest() {
FullHttpRequest req = new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET, "/");
req.headers().set(HttpHeaderNames.ACCEPT_ENCODING, "gzip");
Expand Down

0 comments on commit 4911448

Please sign in to comment.