From 12852a20fb9c1bc5970e3d3e98ab507d098d459d Mon Sep 17 00:00:00 2001 From: Norman Maurer Date: Tue, 24 Jan 2012 20:37:31 +0100 Subject: [PATCH 01/10] Remove not-needed call of ByteBuffer.clear(). See #161 --- .../jboss/netty/channel/socket/nio/SocketReceiveBufferPool.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/org/jboss/netty/channel/socket/nio/SocketReceiveBufferPool.java b/src/main/java/org/jboss/netty/channel/socket/nio/SocketReceiveBufferPool.java index bc20ab47c9..f8c646998a 100644 --- a/src/main/java/org/jboss/netty/channel/socket/nio/SocketReceiveBufferPool.java +++ b/src/main/java/org/jboss/netty/channel/socket/nio/SocketReceiveBufferPool.java @@ -54,7 +54,6 @@ final class SocketReceiveBufferPool { } ByteBuffer buf = ByteBuffer.allocateDirect(normalizeCapacity(size)); - buf.clear(); return buf; } From 3b0f45c93cdb56bb0edc9c0ff52338ec879fc97c Mon Sep 17 00:00:00 2001 From: Norman Maurer Date: Tue, 31 Jan 2012 11:07:33 +0100 Subject: [PATCH 02/10] Fix possible NPE which will be thrown if the Buffer was set to null and after that Exception was thrown. See #166 --- .../java/org/jboss/netty/channel/socket/nio/NioWorker.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/jboss/netty/channel/socket/nio/NioWorker.java b/src/main/java/org/jboss/netty/channel/socket/nio/NioWorker.java index 5554bee218..84b47340d0 100644 --- a/src/main/java/org/jboss/netty/channel/socket/nio/NioWorker.java +++ b/src/main/java/org/jboss/netty/channel/socket/nio/NioWorker.java @@ -495,7 +495,9 @@ class NioWorker implements Runnable { } catch (AsynchronousCloseException e) { // Doesn't need a user attention - ignore. } catch (Throwable t) { - buf.release(); + if (buf != null) { + buf.release(); + } channel.currentWriteEvent = null; channel.currentWriteBuffer = null; buf = null; From edc34c319d274bdf29ce792407552e06c533ffae Mon Sep 17 00:00:00 2001 From: Norman Maurer Date: Tue, 31 Jan 2012 13:03:53 +0100 Subject: [PATCH 03/10] Mark StaticChannelPipeline @Deprecated. See #168 --- .../java/org/jboss/netty/channel/StaticChannelPipeline.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/main/java/org/jboss/netty/channel/StaticChannelPipeline.java b/src/main/java/org/jboss/netty/channel/StaticChannelPipeline.java index 1f201ab8b8..568aa0215a 100644 --- a/src/main/java/org/jboss/netty/channel/StaticChannelPipeline.java +++ b/src/main/java/org/jboss/netty/channel/StaticChannelPipeline.java @@ -30,7 +30,10 @@ import org.jboss.netty.util.internal.ConversionUtil; * disabled dynamic insertion and removal of {@link ChannelHandler}s. * An attempt to insert, remove, or replace a handler in this pipeline will * trigger an {@link UnsupportedOperationException}. + * + * @deprecated use {@link DefaultChannelPipeline} */ +@Deprecated public class StaticChannelPipeline implements ChannelPipeline { // FIXME Code duplication with DefaultChannelPipeline From 4d7c9b397dfd5f08d56ef461a52e885678f1ad81 Mon Sep 17 00:00:00 2001 From: Norman Maurer Date: Tue, 31 Jan 2012 20:57:23 +0100 Subject: [PATCH 04/10] Allow to @override the cumulative ChannelBuffer creation. See #169 --- .../netty/handler/codec/frame/FrameDecoder.java | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/jboss/netty/handler/codec/frame/FrameDecoder.java b/src/main/java/org/jboss/netty/handler/codec/frame/FrameDecoder.java index 530d147cd9..f4459d01dc 100644 --- a/src/main/java/org/jboss/netty/handler/codec/frame/FrameDecoder.java +++ b/src/main/java/org/jboss/netty/handler/codec/frame/FrameDecoder.java @@ -364,10 +364,20 @@ public abstract class FrameDecoder extends SimpleChannelUpstreamHandler { private ChannelBuffer cumulation(ChannelHandlerContext ctx) { ChannelBuffer c = cumulation; if (c == null) { - c = ChannelBuffers.dynamicBuffer( - ctx.getChannel().getConfig().getBufferFactory()); + c = createCumulationDynamicBuffer(ctx); cumulation = c; } return c; } + + /** + * Create a new {@link ChannelBuffer} which is used for the cumulation. Be aware that this MUST be a dynamic buffer. Sub-classes may override this to provide a + * dynamic {@link ChannelBuffer} which has some prelocated size that better fit their need. + * + * @param ctx {@link ChannelHandlerContext} for this handler + * @return buffer the {@link ChannelBuffer} which is used for cumulation + */ + protected ChannelBuffer createCumulationDynamicBuffer(ChannelHandlerContext ctx) { + return ChannelBuffers.dynamicBuffer(ctx.getChannel().getConfig().getBufferFactory()); + } } From 4116c44c7749f0889b5ceef6067bf13ff3c1ad21 Mon Sep 17 00:00:00 2001 From: Norman Maurer Date: Tue, 31 Jan 2012 21:02:00 +0100 Subject: [PATCH 05/10] FixedLengthFrameDecoder should used a optimizated initialSize when creating the cumulative ChannelBuffer. See #170 --- .../codec/frame/FixedLengthFrameDecoder.java | 23 +++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/jboss/netty/handler/codec/frame/FixedLengthFrameDecoder.java b/src/main/java/org/jboss/netty/handler/codec/frame/FixedLengthFrameDecoder.java index 3e7a085822..d4dee7d335 100644 --- a/src/main/java/org/jboss/netty/handler/codec/frame/FixedLengthFrameDecoder.java +++ b/src/main/java/org/jboss/netty/handler/codec/frame/FixedLengthFrameDecoder.java @@ -16,6 +16,7 @@ package org.jboss.netty.handler.codec.frame; import org.jboss.netty.buffer.ChannelBuffer; +import org.jboss.netty.buffer.ChannelBuffers; import org.jboss.netty.channel.Channel; import org.jboss.netty.channel.ChannelHandlerContext; @@ -38,18 +39,28 @@ import org.jboss.netty.channel.ChannelHandlerContext; public class FixedLengthFrameDecoder extends FrameDecoder { private final int frameLength; - + private final boolean allocateFullBuffer; + + /** + * Calls {@link #FixedLengthFrameDecoder(int, boolean)} with false + */ + public FixedLengthFrameDecoder(int frameLength) { + this(frameLength, false); + } + /** * Creates a new instance. * * @param frameLength the length of the frame + * @param allocateFullBuffer true if the cumulative {@link ChannelBuffer} should use the {@link #frameLength} as its initial size */ - public FixedLengthFrameDecoder(int frameLength) { + public FixedLengthFrameDecoder(int frameLength, boolean allocateFullBuffer) { if (frameLength <= 0) { throw new IllegalArgumentException( "frameLength must be a positive integer: " + frameLength); } this.frameLength = frameLength; + this.allocateFullBuffer = allocateFullBuffer; } @Override @@ -61,4 +72,12 @@ public class FixedLengthFrameDecoder extends FrameDecoder { return buffer.readBytes(frameLength); } } + + @Override + protected ChannelBuffer createCumulationDynamicBuffer(ChannelHandlerContext ctx) { + if (allocateFullBuffer) { + return ChannelBuffers.dynamicBuffer(frameLength, ctx.getChannel().getConfig().getBufferFactory()); + } + return super.createCumulationDynamicBuffer(ctx); + } } From aecce011e8a27ba4737737b273c53b8202442ef7 Mon Sep 17 00:00:00 2001 From: Jeff Pinner Date: Tue, 31 Jan 2012 14:34:21 -0800 Subject: [PATCH 06/10] Fix #164: HttpContentCompressor accepts encodings whose qvalue is 0 --- .../codec/http/HttpContentCompressor.java | 40 +++++++++++++-- .../codec/http/HttpContentCompressorTest.java | 49 +++++++++++++++++++ 2 files changed, 84 insertions(+), 5 deletions(-) create mode 100644 src/test/java/org/jboss/netty/handler/codec/http/HttpContentCompressorTest.java diff --git a/src/main/java/org/jboss/netty/handler/codec/http/HttpContentCompressor.java b/src/main/java/org/jboss/netty/handler/codec/http/HttpContentCompressor.java index 803c2c53b5..8f455234f2 100644 --- a/src/main/java/org/jboss/netty/handler/codec/http/HttpContentCompressor.java +++ b/src/main/java/org/jboss/netty/handler/codec/http/HttpContentCompressor.java @@ -83,12 +83,42 @@ public class HttpContentCompressor extends HttpContentEncoder { } private ZlibWrapper determineWrapper(String acceptEncoding) { - // FIXME: Use the Q value. - if (acceptEncoding.indexOf("gzip") >= 0) { - return ZlibWrapper.GZIP; + float starQ = -1.0f; + float gzipQ = -1.0f; + float deflateQ = -1.0f; + for (String encoding : acceptEncoding.split(",")) { + float q = 1.0f; + int equalsPos = encoding.indexOf('='); + if (equalsPos != -1) { + try { + q = Float.valueOf(encoding.substring(equalsPos + 1)); + } catch (NumberFormatException e) { + // Ignore encoding + q = 0.0f; + } + } + if (encoding.indexOf("*") >= 0) { + starQ = q; + } else if (encoding.indexOf("gzip") >= 0 && q > gzipQ) { + gzipQ = q; + } else if (encoding.indexOf("deflate") >= 0 && q > deflateQ) { + deflateQ = q; + } } - if (acceptEncoding.indexOf("deflate") >= 0) { - return ZlibWrapper.ZLIB; + if (gzipQ > 0.0f || deflateQ > 0.0f) { + if (gzipQ >= deflateQ) { + return ZlibWrapper.GZIP; + } else { + return ZlibWrapper.ZLIB; + } + } + if (starQ > 0.0f) { + if (gzipQ == -1.0f) { + return ZlibWrapper.GZIP; + } + if (deflateQ == -1.0f) { + return ZlibWrapper.ZLIB; + } } return null; } diff --git a/src/test/java/org/jboss/netty/handler/codec/http/HttpContentCompressorTest.java b/src/test/java/org/jboss/netty/handler/codec/http/HttpContentCompressorTest.java new file mode 100644 index 0000000000..3fb962ccab --- /dev/null +++ b/src/test/java/org/jboss/netty/handler/codec/http/HttpContentCompressorTest.java @@ -0,0 +1,49 @@ +/* + * Copyright 2011 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package org.jboss.netty.handler.codec.http; + +import org.junit.Assert; +import org.junit.Test; + +public class HttpContentCompressorTest { + + private HttpContentCompressor httpContentCompressor = + new HttpContentCompressor(); + + @Test + public void testGetTargetContentEncoding() throws Exception { + HttpContentCompressor compressor = new HttpContentCompressor(); + + String[] tests = { + // Accept-Encoding -> Content-Encoding + "", null, + "*", "gzip", + "*;q=0.0", null, + "gzip", "gzip", + "compress, gzip;q=0.5", "gzip", + "gzip; q=0.5, identity", "gzip", + "gzip ; q=0.1", "gzip", + "gzip; q=0, deflate", "deflate", + " defalte ; q=0 , *;q=0.5", "gzip", + }; + for (int i = 0; i < tests.length; i += 2) { + String acceptEncoding = tests[i]; + String contentEncoding = tests[i + 1]; + String targetEncoding = compressor.getTargetContentEncoding(acceptEncoding); + Assert.assertEquals(contentEncoding, targetEncoding); + } + } +} From 24baa9a2ac2d04c602c4eda72fd8edb04fc922cd Mon Sep 17 00:00:00 2001 From: Jeff Pinner Date: Wed, 1 Feb 2012 16:00:10 -0800 Subject: [PATCH 07/10] Fix #163: HttpContentCompressor consumes too much memory --- .../codec/compression/ZlibEncoder.java | 105 +++++++++++++++--- .../codec/http/HttpContentCompressor.java | 47 +++++++- .../netty/util/internal/jzlib/Deflate.java | 4 +- .../netty/util/internal/jzlib/ZStream.java | 8 +- 4 files changed, 142 insertions(+), 22 deletions(-) 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 5925d6fb89..bd518755ef 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 @@ -46,7 +46,8 @@ public class ZlibEncoder extends OneToOneEncoder implements LifeCycleAwareChanne private volatile ChannelHandlerContext ctx; /** - * Creates a new zlib encoder with the default compression level ({@code 6}) + * Creates a new zlib encoder with the default compression level ({@code 6}), + * default window bits ({@code 15}), default memory level ({@code 8}), * and the default wrapper ({@link ZlibWrapper#ZLIB}). * * @throws CompressionException if failed to initialize zlib @@ -56,7 +57,8 @@ public class ZlibEncoder extends OneToOneEncoder implements LifeCycleAwareChanne } /** - * Creates a new zlib encoder with the specified {@code compressionLevel} + * Creates a new zlib encoder with the specified {@code compressionLevel}, + * default window bits ({@code 15}), default memory level ({@code 8}), * and the default wrapper ({@link ZlibWrapper#ZLIB}). * * @param compressionLevel @@ -71,7 +73,8 @@ public class ZlibEncoder extends OneToOneEncoder implements LifeCycleAwareChanne } /** - * Creates a new zlib encoder with the default compression level ({@code 6}) + * Creates a new zlib encoder with the default compression level ({@code 6}), + * default window bits ({@code 15}), default memory level ({@code 8}), * and the specified wrapper. * * @throws CompressionException if failed to initialize zlib @@ -81,8 +84,10 @@ public class ZlibEncoder extends OneToOneEncoder implements LifeCycleAwareChanne } /** - * Creates a new zlib encoder with the specified {@code compressionLevel} + * Creates a new zlib encoder with the specified {@code compressionLevel}, + * default window bits ({@code 15}), default memory level ({@code 8}), * and the specified wrapper. + * * @param compressionLevel * {@code 1} yields the fastest compression and {@code 9} yields the * best compression. {@code 0} means no compression. The default @@ -91,10 +96,43 @@ public class ZlibEncoder extends OneToOneEncoder implements LifeCycleAwareChanne * @throws CompressionException if failed to initialize zlib */ public ZlibEncoder(ZlibWrapper wrapper, int compressionLevel) { + this(wrapper, compressionLevel, 15, 8); + } + + /** + * Creates a new zlib encoder with the specified {@code compressionLevel}, + * the specified {@code windowBits}, the specified {@code memLevel}, and + * the specified wrapper. + * + * @param compressionLevel + * {@code 1} yields the fastest compression and {@code 9} yields the + * best compression. {@code 0} means no compression. The default + * compression level is {@code 6}. + * @param windowBits + * The base two logarithm of the size of the history buffer. The + * value should be in the range {@code 9} to {@code 15} inclusive. + * Larger values result in better compression at the expense of + * memory usage. The default value is {@code 15}. + * @param memLevel + * How much memory should be allocated for the internal compression + * state. {@code 1} uses minimum memory and {@code 9} uses maximum + * memory. Larger values result in better and faster compression + * at the expense of memory usage. The default value is {@code 8} + * + * @throws CompressionException if failed to initialize zlib + */ + public ZlibEncoder(ZlibWrapper wrapper, int compressionLevel, int windowBits, int memLevel) { if (compressionLevel < 0 || compressionLevel > 9) { throw new IllegalArgumentException( - "compressionLevel: " + compressionLevel + - " (expected: 0-9)"); + "compressionLevel: " + compressionLevel + " (expected: 0-9)"); + } + if (windowBits < 9 || windowBits > 15) { + throw new IllegalArgumentException( + "windowBits: " + windowBits + " (expected: 9-15)"); + } + if (memLevel < 1 || memLevel > 9) { + throw new IllegalArgumentException( + "memLevel: " + memLevel + " (expected: 1-9)"); } if (wrapper == null) { throw new NullPointerException("wrapper"); @@ -106,7 +144,8 @@ public class ZlibEncoder extends OneToOneEncoder implements LifeCycleAwareChanne } synchronized (z) { - int resultCode = z.deflateInit(compressionLevel, ZlibUtil.convertWrapperType(wrapper)); + int resultCode = z.deflateInit(compressionLevel, windowBits, memLevel, + ZlibUtil.convertWrapperType(wrapper)); if (resultCode != JZlib.Z_OK) { ZlibUtil.fail(z, "initialization failure", resultCode); } @@ -114,7 +153,8 @@ public class ZlibEncoder extends OneToOneEncoder implements LifeCycleAwareChanne } /** - * Creates a new zlib encoder with the default compression level ({@code 6}) + * Creates a new zlib encoder with the default compression level ({@code 6}), + * default window bits ({@code 15}), default memory level ({@code 8}), * and the specified preset dictionary. The wrapper is always * {@link ZlibWrapper#ZLIB} because it is the only format that supports * the preset dictionary. @@ -128,7 +168,8 @@ public class ZlibEncoder extends OneToOneEncoder implements LifeCycleAwareChanne } /** - * Creates a new zlib encoder with the specified {@code compressionLevel} + * Creates a new zlib encoder with the specified {@code compressionLevel}, + * default window bits ({@code 15}), default memory level ({@code 8}), * and the specified preset dictionary. The wrapper is always * {@link ZlibWrapper#ZLIB} because it is the only format that supports * the preset dictionary. @@ -142,17 +183,55 @@ public class ZlibEncoder extends OneToOneEncoder implements LifeCycleAwareChanne * @throws CompressionException if failed to initialize zlib */ public ZlibEncoder(int compressionLevel, byte[] dictionary) { - if (compressionLevel < 0 || compressionLevel > 9) { - throw new IllegalArgumentException("compressionLevel: " + compressionLevel + " (expected: 0-9)"); - } + this(compressionLevel, 15, 8, dictionary); + } + /** + * Creates a new zlib encoder with the specified {@code compressionLevel}, + * the specified {@code windowBits}, the specified {@code memLevel}, + * and the specified preset dictionary. The wrapper is always + * {@link ZlibWrapper#ZLIB} because it is the only format that supports + * the preset dictionary. + * + * @param compressionLevel + * {@code 1} yields the fastest compression and {@code 9} yields the + * best compression. {@code 0} means no compression. The default + * compression level is {@code 6}. + * @param windowBits + * The base two logarithm of the size of the history buffer. The + * value should be in the range {@code 9} to {@code 15} inclusive. + * Larger values result in better compression at the expense of + * memory usage. The default value is {@code 15}. + * @param memLevel + * How much memory should be allocated for the internal compression + * state. {@code 1} uses minimum memory and {@code 9} uses maximum + * memory. Larger values result in better and faster compression + * at the expense of memory usage. The default value is {@code 8} + * @param dictionary the preset dictionary + * + * @throws CompressionException if failed to initialize zlib + */ + public ZlibEncoder(int compressionLevel, int windowBits, int memLevel, byte[] dictionary) { + if (compressionLevel < 0 || compressionLevel > 9) { + throw new IllegalArgumentException( + "compressionLevel: " + compressionLevel + " (expected: 0-9)"); + } + if (windowBits < 9 || windowBits > 15) { + throw new IllegalArgumentException( + "windowBits: " + windowBits + " (expected: 9-15)"); + } + if (memLevel < 1 || memLevel > 9) { + throw new IllegalArgumentException( + "memLevel: " + memLevel + " (expected: 1-9)"); + } if (dictionary == null) { throw new NullPointerException("dictionary"); } synchronized (z) { int resultCode; - resultCode = z.deflateInit(compressionLevel, JZlib.W_ZLIB); // Default: ZLIB format + resultCode = z.deflateInit(compressionLevel, windowBits, memLevel, + JZlib.W_ZLIB); // Default: ZLIB format if (resultCode != JZlib.Z_OK) { ZlibUtil.fail(z, "initialization failure", resultCode); } else { diff --git a/src/main/java/org/jboss/netty/handler/codec/http/HttpContentCompressor.java b/src/main/java/org/jboss/netty/handler/codec/http/HttpContentCompressor.java index 803c2c53b5..3e85fed46f 100644 --- a/src/main/java/org/jboss/netty/handler/codec/http/HttpContentCompressor.java +++ b/src/main/java/org/jboss/netty/handler/codec/http/HttpContentCompressor.java @@ -30,16 +30,20 @@ import org.jboss.netty.handler.codec.embedder.EncoderEmbedder; public class HttpContentCompressor extends HttpContentEncoder { private final int compressionLevel; + private final int windowBits; + private final int memLevel; /** - * Creates a new handler with the default compression level (6). + * Creates a new handler with the default compression level (6), + * default window size (15) and default memory level (8). */ public HttpContentCompressor() { this(6); } /** - * Creates a new handler with the specified compression level. + * Creates a new handler with the specified compression level, default + * window size (15) and default memory level (8). * * @param compressionLevel * {@code 1} yields the fastest compression and {@code 9} yields the @@ -47,12 +51,44 @@ public class HttpContentCompressor extends HttpContentEncoder { * compression level is {@code 6}. */ public HttpContentCompressor(int compressionLevel) { + this(compressionLevel, 15, 8); + } + + /** + * Creates a new handler with the specified compression level, window size, + * and memory level.. + * + * @param compressionLevel + * {@code 1} yields the fastest compression and {@code 9} yields the + * best compression. {@code 0} means no compression. The default + * compression level is {@code 6}. + * @param windowBits + * The base two logarithm of the size of the history buffer. The + * value should be in the range {@code 9} to {@code 15} inclusive. + * Larger values result in better compression at the expense of + * memory usage. The default value is {@code 15}. + * @param memLevel + * How much memory should be allocated for the internal compression + * state. {@code 1} uses minimum memory and {@code 9} uses maximum + * memory. Larger values result in better and faster compression + * at the expense of memory usage. The default value is {@code 8} + */ + public HttpContentCompressor(int compressionLevel, int windowBits, int memLevel) { if (compressionLevel < 0 || compressionLevel > 9) { throw new IllegalArgumentException( - "compressionLevel: " + compressionLevel + - " (expected: 0-9)"); + "compressionLevel: " + compressionLevel + " (expected: 0-9)"); + } + if (windowBits < 9 || windowBits > 15) { + throw new IllegalArgumentException( + "windowBits: " + windowBits + " (expected: 9-15)"); + } + if (memLevel < 1 || memLevel > 9) { + throw new IllegalArgumentException( + "memLevel: " + memLevel + " (expected: 1-9)"); } this.compressionLevel = compressionLevel; + this.windowBits = windowBits; + this.memLevel = memLevel; } @Override @@ -62,7 +98,8 @@ public class HttpContentCompressor extends HttpContentEncoder { return null; } - return new EncoderEmbedder(new ZlibEncoder(wrapper, compressionLevel)); + return new EncoderEmbedder( + new ZlibEncoder(wrapper, compressionLevel, windowBits, memLevel)); } @Override diff --git a/src/main/java/org/jboss/netty/util/internal/jzlib/Deflate.java b/src/main/java/org/jboss/netty/util/internal/jzlib/Deflate.java index e98622109c..ba8fefcc28 100644 --- a/src/main/java/org/jboss/netty/util/internal/jzlib/Deflate.java +++ b/src/main/java/org/jboss/netty/util/internal/jzlib/Deflate.java @@ -1298,9 +1298,9 @@ final class Deflate { return lookahead; } - int deflateInit(ZStream strm, int level, int bits, WrapperType wrapperType) { + int deflateInit(ZStream strm, int level, int bits, int memLevel, WrapperType wrapperType) { return deflateInit2(strm, level, JZlib.Z_DEFLATED, bits, - JZlib.DEF_MEM_LEVEL, JZlib.Z_DEFAULT_STRATEGY, wrapperType); + memLevel, JZlib.Z_DEFAULT_STRATEGY, wrapperType); } private int deflateInit2(ZStream strm, int level, int method, int windowBits, diff --git a/src/main/java/org/jboss/netty/util/internal/jzlib/ZStream.java b/src/main/java/org/jboss/netty/util/internal/jzlib/ZStream.java index b28b595080..2fbd6c0fda 100644 --- a/src/main/java/org/jboss/netty/util/internal/jzlib/ZStream.java +++ b/src/main/java/org/jboss/netty/util/internal/jzlib/ZStream.java @@ -124,9 +124,13 @@ public final class ZStream { return deflateInit(level, bits, WrapperType.ZLIB); } - public int deflateInit(int level, int bits, @SuppressWarnings("rawtypes") Enum wrapperType) { + public int deflateInit(int level, int bits, Enum wrapperType) { + return deflateInit(level, bits, JZlib.DEF_MEM_LEVEL, wrapperType); + } + + public int deflateInit(int level, int bits, int memLevel, @SuppressWarnings("rawtypes") Enum wrapperType) { dstate = new Deflate(); - return dstate.deflateInit(this, level, bits, (WrapperType) wrapperType); + return dstate.deflateInit(this, level, bits, memLevel, (WrapperType) wrapperType); } public int deflate(int flush) { From 0ee43f770f8c95eb2192d6e731b3b2d179b32292 Mon Sep 17 00:00:00 2001 From: Trustin Lee Date: Thu, 2 Feb 2012 16:18:27 +0900 Subject: [PATCH 08/10] Remove a unused field --- .../netty/handler/codec/http/HttpContentCompressorTest.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/test/java/org/jboss/netty/handler/codec/http/HttpContentCompressorTest.java b/src/test/java/org/jboss/netty/handler/codec/http/HttpContentCompressorTest.java index 3fb962ccab..4dd00ec1c8 100644 --- a/src/test/java/org/jboss/netty/handler/codec/http/HttpContentCompressorTest.java +++ b/src/test/java/org/jboss/netty/handler/codec/http/HttpContentCompressorTest.java @@ -20,9 +20,6 @@ import org.junit.Test; public class HttpContentCompressorTest { - private HttpContentCompressor httpContentCompressor = - new HttpContentCompressor(); - @Test public void testGetTargetContentEncoding() throws Exception { HttpContentCompressor compressor = new HttpContentCompressor(); From 01225b0a522720a7423390673581a0e48bf1d7c2 Mon Sep 17 00:00:00 2001 From: Norman Maurer Date: Thu, 2 Feb 2012 15:16:45 +0100 Subject: [PATCH 09/10] HttpMessageEncoder should add Header "Transfer-Encoding: chunked" if HttpMessage.isChunked(). See #171 --- .../handler/codec/http/HttpMessageEncoder.java | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/jboss/netty/handler/codec/http/HttpMessageEncoder.java b/src/main/java/org/jboss/netty/handler/codec/http/HttpMessageEncoder.java index fb5ef5418f..38ca722f2a 100644 --- a/src/main/java/org/jboss/netty/handler/codec/http/HttpMessageEncoder.java +++ b/src/main/java/org/jboss/netty/handler/codec/http/HttpMessageEncoder.java @@ -25,6 +25,8 @@ import org.jboss.netty.buffer.ChannelBuffer; import org.jboss.netty.buffer.ChannelBuffers; import org.jboss.netty.channel.Channel; import org.jboss.netty.channel.ChannelHandlerContext; +import org.jboss.netty.handler.codec.http.HttpHeaders.Names; +import org.jboss.netty.handler.codec.http.HttpHeaders.Values; import org.jboss.netty.handler.codec.oneone.OneToOneEncoder; import org.jboss.netty.util.CharsetUtil; @@ -60,7 +62,17 @@ public abstract class HttpMessageEncoder extends OneToOneEncoder { protected Object encode(ChannelHandlerContext ctx, Channel channel, Object msg) throws Exception { if (msg instanceof HttpMessage) { HttpMessage m = (HttpMessage) msg; - boolean chunked = this.chunked = HttpCodecUtil.isTransferEncodingChunked(m); + boolean chunked; + if (m.isChunked()) { + // check if the Transfer-Encoding is set to chunked already. + // if not add the header to the message + if (!HttpCodecUtil.isTransferEncodingChunked(m)) { + m.addHeader(Names.TRANSFER_ENCODING, Values.CHUNKED); + } + chunked = this.chunked = true; + } else { + chunked = this.chunked = HttpCodecUtil.isTransferEncodingChunked(m); + } ChannelBuffer header = ChannelBuffers.dynamicBuffer( channel.getConfig().getBufferFactory()); encodeInitialLine(header, m); From 188f01f3174cf94bbf5f31906b046d8aec5cebf8 Mon Sep 17 00:00:00 2001 From: Norman Maurer Date: Fri, 3 Feb 2012 15:47:34 +0100 Subject: [PATCH 10/10] Remove the child Executor with the right method so it will also work when the channel is not the key.See #175 --- .../handler/execution/OrderedMemoryAwareThreadPoolExecutor.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/jboss/netty/handler/execution/OrderedMemoryAwareThreadPoolExecutor.java b/src/main/java/org/jboss/netty/handler/execution/OrderedMemoryAwareThreadPoolExecutor.java index 23b7f17b37..6995b3bfb3 100644 --- a/src/main/java/org/jboss/netty/handler/execution/OrderedMemoryAwareThreadPoolExecutor.java +++ b/src/main/java/org/jboss/netty/handler/execution/OrderedMemoryAwareThreadPoolExecutor.java @@ -260,7 +260,7 @@ public class OrderedMemoryAwareThreadPoolExecutor extends ChannelStateEvent se = (ChannelStateEvent) e; if (se.getState() == ChannelState.OPEN && !channel.isOpen()) { - childExecutors.remove(channel); + removeChildExecutor(key); } } return executor;