diff --git a/codec-http/src/main/java/io/netty/handler/codec/http/multipart/HttpPostRequestEncoder.java b/codec-http/src/main/java/io/netty/handler/codec/http/multipart/HttpPostRequestEncoder.java index 3252865669..57e1dfb1ec 100644 --- a/codec-http/src/main/java/io/netty/handler/codec/http/multipart/HttpPostRequestEncoder.java +++ b/codec-http/src/main/java/io/netty/handler/codec/http/multipart/HttpPostRequestEncoder.java @@ -828,6 +828,7 @@ public class HttpPostRequestEncoder implements ChunkedInput { int length = currentBuffer.readableBytes(); if (length > HttpPostBodyUtil.chunkSize) { ByteBuf slice = currentBuffer.slice(currentBuffer.readerIndex(), HttpPostBodyUtil.chunkSize); + currentBuffer.retain(); currentBuffer.skipBytes(HttpPostBodyUtil.chunkSize); return slice; } else { diff --git a/codec-http/src/test/java/io/netty/handler/codec/http/multipart/HttpPostRequestEncoderTest.java b/codec-http/src/test/java/io/netty/handler/codec/http/multipart/HttpPostRequestEncoderTest.java index 242d3d5a59..9037979ed0 100644 --- a/codec-http/src/test/java/io/netty/handler/codec/http/multipart/HttpPostRequestEncoderTest.java +++ b/codec-http/src/test/java/io/netty/handler/codec/http/multipart/HttpPostRequestEncoderTest.java @@ -16,8 +16,10 @@ package io.netty.handler.codec.http.multipart; import io.netty.buffer.ByteBuf; +import io.netty.buffer.SlicedByteBuf; import io.netty.buffer.Unpooled; import io.netty.handler.codec.http.DefaultFullHttpRequest; +import io.netty.handler.codec.http.HttpContent; import io.netty.handler.codec.http.HttpMethod; import io.netty.handler.codec.http.HttpVersion; import io.netty.handler.codec.http.multipart.HttpPostRequestEncoder.EncoderMode; @@ -26,6 +28,7 @@ import io.netty.util.internal.StringUtil; import org.junit.Test; import java.io.File; +import java.util.Arrays; import java.util.List; import static io.netty.handler.codec.http.HttpHeaderNames.*; @@ -187,6 +190,38 @@ public class HttpPostRequestEncoderTest { assertEquals(expected, content); } + @Test + public void testHttpPostRequestEncoderSlicedBuffer() throws Exception { + DefaultFullHttpRequest request = new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, + HttpMethod.POST, "http://localhost"); + + HttpPostRequestEncoder encoder = new HttpPostRequestEncoder(request, true); + // add Form attribute + encoder.addBodyAttribute("getform", "POST"); + encoder.addBodyAttribute("info", "first value"); + encoder.addBodyAttribute("secondinfo", "secondvalue a&"); + encoder.addBodyAttribute("thirdinfo", "short text"); + int length = 100000; + char[] array = new char[length]; + Arrays.fill(array, 'a'); + String longText = new String(array); + encoder.addBodyAttribute("fourthinfo", longText.substring(0, 7470)); + File file1 = new File(getClass().getResource("/file-01.txt").toURI()); + encoder.addBodyFileUpload("myfile", file1, "application/x-zip-compressed", false); + encoder.finalizeRequest(); + while (! encoder.isEndOfInput()) { + HttpContent httpContent = encoder.readChunk(null); + if (httpContent.content() instanceof SlicedByteBuf) { + assertEquals(2, httpContent.content().refCnt()); + } else { + assertEquals(1, httpContent.content().refCnt()); + } + httpContent.release(); + } + encoder.cleanFiles(); + encoder.close(); + } + private static String getRequestBody(HttpPostRequestEncoder encoder) throws Exception { encoder.finalizeRequest();