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.
This commit is contained in:
Trustin Lee 2014-11-20 15:25:05 +09:00
parent 3451bce17f
commit 4772989ddd
2 changed files with 21 additions and 10 deletions

View File

@ -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()) {

View File

@ -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);
}