Add ZLIB_OR_NONE support to JdkZlibDecoder [#2016]

This commit is contained in:
Jakob Buchgraber 2014-02-27 19:41:48 +01:00 committed by Norman Maurer
parent fcc6b544a4
commit 9fb235459e
5 changed files with 43 additions and 42 deletions

View File

@ -36,7 +36,7 @@ public class JdkZlibDecoder extends ZlibDecoder {
private static final int FCOMMENT = 0x10;
private static final int FRESERVED = 0xE0;
private final Inflater inflater;
private Inflater inflater;
private final byte[] dictionary;
// GZIP related
@ -59,6 +59,8 @@ public class JdkZlibDecoder extends ZlibDecoder {
private volatile boolean finished;
private boolean decideZlibOrNone;
/**
* Creates a new instance with the default wrapper ({@link ZlibWrapper#ZLIB}).
*/
@ -101,6 +103,11 @@ public class JdkZlibDecoder extends ZlibDecoder {
inflater = new Inflater();
crc = null;
break;
case ZLIB_OR_NONE:
// Postpone the decision until decode(...) is called.
decideZlibOrNone = true;
crc = null;
break;
default:
throw new IllegalArgumentException("Only GZIP or ZLIB is supported, but you used " + wrapper);
}
@ -124,6 +131,17 @@ public class JdkZlibDecoder extends ZlibDecoder {
return;
}
if (decideZlibOrNone) {
// First two bytes are needed to decide if it's a ZLIB stream.
if (in.readableBytes() < 2) {
return;
}
boolean nowrap = !looksLikeZlib(in.getShort(0));
inflater = new Inflater(nowrap);
decideZlibOrNone = false;
}
if (crc != null) {
switch (gzipState) {
case FOOTER_START:
@ -215,8 +233,10 @@ public class JdkZlibDecoder extends ZlibDecoder {
@Override
protected void handlerRemoved0(ChannelHandlerContext ctx) throws Exception {
super.handlerRemoved0(ctx);
if (inflater != null) {
inflater.end();
}
}
private boolean readGZIPHeader(ByteBuf in) {
switch (gzipState) {
@ -357,4 +377,16 @@ public class JdkZlibDecoder extends ZlibDecoder {
"CRC value missmatch. Expected: " + crcValue + ", Got: " + readCrc);
}
}
/*
* Returns true if the cmf_flg parameter (think: first two bytes of a zlib stream)
* indicates that this is a zlib stream.
* <p>
* You can lookup the details in the ZLIB RFC:
* <a href="http://tools.ietf.org/html/rfc1950#section-2.2">RFC 1950</a>.
*/
private boolean looksLikeZlib(short cmf_flg) {
return (cmf_flg & 0x7800) == 0x7800 &&
cmf_flg % 31 == 0;
}
}

View File

@ -98,17 +98,12 @@ public final class ZlibCodecFactory {
}
public static ZlibDecoder newZlibDecoder(ZlibWrapper wrapper) {
switch (wrapper) {
case ZLIB_OR_NONE:
return new JZlibDecoder(wrapper);
default:
if (PlatformDependent.javaVersion() < 7 || noJdkZlibDecoder) {
return new JZlibDecoder(wrapper);
} else {
return new JdkZlibDecoder(wrapper);
}
}
}
public static ZlibDecoder newZlibDecoder(byte[] dictionary) {
if (PlatformDependent.javaVersion() < 7 || noJdkZlibDecoder) {

View File

@ -30,21 +30,8 @@ public class JdkZlibTest extends ZlibTest {
return new JdkZlibDecoder(wrapper);
}
@Override
@Test(expected = IllegalArgumentException.class)
public void testZLIB_OR_NONE() throws Exception {
new JdkZlibDecoder(ZlibWrapper.ZLIB_OR_NONE);
}
@Override
@Test(expected = IllegalArgumentException.class)
public void testZLIB_OR_NONE2() throws Exception {
new JdkZlibDecoder(ZlibWrapper.ZLIB_OR_NONE);
}
@Override
@Test(expected = IllegalArgumentException.class)
@Test(expected = DecompressionException.class)
public void testZLIB_OR_NONE3() throws Exception {
new JdkZlibDecoder(ZlibWrapper.ZLIB_OR_NONE);
super.testZLIB_OR_NONE3();
}
}

View File

@ -29,21 +29,8 @@ public class ZlibCrossTest2 extends ZlibTest {
return new JdkZlibDecoder(wrapper);
}
@Override
@Test(expected = IllegalArgumentException.class)
public void testZLIB_OR_NONE() throws Exception {
new JdkZlibDecoder(ZlibWrapper.ZLIB_OR_NONE);
}
@Override
@Test(expected = IllegalArgumentException.class)
public void testZLIB_OR_NONE2() throws Exception {
new JdkZlibDecoder(ZlibWrapper.ZLIB_OR_NONE);
}
@Override
@Test(expected = IllegalArgumentException.class)
@Test(expected = DecompressionException.class)
public void testZLIB_OR_NONE3() throws Exception {
new JdkZlibDecoder(ZlibWrapper.ZLIB_OR_NONE);
super.testZLIB_OR_NONE3();
}
}

View File

@ -179,7 +179,7 @@ public abstract class ZlibTest {
public void testZLIB_OR_NONE2() throws Exception {
testCompressNone(ZlibWrapper.ZLIB, ZlibWrapper.ZLIB_OR_NONE);
testCompressSmall(ZlibWrapper.ZLIB, ZlibWrapper.ZLIB_OR_NONE);
testCompressLarge(ZlibWrapper.GZIP, ZlibWrapper.ZLIB_OR_NONE);
testCompressLarge(ZlibWrapper.ZLIB, ZlibWrapper.ZLIB_OR_NONE);
}
@Test