From ee0897a1d9d80119990964834d62f906f800afb8 Mon Sep 17 00:00:00 2001 From: Nitesh Kant Date: Sun, 19 Jun 2016 20:37:07 -0700 Subject: [PATCH] HttpContentDecompressor should change decompressed requests to chunked encoding. Fixes issue #5428 `HttpContentDecoder` was removing `Content-Length` header but not adding a `Transfer-Encoding` header which goes against the HTTP spec. Added `Transfer-Encoding` header with value `chunked` when `Content-Length` is removed. Modified existing unit test to also check for this condition. Compliance with HTTP spec. --- .../codec/http/HttpContentDecoder.java | 1 + .../codec/http/HttpContentDecoderTest.java | 80 +++++++++---------- 2 files changed, 40 insertions(+), 41 deletions(-) diff --git a/codec-http/src/main/java/io/netty/handler/codec/http/HttpContentDecoder.java b/codec-http/src/main/java/io/netty/handler/codec/http/HttpContentDecoder.java index 375bac5462..1f707d71a9 100644 --- a/codec-http/src/main/java/io/netty/handler/codec/http/HttpContentDecoder.java +++ b/codec-http/src/main/java/io/netty/handler/codec/http/HttpContentDecoder.java @@ -99,6 +99,7 @@ public abstract class HttpContentDecoder extends MessageToMessageDecoder req = channel.inboundMessages(); assertTrue(req.size() > 1); int contentLength = 0; - for (Object o : req) { - if (o instanceof HttpContent) { - assertTrue(((HttpContent) o).refCnt() > 0); - ByteBuf b = ((HttpContent) o).content(); - contentLength += b.readableBytes(); - } - } + contentLength = calculateContentLength(req, contentLength); - int readCount = 0; - byte[] receivedContent = new byte[contentLength]; - for (Object o : req) { - if (o instanceof HttpContent) { - ByteBuf b = ((HttpContent) o).content(); - int readableBytes = b.readableBytes(); - b.readBytes(receivedContent, readCount, readableBytes); - readCount += readableBytes; - } - } + byte[] receivedContent = readContent(req, contentLength); assertEquals(HELLO_WORLD, new String(receivedContent, CharsetUtil.US_ASCII)); @@ -396,24 +384,9 @@ public class HttpContentDecoderTest { Queue resp = channel.inboundMessages(); assertTrue(resp.size() > 1); int contentLength = 0; - for (Object o : resp) { - if (o instanceof HttpContent) { - assertTrue(((HttpContent) o).refCnt() > 0); - ByteBuf b = ((HttpContent) o).content(); - contentLength += b.readableBytes(); - } - } + contentLength = calculateContentLength(resp, contentLength); - int readCount = 0; - byte[] receivedContent = new byte[contentLength]; - for (Object o : resp) { - if (o instanceof HttpContent) { - ByteBuf b = ((HttpContent) o).content(); - int readableBytes = b.readableBytes(); - b.readBytes(receivedContent, readCount, readableBytes); - readCount += readableBytes; - } - } + byte[] receivedContent = readContent(resp, contentLength); assertEquals(HELLO_WORLD, new String(receivedContent, CharsetUtil.US_ASCII)); @@ -422,7 +395,7 @@ public class HttpContentDecoderTest { assertFalse(channel.finish()); } - private byte[] gzDecompress(byte[] input) { + private static byte[] gzDecompress(byte[] input) { ZlibDecoder decoder = ZlibCodecFactory.newZlibDecoder(ZlibWrapper.GZIP); EmbeddedChannel channel = new EmbeddedChannel(decoder); assertTrue(channel.writeInbound(Unpooled.wrappedBuffer(input))); @@ -448,7 +421,32 @@ public class HttpContentDecoderTest { return output; } - private byte[] gzCompress(byte[] input) { + private static byte[] readContent(Queue req, int contentLength) { + byte[] receivedContent = new byte[contentLength]; + int readCount = 0; + for (Object o : req) { + if (o instanceof HttpContent) { + ByteBuf b = ((HttpContent) o).content(); + int readableBytes = b.readableBytes(); + b.readBytes(receivedContent, readCount, readableBytes); + readCount += readableBytes; + } + } + return receivedContent; + } + + private static int calculateContentLength(Queue req, int contentLength) { + for (Object o : req) { + if (o instanceof HttpContent) { + assertTrue(((HttpContent) o).refCnt() > 0); + ByteBuf b = ((HttpContent) o).content(); + contentLength += b.readableBytes(); + } + } + return contentLength; + } + + private static byte[] gzCompress(byte[] input) { ZlibEncoder encoder = ZlibCodecFactory.newZlibEncoder(ZlibWrapper.GZIP); EmbeddedChannel channel = new EmbeddedChannel(encoder); assertTrue(channel.writeOutbound(Unpooled.wrappedBuffer(input))); @@ -474,7 +472,7 @@ public class HttpContentDecoderTest { return output; } - private void assertHasInboundMessages(EmbeddedChannel channel, boolean hasMessages) { + private static void assertHasInboundMessages(EmbeddedChannel channel, boolean hasMessages) { Object o; if (hasMessages) { while (true) { @@ -491,7 +489,7 @@ public class HttpContentDecoderTest { } } - private void assertHasOutboundMessages(EmbeddedChannel channel, boolean hasMessages) { + private static void assertHasOutboundMessages(EmbeddedChannel channel, boolean hasMessages) { Object o; if (hasMessages) { while (true) {