package io.undertow.conduits;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.zip.CRC32;
import java.util.zip.Deflater;
import java.util.zip.Inflater;
import org.xnio.conduits.StreamSourceConduit;
import io.undertow.UndertowMessages;
import io.undertow.server.ConduitWrapper;
import io.undertow.server.HttpServerExchange;
import io.undertow.util.ConduitFactory;
import io.undertow.util.ObjectPool;
public class GzipStreamSourceConduit extends InflatingStreamSourceConduit {
public static final ConduitWrapper<StreamSourceConduit> WRAPPER = new ConduitWrapper<StreamSourceConduit>() {
@Override
public StreamSourceConduit wrap(ConduitFactory<StreamSourceConduit> factory, HttpServerExchange exchange) {
return new GzipStreamSourceConduit(exchange, factory.create());
}
};
private static final int GZIP_MAGIC = 0x8b1f;
private static final byte[] = new byte[]{
(byte) GZIP_MAGIC,
(byte) (GZIP_MAGIC >> 8),
Deflater.DEFLATED,
0,
0,
0,
0,
0,
0,
0
};
private final CRC32 crc = new CRC32();
public GzipStreamSourceConduit(HttpServerExchange exchange, StreamSourceConduit next) {
super(exchange, next);
}
public GzipStreamSourceConduit(
HttpServerExchange exchange,
StreamSourceConduit next,
ObjectPool<Inflater> inflaterPool) {
super(exchange, next, inflaterPool);
}
private int totalOut;
private int = 0;
private int = 0;
byte[] ;
protected boolean (ByteBuffer headerData) throws IOException {
while (headerRead < HEADER.length && headerData.hasRemaining()) {
byte data = headerData.get();
if (headerRead == 0 && data != HEADER[0]) {
throw UndertowMessages.MESSAGES.invalidGzipHeader();
} else if (headerRead == 1 && data != HEADER[1]) {
throw UndertowMessages.MESSAGES.invalidGzipHeader();
}
headerRead++;
}
return headerRead == HEADER.length;
}
protected void (ByteBuffer buf) throws IOException {
if (expectedFooter == null) {
byte[] ret = new byte[8];
int checksum = (int) crc.getValue();
int total = totalOut;
ret[0] = (byte) ((checksum) & 0xFF);
ret[1] = (byte) ((checksum >> 8) & 0xFF);
ret[2] = (byte) ((checksum >> 16) & 0xFF);
ret[3] = (byte) ((checksum >> 24) & 0xFF);
ret[4] = (byte) ((total) & 0xFF);
ret[5] = (byte) ((total >> 8) & 0xFF);
ret[6] = (byte) ((total >> 16) & 0xFF);
ret[7] = (byte) ((total >> 24) & 0xFF);
expectedFooter = ret;
}
while (buf.hasRemaining() && footerRead < expectedFooter.length) {
byte data = buf.get();
if (expectedFooter[footerRead++] != data) {
throw UndertowMessages.MESSAGES.invalidGZIPFooter();
}
}
if (buf.hasRemaining() && footerRead == expectedFooter.length) {
throw UndertowMessages.MESSAGES.invalidGZIPFooter();
}
}
protected void dataDeflated(byte[] data, int off, int len) {
crc.update(data, off, len);
totalOut += len;
}
}