Fix issue if encoding is enabled but not used (#11358)

Motivation:

Fixes an IllegalReferenceCountException

Modification:

Retained the buffers so the encoder works correctly.

Result:

Fixes #11357
This commit is contained in:
Stuart Douglas 2021-06-07 16:52:44 +10:00 committed by Norman Maurer
parent 1e6169fb65
commit f1db0b9014
2 changed files with 63 additions and 2 deletions

View File

@ -143,7 +143,7 @@ public abstract class HttpContentEncoder extends MessageToMessageCodec<HttpReque
if (isFull) {
out.add(ReferenceCountUtil.retain(res));
} else {
out.add(res);
out.add(ReferenceCountUtil.retain(res));
// Pass through all following contents.
state = State.PASS_THROUGH;
}
@ -166,7 +166,7 @@ public abstract class HttpContentEncoder extends MessageToMessageCodec<HttpReque
if (isFull) {
out.add(ReferenceCountUtil.retain(res));
} else {
out.add(res);
out.add(ReferenceCountUtil.retain(res));
// Pass through all following contents.
state = State.PASS_THROUGH;
}

View File

@ -26,6 +26,8 @@ import io.netty.util.CharsetUtil;
import io.netty.util.ReferenceCountUtil;
import org.junit.jupiter.api.Test;
import java.nio.charset.StandardCharsets;
import static io.netty.handler.codec.http.HttpHeadersTestUtils.of;
import static org.hamcrest.CoreMatchers.instanceOf;
import static org.hamcrest.CoreMatchers.is;
@ -197,6 +199,65 @@ public class HttpContentCompressorTest {
assertThat(ch.readOutbound(), is(nullValue()));
}
@Test
public void testChunkedContentWithAssembledResponseIdentityEncoding() throws Exception {
EmbeddedChannel ch = new EmbeddedChannel(new HttpContentCompressor());
ch.writeInbound(new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET, "/"));
HttpResponse res = new AssembledHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK,
Unpooled.copiedBuffer("Hell", CharsetUtil.US_ASCII));
res.headers().set(HttpHeaderNames.TRANSFER_ENCODING, HttpHeaderValues.CHUNKED);
ch.writeOutbound(res);
ch.writeOutbound(new DefaultHttpContent(Unpooled.copiedBuffer("o, w", CharsetUtil.US_ASCII)));
ch.writeOutbound(new DefaultLastHttpContent(Unpooled.copiedBuffer("orld", CharsetUtil.US_ASCII)));
HttpContent chunk;
chunk = ch.readOutbound();
assertThat(chunk.content().toString(StandardCharsets.UTF_8), is("Hell"));
chunk.release();
chunk = ch.readOutbound();
assertThat(chunk.content().toString(StandardCharsets.UTF_8), is("o, w"));
chunk.release();
chunk = ch.readOutbound();
assertThat(chunk.content().toString(StandardCharsets.UTF_8), is("orld"));
assertThat(chunk, is(instanceOf(LastHttpContent.class)));
chunk.release();
assertThat(ch.readOutbound(), is(nullValue()));
}
@Test
public void testContentWithAssembledResponseIdentityEncodingHttp10() throws Exception {
EmbeddedChannel ch = new EmbeddedChannel(new HttpContentCompressor());
ch.writeInbound(new DefaultFullHttpRequest(HttpVersion.HTTP_1_0, HttpMethod.GET, "/"));
HttpResponse res = new AssembledHttpResponse(HttpVersion.HTTP_1_0, HttpResponseStatus.OK,
Unpooled.copiedBuffer("Hell", CharsetUtil.US_ASCII));
ch.writeOutbound(res);
ch.writeOutbound(new DefaultHttpContent(Unpooled.copiedBuffer("o, w", CharsetUtil.US_ASCII)));
ch.writeOutbound(new DefaultLastHttpContent(Unpooled.copiedBuffer("orld", CharsetUtil.US_ASCII)));
HttpContent chunk;
chunk = ch.readOutbound();
assertThat(chunk.content().toString(StandardCharsets.UTF_8), is("Hell"));
chunk.release();
chunk = ch.readOutbound();
assertThat(chunk.content().toString(StandardCharsets.UTF_8), is("o, w"));
chunk.release();
chunk = ch.readOutbound();
assertThat(chunk.content().toString(StandardCharsets.UTF_8), is("orld"));
assertThat(chunk, is(instanceOf(LastHttpContent.class)));
chunk.release();
assertThat(ch.readOutbound(), is(nullValue()));
}
@Test
public void testChunkedContentWithTrailingHeader() throws Exception {
EmbeddedChannel ch = new EmbeddedChannel(new HttpContentCompressor());