Skip to content

Commit 61d75db

Browse files
vietjnormanmaurer
andauthored
Fix BrotliEncoder bug that does not mark ByteBuf it encodes as read (#13497)
Motivation: The contract between HttpContentCompressor and compression encoders assumes that encoders will mark the encoded ByteBuf as read after they have been encoded, otherwise the HttpContentCompressor will send encoded chunk twice (one time decoded and one time encoded). The BrotliEncoder peeks the ByteBuf nio buffer and pass it to the BrotliChannelEncoder without marking the ByteBuf and does not respect the implicit contract with HttpContentCompressor. Modifications: The BrotliEncoder now will set skip bytes of encoded ByteBuf, in addition the test generic AbstractEncoderTest has been modified to ensure that the readable bytes of a ByteBuf is equals to 0 after it has been encoded. Result: This fixes the bug. --------- Co-authored-by: Norman Maurer <norman_maurer@apple.com>
1 parent 4e1a0c3 commit 61d75db

2 files changed

Lines changed: 7 additions & 1 deletion

File tree

codec/src/main/java/io/netty/handler/codec/compression/BrotliEncoder.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,10 @@ private void encode(ByteBuf msg, boolean preferDirect) throws Exception {
205205
//
206206
// A race condition will not arise because one flush call to encoder will result
207207
// in only 1 call at `write(ByteBuffer)`.
208-
brotliEncoderChannel.write(msg.nioBuffer());
208+
ByteBuffer nioBuffer = msg.nioBuffer();
209+
int position = nioBuffer.position();
210+
brotliEncoderChannel.write(nioBuffer);
211+
msg.skipBytes(nioBuffer.position() - position);
209212
brotliEncoderChannel.flush();
210213
} catch (Exception e) {
211214
ReferenceCountUtil.release(msg);

codec/src/test/java/io/netty/handler/codec/compression/AbstractEncoderTest.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ protected void testCompression(final ByteBuf data) throws Exception {
8787
final int dataLength = data.readableBytes();
8888
assertTrue(channel.writeOutbound(data.retain()));
8989
assertTrue(channel.finish());
90+
assertEquals(0, data.readableBytes());
9091

9192
ByteBuf decompressed = readDecompressed(dataLength);
9293
assertEquals(data.resetReaderIndex(), decompressed);
@@ -101,12 +102,14 @@ protected void testCompressionOfBatchedFlow(final ByteBuf data) throws Exception
101102
while (written + length < dataLength) {
102103
ByteBuf in = data.retainedSlice(written, length);
103104
assertTrue(channel.writeOutbound(in));
105+
assertEquals(0, in.readableBytes());
104106
written += length;
105107
length = rand.nextInt(100);
106108
}
107109
ByteBuf in = data.retainedSlice(written, dataLength - written);
108110
assertTrue(channel.writeOutbound(in));
109111
assertTrue(channel.finish());
112+
assertEquals(0, in.readableBytes());
110113

111114
ByteBuf decompressed = readDecompressed(dataLength);
112115
assertEquals(data, decompressed);

0 commit comments

Comments
 (0)