From 4772989dddec4830e55d21c353d7258802a0b3e1 Mon Sep 17 00:00:00 2001 From: Trustin Lee Date: Thu, 20 Nov 2014 15:25:05 +0900 Subject: [PATCH] HTTP Content Encoder allow EmptyLastHttpContent Related: #3107, origianlly written by @Scottmitch Motiviation: The HttpContentEncoder does not account for an EmptyLastHttpContent being provides as input. This is useful in situations where the client is unable to determine if the current content chunk is the last content chunk (i.e. a proxy forwarding content when trnasfer encoding is chunked) Modifications: - HttpContentEncoder should not attempt to compress empty HttpContent objects. Result: HttpContentEncoder supports a EmptyLastHttpContent to terminate the response. --- .../codec/compression/JdkZlibEncoder.java | 14 ++++++++++---- .../handler/codec/compression/ZlibEncoder.java | 17 +++++++++++------ 2 files changed, 21 insertions(+), 10 deletions(-) diff --git a/src/main/java/org/jboss/netty/handler/codec/compression/JdkZlibEncoder.java b/src/main/java/org/jboss/netty/handler/codec/compression/JdkZlibEncoder.java index 27e16df64b..95b53dd828 100644 --- a/src/main/java/org/jboss/netty/handler/codec/compression/JdkZlibEncoder.java +++ b/src/main/java/org/jboss/netty/handler/codec/compression/JdkZlibEncoder.java @@ -183,12 +183,18 @@ public class JdkZlibEncoder extends OneToOneStrictEncoder implements LifeCycleAw return msg; } - ChannelBuffer uncompressed = (ChannelBuffer) msg; - byte[] in = new byte[uncompressed.readableBytes()]; + final ChannelBuffer uncompressed = (ChannelBuffer) msg; + final int uncompressedLen = uncompressed.readableBytes(); + if (uncompressedLen == 0) { + return uncompressed; + } + + final byte[] in = new byte[uncompressedLen]; uncompressed.readBytes(in); - int sizeEstimate = estimateCompressedSize(in.length); - ChannelBuffer compressed = ChannelBuffers.dynamicBuffer(sizeEstimate, channel.getConfig().getBufferFactory()); + final int sizeEstimate = estimateCompressedSize(uncompressedLen); + final ChannelBuffer compressed = + ChannelBuffers.dynamicBuffer(sizeEstimate, channel.getConfig().getBufferFactory()); synchronized (deflater) { if (isGzip()) { diff --git a/src/main/java/org/jboss/netty/handler/codec/compression/ZlibEncoder.java b/src/main/java/org/jboss/netty/handler/codec/compression/ZlibEncoder.java index cec345641b..8f1c66ffde 100644 --- a/src/main/java/org/jboss/netty/handler/codec/compression/ZlibEncoder.java +++ b/src/main/java/org/jboss/netty/handler/codec/compression/ZlibEncoder.java @@ -266,25 +266,30 @@ public class ZlibEncoder extends OneToOneStrictEncoder implements LifeCycleAware return msg; } - ChannelBuffer result; + final ChannelBuffer result; synchronized (z) { try { // Configure input. - ChannelBuffer uncompressed = (ChannelBuffer) msg; - byte[] in = new byte[uncompressed.readableBytes()]; + final ChannelBuffer uncompressed = (ChannelBuffer) msg; + final int uncompressedLen = uncompressed.readableBytes(); + if (uncompressedLen == 0) { + return uncompressed; + } + + final byte[] in = new byte[uncompressedLen]; uncompressed.readBytes(in); z.next_in = in; z.next_in_index = 0; - z.avail_in = in.length; + z.avail_in = uncompressedLen; // Configure output. - byte[] out = new byte[(int) Math.ceil(in.length * 1.001) + 12 + wrapperOverhead]; + final byte[] out = new byte[(int) Math.ceil(uncompressedLen * 1.001) + 12 + wrapperOverhead]; z.next_out = out; z.next_out_index = 0; z.avail_out = out.length; // Note that Z_PARTIAL_FLUSH has been deprecated. - int resultCode = z.deflate(JZlib.Z_SYNC_FLUSH); + final int resultCode = z.deflate(JZlib.Z_SYNC_FLUSH); if (resultCode != JZlib.Z_OK) { ZlibUtil.fail(z, "compression failure", resultCode); }