366 lines
10 KiB
Diff
366 lines
10 KiB
Diff
|
--- mod_gzip.c-old Fri Jan 26 10:50:05 2001
|
|||
|
+++ mod_gzip.c Fri Jan 26 15:08:26 2001
|
|||
|
@@ -575,10 +575,15 @@
|
|||
|
* The GZP request control structure...
|
|||
|
*/
|
|||
|
|
|||
|
+#define GZIP_FORMAT (0)
|
|||
|
+#define DEFLATE_FORMAT (1)
|
|||
|
+
|
|||
|
typedef struct _GZP_CONTROL {
|
|||
|
|
|||
|
int decompress; /* 0=Compress 1=Decompress */
|
|||
|
|
|||
|
+ int compression_format; /* GZIP_FORMAT or DEFLATE_FORMAT */
|
|||
|
+
|
|||
|
/* Input control... */
|
|||
|
|
|||
|
int input_ismem; /* Input source is memory buffer, not file */
|
|||
|
@@ -2209,10 +2214,11 @@
|
|||
|
mod_gzip_printf( "%s: Checking for 'gzip' designator...\n",cn);
|
|||
|
#endif
|
|||
|
|
|||
|
- if ( strstr( has_encoding, "gzip" ) )
|
|||
|
+ if ( strstr( has_encoding, "gzip" ) ||
|
|||
|
+ strstr( has_encoding, "deflate" ) )
|
|||
|
{
|
|||
|
#ifdef MOD_GZIP_DEBUG1
|
|||
|
- mod_gzip_printf( "%s: 'Content-encoding:' field contains 'gzip' designator...\n",cn);
|
|||
|
+ mod_gzip_printf( "%s: 'Content-encoding:' field contains 'gzip' or 'deflate' designator...\n",cn);
|
|||
|
mod_gzip_printf( "%s: Pre-compression is assumed.\n",cn);
|
|||
|
mod_gzip_printf( "%s: Exit > return( DECLINED ) >\n",cn);
|
|||
|
#endif
|
|||
|
@@ -2237,7 +2243,7 @@
|
|||
|
else /* 'gzip' designator not found... */
|
|||
|
{
|
|||
|
#ifdef MOD_GZIP_DEBUG1
|
|||
|
- mod_gzip_printf( "%s: 'Content-encoding:' field does NOT contain 'gzip' designator...\n",cn);
|
|||
|
+ mod_gzip_printf( "%s: 'Content-encoding:' field does NOT contain 'gzip' or 'deflate' designator...\n",cn);
|
|||
|
mod_gzip_printf( "%s: Assuming OK to proceed...\n",cn);
|
|||
|
#endif
|
|||
|
}
|
|||
|
@@ -2347,10 +2353,21 @@
|
|||
|
if ( accept_encoding )
|
|||
|
{
|
|||
|
/* ...and if it has the right 'gzip' indicator... */
|
|||
|
-
|
|||
|
+ /* We record the compression format in a request note, so we
|
|||
|
+ * can get it again later, and so it can potentially be logged.
|
|||
|
+ */
|
|||
|
if ( strstr( accept_encoding, "gzip" ) )
|
|||
|
{
|
|||
|
process = 1; /* ...set the 'process' flag TRUE */
|
|||
|
+ ap_table_setn( r->notes,"mod_gzip_compression_format",
|
|||
|
+ ap_pstrdup(r->pool,"gzip"));
|
|||
|
+
|
|||
|
+ }
|
|||
|
+ else if ( strstr( accept_encoding, "deflate" ) )
|
|||
|
+ {
|
|||
|
+ process = 1; /* ...set the 'process' flag TRUE */
|
|||
|
+ ap_table_setn( r->notes,"mod_gzip_compression_format",
|
|||
|
+ ap_pstrdup(r->pool,"deflate"));
|
|||
|
}
|
|||
|
|
|||
|
}/* End 'if( accept_encoding )' */
|
|||
|
@@ -2388,7 +2405,7 @@
|
|||
|
else /* 'gzip' designator was seen in 'Accept-Encoding:' field */
|
|||
|
{
|
|||
|
#ifdef MOD_GZIP_DEBUG1
|
|||
|
- mod_gzip_printf( "%s: 'gzip' capability specified by user-agent.\n",cn);
|
|||
|
+ mod_gzip_printf( "%s: 'gzip' or 'deflate' capability specified by user-agent.\n",cn);
|
|||
|
mod_gzip_printf( "%s: Assuming OK to proceed...\n",cn);
|
|||
|
#endif
|
|||
|
}
|
|||
|
@@ -4093,7 +4110,8 @@
|
|||
|
|
|||
|
char tmp[ MOD_GZIP_LARGE_BUFFER_SIZE + 2 ]; /* Scratch buffer */
|
|||
|
|
|||
|
- char actual_content_encoding_name[] = "gzip"; /* Adjustable */
|
|||
|
+ char *actual_content_encoding_name = "gzip"; /* Adjustable */
|
|||
|
+ const char *compression_format;
|
|||
|
|
|||
|
#ifdef MOD_GZIP_DEBUG1
|
|||
|
char cn[]="mod_gzip_encode_and_transmit()";
|
|||
|
@@ -4470,6 +4488,18 @@
|
|||
|
|
|||
|
gzp->decompress = 0; /* Perform encoding */
|
|||
|
|
|||
|
+ /* Recover the compression format we're supposed to use. */
|
|||
|
+ compression_format = ap_table_get(r->notes, "mod_gzip_compression_format");
|
|||
|
+ if (compression_format && strcmp(compression_format, "deflate") == 0)
|
|||
|
+ {
|
|||
|
+ actual_content_encoding_name = "deflate";
|
|||
|
+ gzp->compression_format = DEFLATE_FORMAT;
|
|||
|
+ }
|
|||
|
+ else
|
|||
|
+ {
|
|||
|
+ gzp->compression_format = GZIP_FORMAT;
|
|||
|
+ }
|
|||
|
+
|
|||
|
if ( input_size <= (long) conf->maximum_inmem_size )
|
|||
|
{
|
|||
|
/* The input source is small enough to compress directly */
|
|||
|
@@ -4591,6 +4621,7 @@
|
|||
|
|
|||
|
#ifdef MOD_GZIP_DEBUG1
|
|||
|
mod_gzip_printf( "%s: gzp->decompress = %d\n" ,cn,gzp->decompress);
|
|||
|
+ mod_gzip_printf( "%s: gzp->compression_format = %d\n",cn,gzp->compression_format);
|
|||
|
mod_gzip_printf( "%s: gzp->input_ismem = %d\n", cn,gzp->input_ismem);
|
|||
|
mod_gzip_printf( "%s: gzp->output_ismem = %d\n", cn,gzp->output_ismem);
|
|||
|
mod_gzip_printf( "%s: gzp->input_filename = [%s]\n",cn,gzp->input_filename);
|
|||
|
@@ -7256,6 +7287,8 @@
|
|||
|
};
|
|||
|
|
|||
|
typedef struct _GZ1 {
|
|||
|
+ long compression_format;
|
|||
|
+
|
|||
|
long versionid1;
|
|||
|
int state;
|
|||
|
int done;
|
|||
|
@@ -7345,6 +7378,7 @@
|
|||
|
int dbits;
|
|||
|
ulg window_size;
|
|||
|
ulg crc;
|
|||
|
+ ulg adler;
|
|||
|
|
|||
|
uch dist_code[512];
|
|||
|
uch length_code[MAX_MATCH-MIN_MATCH+1];
|
|||
|
@@ -7449,6 +7483,15 @@
|
|||
|
|
|||
|
void error( char *msg );
|
|||
|
|
|||
|
+/* XXX - Precomputed zlib header. If you change the window size or
|
|||
|
+ * compression level from the defaults, this will break badly. The
|
|||
|
+ * algorithm to build this is fairly complex; you can find it in
|
|||
|
+ * the file deflate.c from the zlib distribution.
|
|||
|
+ */
|
|||
|
+#define ZLIB_HEADER "\170<37>"
|
|||
|
+
|
|||
|
+ulg adler32(ulg adler, uch *buf, unsigned len);
|
|||
|
+
|
|||
|
int zip(
|
|||
|
PGZ1 gz1,
|
|||
|
int in,
|
|||
|
@@ -9088,10 +9131,20 @@
|
|||
|
if ( len == (unsigned)(-1) || len == 0 )
|
|||
|
{
|
|||
|
gz1->crc = gz1->crc ^ 0xffffffffL;
|
|||
|
+ /* XXX - Do we need to do something with Adler CRC's here?
|
|||
|
+ * I don't think so--they don't seem to need postprocessing. */
|
|||
|
return (int)len;
|
|||
|
}
|
|||
|
|
|||
|
- updcrc( gz1, (uch*)buf, len );
|
|||
|
+ if (gz1->compression_format != DEFLATE_FORMAT)
|
|||
|
+ {
|
|||
|
+ updcrc( gz1, (uch*)buf, len );
|
|||
|
+ }
|
|||
|
+ else
|
|||
|
+ {
|
|||
|
+ gz1->adler = adler32(gz1->adler, (uch*)buf, len);
|
|||
|
+ }
|
|||
|
+
|
|||
|
gz1->bytes_in += (ulg)len;
|
|||
|
|
|||
|
return (int)len;
|
|||
|
@@ -9288,6 +9341,7 @@
|
|||
|
gz1->heap[k] = v;
|
|||
|
}
|
|||
|
|
|||
|
+
|
|||
|
#define GZS_ZIP1 1
|
|||
|
#define GZS_ZIP2 2
|
|||
|
#define GZS_DEFLATE1 3
|
|||
|
@@ -9317,6 +9371,7 @@
|
|||
|
}
|
|||
|
|
|||
|
gz1->decompress = gzp->decompress;
|
|||
|
+ gz1->compression_format = gzp->compression_format;
|
|||
|
|
|||
|
strcpy( gz1->ifname, gzp->input_filename );
|
|||
|
strcpy( gz1->ofname, gzp->output_filename );
|
|||
|
@@ -9489,6 +9544,7 @@
|
|||
|
return( rc );
|
|||
|
}
|
|||
|
|
|||
|
+
|
|||
|
int gzs_zip1( PGZ1 gz1 )
|
|||
|
{
|
|||
|
uch flags = 0;
|
|||
|
@@ -9499,21 +9555,40 @@
|
|||
|
|
|||
|
gz1->method = DEFLATED;
|
|||
|
|
|||
|
- put_byte(GZIP_MAGIC[0]);
|
|||
|
- put_byte(GZIP_MAGIC[1]);
|
|||
|
- put_byte(DEFLATED);
|
|||
|
+ if (gz1->compression_format != DEFLATE_FORMAT)
|
|||
|
+ {
|
|||
|
+ put_byte(GZIP_MAGIC[0]);
|
|||
|
+ put_byte(GZIP_MAGIC[1]);
|
|||
|
+ put_byte(DEFLATED);
|
|||
|
+ }
|
|||
|
+ else
|
|||
|
+ {
|
|||
|
+ /* Yes, I know RFC 1951 doesn't mention any header at the start of
|
|||
|
+ * a deflated document, but zlib absolutely requires one. And since nearly
|
|||
|
+ * all "deflate" implementations use zlib, we need to play along with this
|
|||
|
+ * brain damage. */
|
|||
|
+ put_byte(ZLIB_HEADER[0]);
|
|||
|
+ put_byte(ZLIB_HEADER[1]);
|
|||
|
+ }
|
|||
|
|
|||
|
if ( gz1->save_orig_name )
|
|||
|
{
|
|||
|
flags |= ORIG_NAME;
|
|||
|
}
|
|||
|
|
|||
|
- put_byte(flags);
|
|||
|
- put_long(gz1->time_stamp);
|
|||
|
-
|
|||
|
- gz1->crc = -1;
|
|||
|
+ if (gz1->compression_format != DEFLATE_FORMAT)
|
|||
|
+ {
|
|||
|
+ put_byte(flags);
|
|||
|
+ put_long(gz1->time_stamp);
|
|||
|
|
|||
|
- updcrc( gz1, NULL, 0 );
|
|||
|
+ gz1->crc = -1;
|
|||
|
+ updcrc( gz1, NULL, 0 );
|
|||
|
+ }
|
|||
|
+ else
|
|||
|
+ {
|
|||
|
+ /* Deflate compression uses an Adler32 CRC, not a CRC32. */
|
|||
|
+ gz1->adler = 1L;
|
|||
|
+ }
|
|||
|
|
|||
|
gz1->state = GZS_ZIP2;
|
|||
|
|
|||
|
@@ -9529,18 +9604,20 @@
|
|||
|
bi_init( gz1, gz1->ofd );
|
|||
|
ct_init( gz1, &attr, &gz1->method );
|
|||
|
lm_init( gz1, gz1->level, &deflate_flags );
|
|||
|
- put_byte((uch)deflate_flags);
|
|||
|
-
|
|||
|
- put_byte(OS_CODE);
|
|||
|
|
|||
|
- if ( gz1->save_orig_name )
|
|||
|
+ if (gz1->compression_format != DEFLATE_FORMAT)
|
|||
|
{
|
|||
|
- char *p = gz1_basename( gz1, gz1->ifname );
|
|||
|
+ put_byte((uch)deflate_flags);
|
|||
|
+ put_byte(OS_CODE);
|
|||
|
+ if ( gz1->save_orig_name )
|
|||
|
+ {
|
|||
|
+ char *p = gz1_basename( gz1, gz1->ifname );
|
|||
|
|
|||
|
- do {
|
|||
|
- put_char(*p);
|
|||
|
+ do {
|
|||
|
+ put_char(*p);
|
|||
|
|
|||
|
- } while (*p++);
|
|||
|
+ } while (*p++);
|
|||
|
+ }
|
|||
|
}
|
|||
|
|
|||
|
gz1->header_bytes = (long)gz1->outcnt;
|
|||
|
@@ -9674,10 +9751,25 @@
|
|||
|
}
|
|||
|
#endif
|
|||
|
|
|||
|
- put_long( gz1->crc );
|
|||
|
- put_long( gz1->bytes_in );
|
|||
|
-
|
|||
|
- gz1->header_bytes += 2*sizeof(long);
|
|||
|
+ if (gz1->compression_format != DEFLATE_FORMAT)
|
|||
|
+ {
|
|||
|
+ put_long( gz1->crc );
|
|||
|
+ put_long( gz1->bytes_in );
|
|||
|
+ gz1->header_bytes += 2*sizeof(long);
|
|||
|
+ }
|
|||
|
+ else
|
|||
|
+ {
|
|||
|
+ /* Append an Adler32 CRC to our deflated data.
|
|||
|
+ * Yes, I know RFC 1951 doesn't mention any CRC at the end of a
|
|||
|
+ * deflated document, but zlib absolutely requires one. And since nearly
|
|||
|
+ * all "deflate" implementations use zlib, we need to play along with this
|
|||
|
+ * brain damage. */
|
|||
|
+ put_byte( (gz1->adler >> 24) );
|
|||
|
+ put_byte( (gz1->adler >> 16) & 0xFF );
|
|||
|
+ put_byte( (gz1->adler >> 8) & 0xFF );
|
|||
|
+ put_byte( (gz1->adler ) & 0xFF );
|
|||
|
+ gz1->header_bytes += 4*sizeof(uch);
|
|||
|
+ }
|
|||
|
|
|||
|
flush_outbuf( gz1 );
|
|||
|
|
|||
|
@@ -9685,6 +9777,67 @@
|
|||
|
|
|||
|
return OK;
|
|||
|
}
|
|||
|
+
|
|||
|
+
|
|||
|
+/* =========================================================================
|
|||
|
+ adler32 -- compute the Adler-32 checksum of a data stream
|
|||
|
+ Copyright (C) 1995-1998 Mark Adler
|
|||
|
+
|
|||
|
+ This software is provided 'as-is', without any express or implied
|
|||
|
+ warranty. In no event will the authors be held liable for any damages
|
|||
|
+ arising from the use of this software.
|
|||
|
+
|
|||
|
+ Permission is granted to anyone to use this software for any purpose,
|
|||
|
+ including commercial applications, and to alter it and redistribute it
|
|||
|
+ freely, subject to the following restrictions:
|
|||
|
+
|
|||
|
+ 1. The origin of this software must not be misrepresented; you must not
|
|||
|
+ claim that you wrote the original software. If you use this software
|
|||
|
+ in a product, an acknowledgment in the product documentation would be
|
|||
|
+ appreciated but is not required.
|
|||
|
+ 2. Altered source versions must be plainly marked as such, and must not be
|
|||
|
+ misrepresented as being the original software.
|
|||
|
+ 3. This notice may not be removed or altered from any source distribution.
|
|||
|
+
|
|||
|
+ Modified by Eric Kidd <eric.kidd@pobox.com> to play nicely with mod_gzip.
|
|||
|
+ */
|
|||
|
+
|
|||
|
+#define BASE 65521L /* largest prime smaller than 65536 */
|
|||
|
+#define NMAX 5552
|
|||
|
+/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */
|
|||
|
+
|
|||
|
+#define DO1(buf,i) {s1 += buf[i]; s2 += s1;}
|
|||
|
+#define DO2(buf,i) DO1(buf,i); DO1(buf,i+1);
|
|||
|
+#define DO4(buf,i) DO2(buf,i); DO2(buf,i+2);
|
|||
|
+#define DO8(buf,i) DO4(buf,i); DO4(buf,i+4);
|
|||
|
+#define DO16(buf) DO8(buf,0); DO8(buf,8);
|
|||
|
+
|
|||
|
+ulg adler32(ulg adler, uch *buf, unsigned len)
|
|||
|
+{
|
|||
|
+ unsigned long s1 = adler & 0xffff;
|
|||
|
+ unsigned long s2 = (adler >> 16) & 0xffff;
|
|||
|
+ int k;
|
|||
|
+
|
|||
|
+ if (buf == NULL) return 1L;
|
|||
|
+
|
|||
|
+ while (len > 0) {
|
|||
|
+ k = len < NMAX ? len : NMAX;
|
|||
|
+ len -= k;
|
|||
|
+ while (k >= 16) {
|
|||
|
+ DO16(buf);
|
|||
|
+ buf += 16;
|
|||
|
+ k -= 16;
|
|||
|
+ }
|
|||
|
+ if (k != 0) do {
|
|||
|
+ s1 += *buf++;
|
|||
|
+ s2 += s1;
|
|||
|
+ } while (--k);
|
|||
|
+ s1 %= BASE;
|
|||
|
+ s2 %= BASE;
|
|||
|
+ }
|
|||
|
+ return (s2 << 16) | s1;
|
|||
|
+}
|
|||
|
+
|
|||
|
|
|||
|
/* END OF FILE */
|
|||
|
|