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 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; 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; } 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/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); + } } 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()); + } } 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..170240c260 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 @@ -83,12 +120,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/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); 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; 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) { 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..4dd00ec1c8 --- /dev/null +++ b/src/test/java/org/jboss/netty/handler/codec/http/HttpContentCompressorTest.java @@ -0,0 +1,46 @@ +/* + * 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 { + + @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); + } + } +}