1
18
19 package io.undertow.conduits;
20
21 import io.undertow.server.Connectors;
22 import io.undertow.server.HttpServerExchange;
23 import io.undertow.util.ConduitFactory;
24 import io.undertow.util.ObjectPool;
25 import org.xnio.conduits.StreamSinkConduit;
26
27 import java.util.zip.CRC32;
28 import java.util.zip.Deflater;
29
30
33 public class GzipStreamSinkConduit extends DeflatingStreamSinkConduit {
34
35
38 private static final int GZIP_MAGIC = 0x8b1f;
39 private static final byte[] HEADER = new byte[]{
40 (byte) GZIP_MAGIC,
41 (byte) (GZIP_MAGIC >> 8),
42 Deflater.DEFLATED,
43 0,
44 0,
45 0,
46 0,
47 0,
48 0,
49 0
50 };
51
52
55 protected CRC32 crc = new CRC32();
56
57 public GzipStreamSinkConduit(ConduitFactory<StreamSinkConduit> conduitFactory, HttpServerExchange exchange) {
58 this(conduitFactory, exchange, Deflater.DEFAULT_COMPRESSION);
59 }
60
61 public GzipStreamSinkConduit(
62 ConduitFactory<StreamSinkConduit> conduitFactory,
63 HttpServerExchange exchange,
64 int deflateLevel) {
65 this(conduitFactory, exchange, newInstanceDeflaterPool(deflateLevel));
66 }
67
68 public GzipStreamSinkConduit(
69 ConduitFactory<StreamSinkConduit> conduitFactory,
70 HttpServerExchange exchange,
71 ObjectPool deflaterPool) {
72 super(conduitFactory, exchange, deflaterPool);
73 writeHeader();
74 Connectors.updateResponseBytesSent(exchange, HEADER.length);
75 }
76
77 private void writeHeader() {
78 currentBuffer.getBuffer().put(HEADER);
79 }
80
81 @Override
82 protected void preDeflate(byte[] data) {
83 crc.update(data);
84 }
85
86 @Override
87 protected byte[] getTrailer() {
88 byte[] ret = new byte[8];
89 int checksum = (int) crc.getValue();
90 int total = deflater.getTotalIn();
91 ret[0] = (byte) ((checksum) & 0xFF);
92 ret[1] = (byte) ((checksum >> 8) & 0xFF);
93 ret[2] = (byte) ((checksum >> 16) & 0xFF);
94 ret[3] = (byte) ((checksum >> 24) & 0xFF);
95 ret[4] = (byte) ((total) & 0xFF);
96 ret[5] = (byte) ((total >> 8) & 0xFF);
97 ret[6] = (byte) ((total >> 16) & 0xFF);
98 ret[7] = (byte) ((total >> 24) & 0xFF);
99 return ret;
100 }
101 }
102