package io.undertow.conduits;
import io.undertow.server.Connectors;
import io.undertow.server.HttpServerExchange;
import io.undertow.util.ConduitFactory;
import io.undertow.util.ObjectPool;
import org.xnio.conduits.StreamSinkConduit;
import java.util.zip.CRC32;
import java.util.zip.Deflater;
public class GzipStreamSinkConduit extends DeflatingStreamSinkConduit {
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
};
protected CRC32 crc = new CRC32();
public GzipStreamSinkConduit(ConduitFactory<StreamSinkConduit> conduitFactory, HttpServerExchange exchange) {
this(conduitFactory, exchange, Deflater.DEFAULT_COMPRESSION);
}
public GzipStreamSinkConduit(
ConduitFactory<StreamSinkConduit> conduitFactory,
HttpServerExchange exchange,
int deflateLevel) {
this(conduitFactory, exchange, newInstanceDeflaterPool(deflateLevel));
}
public GzipStreamSinkConduit(
ConduitFactory<StreamSinkConduit> conduitFactory,
HttpServerExchange exchange,
ObjectPool deflaterPool) {
super(conduitFactory, exchange, deflaterPool);
writeHeader();
Connectors.updateResponseBytesSent(exchange, HEADER.length);
}
private void () {
currentBuffer.getBuffer().put(HEADER);
}
@Override
protected void preDeflate(byte[] data) {
crc.update(data);
}
@Override
protected byte[] getTrailer() {
byte[] ret = new byte[8];
int checksum = (int) crc.getValue();
int total = deflater.getTotalIn();
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);
return ret;
}
}