[#4348] Correctly handle empty frames when compression is enabled.

Motivation:

We need to correctly handle empty frames when compression is enabled.

Modifications:

Not throw an exception when frame is empty.

Result:

Correctly handle empty frames.
This commit is contained in:
Norman Maurer 2015-10-12 09:54:01 +02:00
parent 5c48c59954
commit d20a9942d9
2 changed files with 29 additions and 1 deletions

View File

@ -68,6 +68,7 @@ abstract class DeflateDecoder extends WebSocketExtensionDecoder {
decoder = new EmbeddedChannel(ZlibCodecFactory.newZlibDecoder(ZlibWrapper.NONE));
}
boolean readable = msg.content().isReadable();
decoder.writeInbound(msg.content().retain());
if (appendFrameTail(msg)) {
decoder.writeInbound(Unpooled.wrappedBuffer(FRAME_TAIL));
@ -87,7 +88,9 @@ abstract class DeflateDecoder extends WebSocketExtensionDecoder {
compositeUncompressedContent.writerIndex(compositeUncompressedContent.writerIndex() +
partUncompressedContent.readableBytes());
}
if (compositeUncompressedContent.numComponents() <= 0) {
// Correctly handle empty frames
// See https://github.com/netty/netty/issues/4348
if (readable && compositeUncompressedContent.numComponents() <= 0) {
compositeUncompressedContent.release();
throw new CodecException("cannot read uncompressed buffer");
}

View File

@ -95,4 +95,29 @@ public class PerFrameDeflateDecoderTest {
newFrame.release();
}
// See https://github.com/netty/netty/issues/4348
@Test
public void testCompressedEmptyFrame() {
EmbeddedChannel encoderChannel = new EmbeddedChannel(
ZlibCodecFactory.newZlibEncoder(ZlibWrapper.NONE, 9, 15, 8));
EmbeddedChannel decoderChannel = new EmbeddedChannel(new PerFrameDeflateDecoder(false));
encoderChannel.writeOutbound(Unpooled.EMPTY_BUFFER);
ByteBuf compressedPayload = encoderChannel.readOutbound();
BinaryWebSocketFrame compressedFrame =
new BinaryWebSocketFrame(true, WebSocketExtension.RSV1 | WebSocketExtension.RSV3, compressedPayload);
// execute
decoderChannel.writeInbound(compressedFrame);
BinaryWebSocketFrame uncompressedFrame = decoderChannel.readInbound();
// test
assertNotNull(uncompressedFrame);
assertNotNull(uncompressedFrame.content());
assertTrue(uncompressedFrame instanceof BinaryWebSocketFrame);
assertEquals(WebSocketExtension.RSV3, uncompressedFrame.rsv());
assertEquals(0, uncompressedFrame.content().readableBytes());
uncompressedFrame.release();
}
}