+
+/*
+ * compress_gzip() uses the same calling syntax as compress2(), but it
+ * creates a stream compatible with HTTP "Content-encoding: gzip"
+ */
+#ifdef HAVE_ZLIB
+#define DEF_MEM_LEVEL 8
+#define OS_CODE 0x03 /* unix */
+int ZEXPORT compress_gzip(Bytef * dest, uLongf * destLen,
+ const Bytef * source, uLong sourceLen, int level)
+{
+ const int gz_magic[2] = { 0x1f, 0x8b }; /* gzip magic header */
+
+ /* write gzip header */
+ sprintf((char *) dest, "%c%c%c%c%c%c%c%c%c%c",
+ gz_magic[0], gz_magic[1], Z_DEFLATED,
+ 0 /*flags */ , 0, 0, 0, 0 /*time */ , 0 /*xflags */ ,
+ OS_CODE);
+
+ /* normal deflate */
+ z_stream stream;
+ int err;
+ stream.next_in = (Bytef *) source;
+ stream.avail_in = (uInt) sourceLen;
+ stream.next_out = dest + 10L; // after header
+ stream.avail_out = (uInt) * destLen;
+ if ((uLong) stream.avail_out != *destLen)
+ return Z_BUF_ERROR;
+
+ stream.zalloc = (alloc_func) 0;
+ stream.zfree = (free_func) 0;
+ stream.opaque = (voidpf) 0;
+
+ err = deflateInit2(&stream, level, Z_DEFLATED, -MAX_WBITS,
+ DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY);
+ if (err != Z_OK)
+ return err;
+
+ err = deflate(&stream, Z_FINISH);
+ if (err != Z_STREAM_END) {
+ deflateEnd(&stream);
+ return err == Z_OK ? Z_BUF_ERROR : err;
+ }
+ *destLen = stream.total_out + 10L;
+
+ /* write CRC and Length */
+ uLong crc = crc32(0L, source, sourceLen);
+ int n;
+ for (n = 0; n < 4; ++n, ++*destLen) {
+ dest[*destLen] = (int) (crc & 0xff);
+ crc >>= 8;
+ }
+ uLong len = stream.total_in;
+ for (n = 0; n < 4; ++n, ++*destLen) {
+ dest[*destLen] = (int) (len & 0xff);
+ len >>= 8;
+ }
+ err = deflateEnd(&stream);
+ return err;
+}
+#endif
+
+void end_burst(void)
+{