mod_gzip.c.diff 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365
  1. --- mod_gzip.c-old Fri Jan 26 10:50:05 2001
  2. +++ mod_gzip.c Fri Jan 26 15:08:26 2001
  3. @@ -575,10 +575,15 @@
  4. * The GZP request control structure...
  5. */
  6. +#define GZIP_FORMAT (0)
  7. +#define DEFLATE_FORMAT (1)
  8. +
  9. typedef struct _GZP_CONTROL {
  10. int decompress; /* 0=Compress 1=Decompress */
  11. + int compression_format; /* GZIP_FORMAT or DEFLATE_FORMAT */
  12. +
  13. /* Input control... */
  14. int input_ismem; /* Input source is memory buffer, not file */
  15. @@ -2209,10 +2214,11 @@
  16. mod_gzip_printf( "%s: Checking for 'gzip' designator...\n",cn);
  17. #endif
  18. - if ( strstr( has_encoding, "gzip" ) )
  19. + if ( strstr( has_encoding, "gzip" ) ||
  20. + strstr( has_encoding, "deflate" ) )
  21. {
  22. #ifdef MOD_GZIP_DEBUG1
  23. - mod_gzip_printf( "%s: 'Content-encoding:' field contains 'gzip' designator...\n",cn);
  24. + mod_gzip_printf( "%s: 'Content-encoding:' field contains 'gzip' or 'deflate' designator...\n",cn);
  25. mod_gzip_printf( "%s: Pre-compression is assumed.\n",cn);
  26. mod_gzip_printf( "%s: Exit > return( DECLINED ) >\n",cn);
  27. #endif
  28. @@ -2237,7 +2243,7 @@
  29. else /* 'gzip' designator not found... */
  30. {
  31. #ifdef MOD_GZIP_DEBUG1
  32. - mod_gzip_printf( "%s: 'Content-encoding:' field does NOT contain 'gzip' designator...\n",cn);
  33. + mod_gzip_printf( "%s: 'Content-encoding:' field does NOT contain 'gzip' or 'deflate' designator...\n",cn);
  34. mod_gzip_printf( "%s: Assuming OK to proceed...\n",cn);
  35. #endif
  36. }
  37. @@ -2347,10 +2353,21 @@
  38. if ( accept_encoding )
  39. {
  40. /* ...and if it has the right 'gzip' indicator... */
  41. -
  42. + /* We record the compression format in a request note, so we
  43. + * can get it again later, and so it can potentially be logged.
  44. + */
  45. if ( strstr( accept_encoding, "gzip" ) )
  46. {
  47. process = 1; /* ...set the 'process' flag TRUE */
  48. + ap_table_setn( r->notes,"mod_gzip_compression_format",
  49. + ap_pstrdup(r->pool,"gzip"));
  50. +
  51. + }
  52. + else if ( strstr( accept_encoding, "deflate" ) )
  53. + {
  54. + process = 1; /* ...set the 'process' flag TRUE */
  55. + ap_table_setn( r->notes,"mod_gzip_compression_format",
  56. + ap_pstrdup(r->pool,"deflate"));
  57. }
  58. }/* End 'if( accept_encoding )' */
  59. @@ -2388,7 +2405,7 @@
  60. else /* 'gzip' designator was seen in 'Accept-Encoding:' field */
  61. {
  62. #ifdef MOD_GZIP_DEBUG1
  63. - mod_gzip_printf( "%s: 'gzip' capability specified by user-agent.\n",cn);
  64. + mod_gzip_printf( "%s: 'gzip' or 'deflate' capability specified by user-agent.\n",cn);
  65. mod_gzip_printf( "%s: Assuming OK to proceed...\n",cn);
  66. #endif
  67. }
  68. @@ -4093,7 +4110,8 @@
  69. char tmp[ MOD_GZIP_LARGE_BUFFER_SIZE + 2 ]; /* Scratch buffer */
  70. - char actual_content_encoding_name[] = "gzip"; /* Adjustable */
  71. + char *actual_content_encoding_name = "gzip"; /* Adjustable */
  72. + const char *compression_format;
  73. #ifdef MOD_GZIP_DEBUG1
  74. char cn[]="mod_gzip_encode_and_transmit()";
  75. @@ -4470,6 +4488,18 @@
  76. gzp->decompress = 0; /* Perform encoding */
  77. + /* Recover the compression format we're supposed to use. */
  78. + compression_format = ap_table_get(r->notes, "mod_gzip_compression_format");
  79. + if (compression_format && strcmp(compression_format, "deflate") == 0)
  80. + {
  81. + actual_content_encoding_name = "deflate";
  82. + gzp->compression_format = DEFLATE_FORMAT;
  83. + }
  84. + else
  85. + {
  86. + gzp->compression_format = GZIP_FORMAT;
  87. + }
  88. +
  89. if ( input_size <= (long) conf->maximum_inmem_size )
  90. {
  91. /* The input source is small enough to compress directly */
  92. @@ -4591,6 +4621,7 @@
  93. #ifdef MOD_GZIP_DEBUG1
  94. mod_gzip_printf( "%s: gzp->decompress = %d\n" ,cn,gzp->decompress);
  95. + mod_gzip_printf( "%s: gzp->compression_format = %d\n",cn,gzp->compression_format);
  96. mod_gzip_printf( "%s: gzp->input_ismem = %d\n", cn,gzp->input_ismem);
  97. mod_gzip_printf( "%s: gzp->output_ismem = %d\n", cn,gzp->output_ismem);
  98. mod_gzip_printf( "%s: gzp->input_filename = [%s]\n",cn,gzp->input_filename);
  99. @@ -7256,6 +7287,8 @@
  100. };
  101. typedef struct _GZ1 {
  102. + long compression_format;
  103. +
  104. long versionid1;
  105. int state;
  106. int done;
  107. @@ -7345,6 +7378,7 @@
  108. int dbits;
  109. ulg window_size;
  110. ulg crc;
  111. + ulg adler;
  112. uch dist_code[512];
  113. uch length_code[MAX_MATCH-MIN_MATCH+1];
  114. @@ -7449,6 +7483,15 @@
  115. void error( char *msg );
  116. +/* XXX - Precomputed zlib header. If you change the window size or
  117. + * compression level from the defaults, this will break badly. The
  118. + * algorithm to build this is fairly complex; you can find it in
  119. + * the file deflate.c from the zlib distribution.
  120. + */
  121. +#define ZLIB_HEADER "\170œ"
  122. +
  123. +ulg adler32(ulg adler, uch *buf, unsigned len);
  124. +
  125. int zip(
  126. PGZ1 gz1,
  127. int in,
  128. @@ -9088,10 +9131,20 @@
  129. if ( len == (unsigned)(-1) || len == 0 )
  130. {
  131. gz1->crc = gz1->crc ^ 0xffffffffL;
  132. + /* XXX - Do we need to do something with Adler CRC's here?
  133. + * I don't think so--they don't seem to need postprocessing. */
  134. return (int)len;
  135. }
  136. - updcrc( gz1, (uch*)buf, len );
  137. + if (gz1->compression_format != DEFLATE_FORMAT)
  138. + {
  139. + updcrc( gz1, (uch*)buf, len );
  140. + }
  141. + else
  142. + {
  143. + gz1->adler = adler32(gz1->adler, (uch*)buf, len);
  144. + }
  145. +
  146. gz1->bytes_in += (ulg)len;
  147. return (int)len;
  148. @@ -9288,6 +9341,7 @@
  149. gz1->heap[k] = v;
  150. }
  151. +
  152. #define GZS_ZIP1 1
  153. #define GZS_ZIP2 2
  154. #define GZS_DEFLATE1 3
  155. @@ -9317,6 +9371,7 @@
  156. }
  157. gz1->decompress = gzp->decompress;
  158. + gz1->compression_format = gzp->compression_format;
  159. strcpy( gz1->ifname, gzp->input_filename );
  160. strcpy( gz1->ofname, gzp->output_filename );
  161. @@ -9489,6 +9544,7 @@
  162. return( rc );
  163. }
  164. +
  165. int gzs_zip1( PGZ1 gz1 )
  166. {
  167. uch flags = 0;
  168. @@ -9499,21 +9555,40 @@
  169. gz1->method = DEFLATED;
  170. - put_byte(GZIP_MAGIC[0]);
  171. - put_byte(GZIP_MAGIC[1]);
  172. - put_byte(DEFLATED);
  173. + if (gz1->compression_format != DEFLATE_FORMAT)
  174. + {
  175. + put_byte(GZIP_MAGIC[0]);
  176. + put_byte(GZIP_MAGIC[1]);
  177. + put_byte(DEFLATED);
  178. + }
  179. + else
  180. + {
  181. + /* Yes, I know RFC 1951 doesn't mention any header at the start of
  182. + * a deflated document, but zlib absolutely requires one. And since nearly
  183. + * all "deflate" implementations use zlib, we need to play along with this
  184. + * brain damage. */
  185. + put_byte(ZLIB_HEADER[0]);
  186. + put_byte(ZLIB_HEADER[1]);
  187. + }
  188. if ( gz1->save_orig_name )
  189. {
  190. flags |= ORIG_NAME;
  191. }
  192. - put_byte(flags);
  193. - put_long(gz1->time_stamp);
  194. -
  195. - gz1->crc = -1;
  196. + if (gz1->compression_format != DEFLATE_FORMAT)
  197. + {
  198. + put_byte(flags);
  199. + put_long(gz1->time_stamp);
  200. - updcrc( gz1, NULL, 0 );
  201. + gz1->crc = -1;
  202. + updcrc( gz1, NULL, 0 );
  203. + }
  204. + else
  205. + {
  206. + /* Deflate compression uses an Adler32 CRC, not a CRC32. */
  207. + gz1->adler = 1L;
  208. + }
  209. gz1->state = GZS_ZIP2;
  210. @@ -9529,18 +9604,20 @@
  211. bi_init( gz1, gz1->ofd );
  212. ct_init( gz1, &attr, &gz1->method );
  213. lm_init( gz1, gz1->level, &deflate_flags );
  214. - put_byte((uch)deflate_flags);
  215. -
  216. - put_byte(OS_CODE);
  217. - if ( gz1->save_orig_name )
  218. + if (gz1->compression_format != DEFLATE_FORMAT)
  219. {
  220. - char *p = gz1_basename( gz1, gz1->ifname );
  221. + put_byte((uch)deflate_flags);
  222. + put_byte(OS_CODE);
  223. + if ( gz1->save_orig_name )
  224. + {
  225. + char *p = gz1_basename( gz1, gz1->ifname );
  226. - do {
  227. - put_char(*p);
  228. + do {
  229. + put_char(*p);
  230. - } while (*p++);
  231. + } while (*p++);
  232. + }
  233. }
  234. gz1->header_bytes = (long)gz1->outcnt;
  235. @@ -9674,10 +9751,25 @@
  236. }
  237. #endif
  238. - put_long( gz1->crc );
  239. - put_long( gz1->bytes_in );
  240. -
  241. - gz1->header_bytes += 2*sizeof(long);
  242. + if (gz1->compression_format != DEFLATE_FORMAT)
  243. + {
  244. + put_long( gz1->crc );
  245. + put_long( gz1->bytes_in );
  246. + gz1->header_bytes += 2*sizeof(long);
  247. + }
  248. + else
  249. + {
  250. + /* Append an Adler32 CRC to our deflated data.
  251. + * Yes, I know RFC 1951 doesn't mention any CRC at the end of a
  252. + * deflated document, but zlib absolutely requires one. And since nearly
  253. + * all "deflate" implementations use zlib, we need to play along with this
  254. + * brain damage. */
  255. + put_byte( (gz1->adler >> 24) );
  256. + put_byte( (gz1->adler >> 16) & 0xFF );
  257. + put_byte( (gz1->adler >> 8) & 0xFF );
  258. + put_byte( (gz1->adler ) & 0xFF );
  259. + gz1->header_bytes += 4*sizeof(uch);
  260. + }
  261. flush_outbuf( gz1 );
  262. @@ -9685,6 +9777,67 @@
  263. return OK;
  264. }
  265. +
  266. +
  267. +/* =========================================================================
  268. + adler32 -- compute the Adler-32 checksum of a data stream
  269. + Copyright (C) 1995-1998 Mark Adler
  270. +
  271. + This software is provided 'as-is', without any express or implied
  272. + warranty. In no event will the authors be held liable for any damages
  273. + arising from the use of this software.
  274. +
  275. + Permission is granted to anyone to use this software for any purpose,
  276. + including commercial applications, and to alter it and redistribute it
  277. + freely, subject to the following restrictions:
  278. +
  279. + 1. The origin of this software must not be misrepresented; you must not
  280. + claim that you wrote the original software. If you use this software
  281. + in a product, an acknowledgment in the product documentation would be
  282. + appreciated but is not required.
  283. + 2. Altered source versions must be plainly marked as such, and must not be
  284. + misrepresented as being the original software.
  285. + 3. This notice may not be removed or altered from any source distribution.
  286. +
  287. + Modified by Eric Kidd <eric.kidd@pobox.com> to play nicely with mod_gzip.
  288. + */
  289. +
  290. +#define BASE 65521L /* largest prime smaller than 65536 */
  291. +#define NMAX 5552
  292. +/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */
  293. +
  294. +#define DO1(buf,i) {s1 += buf[i]; s2 += s1;}
  295. +#define DO2(buf,i) DO1(buf,i); DO1(buf,i+1);
  296. +#define DO4(buf,i) DO2(buf,i); DO2(buf,i+2);
  297. +#define DO8(buf,i) DO4(buf,i); DO4(buf,i+4);
  298. +#define DO16(buf) DO8(buf,0); DO8(buf,8);
  299. +
  300. +ulg adler32(ulg adler, uch *buf, unsigned len)
  301. +{
  302. + unsigned long s1 = adler & 0xffff;
  303. + unsigned long s2 = (adler >> 16) & 0xffff;
  304. + int k;
  305. +
  306. + if (buf == NULL) return 1L;
  307. +
  308. + while (len > 0) {
  309. + k = len < NMAX ? len : NMAX;
  310. + len -= k;
  311. + while (k >= 16) {
  312. + DO16(buf);
  313. + buf += 16;
  314. + k -= 16;
  315. + }
  316. + if (k != 0) do {
  317. + s1 += *buf++;
  318. + s2 += s1;
  319. + } while (--k);
  320. + s1 %= BASE;
  321. + s2 %= BASE;
  322. + }
  323. + return (s2 << 16) | s1;
  324. +}
  325. +
  326. /* END OF FILE */