@@ -412,13 +412,18 @@ typedef struct deflate_ctx_t
412412
413413/* Number of validation bytes (CRC and length) after the compressed data */
414414#define VALIDATION_SIZE 8
415+
415416/* Do not update ctx->crc, see comment in flush_libz_buffer */
416- #define NO_UPDATE_CRC 0
417+ #define NO_UPDATE_CRC 0x0
417418/* Do update ctx->crc, see comment in flush_libz_buffer */
418- #define UPDATE_CRC 1
419+ #define UPDATE_CRC 0x1
420+ /* Use a transient bucket, which is ONLY safe if the bucket will be
421+ * passed down the filter chain immediately before the zlib stream is
422+ * used again. */
423+ #define TRANSIENT 0x2
419424
420425static void consume_buffer (deflate_ctx * ctx , deflate_filter_config * c ,
421- int len , int crc , apr_bucket_brigade * bb )
426+ int len , unsigned int flags , apr_bucket_brigade * bb )
422427{
423428 apr_bucket * b ;
424429
@@ -427,12 +432,16 @@ static void consume_buffer(deflate_ctx *ctx, deflate_filter_config *c,
427432 * inflate action where we need to do a crc on the output, whereas
428433 * in the deflate case we need to do a crc on the input
429434 */
430- if (crc ) {
435+ if (flags & UPDATE_CRC ) {
431436 ctx -> crc = crc32 (ctx -> crc , (const Bytef * )ctx -> buffer , len );
432437 }
433438
434- b = apr_bucket_heap_create ((char * )ctx -> buffer , len , NULL ,
435- bb -> bucket_alloc );
439+ if (flags & TRANSIENT )
440+ b = apr_bucket_transient_create ((char * )ctx -> buffer , len ,
441+ bb -> bucket_alloc );
442+ else
443+ b = apr_bucket_heap_create ((char * )ctx -> buffer , len , NULL ,
444+ bb -> bucket_alloc );
436445 APR_BRIGADE_INSERT_TAIL (bb , b );
437446
438447 ctx -> stream .next_out = ctx -> buffer ;
@@ -441,7 +450,7 @@ static void consume_buffer(deflate_ctx *ctx, deflate_filter_config *c,
441450
442451static int flush_libz_buffer (deflate_ctx * ctx , deflate_filter_config * c ,
443452 int (* libz_func )(z_streamp , int ), int flush ,
444- int crc )
453+ unsigned int flags )
445454{
446455 int zRC = Z_OK ;
447456 int done = 0 ;
@@ -450,7 +459,7 @@ static int flush_libz_buffer(deflate_ctx *ctx, deflate_filter_config *c,
450459 for (;;) {
451460 deflate_len = c -> bufferSize - ctx -> stream .avail_out ;
452461 if (deflate_len > 0 ) {
453- consume_buffer (ctx , c , deflate_len , crc , ctx -> bb );
462+ consume_buffer (ctx , c , deflate_len , flags , ctx -> bb );
454463 }
455464
456465 if (done )
@@ -1019,7 +1028,10 @@ static apr_status_t deflate_out_filter(ap_filter_t *f,
10191028
10201029 while (ctx -> stream .avail_in != 0 ) {
10211030 if (ctx -> stream .avail_out == 0 ) {
1022- consume_buffer (ctx , c , c -> bufferSize , NO_UPDATE_CRC , ctx -> bb );
1031+ /* Use a transient bucket since it will be sent down
1032+ * the filter chain immediately. */
1033+ consume_buffer (ctx , c , c -> bufferSize ,
1034+ NO_UPDATE_CRC |TRANSIENT , ctx -> bb );
10231035
10241036 /* Send what we have right now to the next filter. */
10251037 rv = ap_pass_brigade (f -> next , ctx -> bb );
@@ -1840,7 +1852,10 @@ static apr_status_t inflate_out_filter(ap_filter_t *f,
18401852
18411853 while (ctx -> stream .avail_in != 0 ) {
18421854 if (ctx -> stream .avail_out == 0 ) {
1843- consume_buffer (ctx , c , c -> bufferSize , UPDATE_CRC , ctx -> bb );
1855+ /* Use a transient bucket since it will be sent down
1856+ * the filter chain immediately. */
1857+ consume_buffer (ctx , c , c -> bufferSize ,
1858+ UPDATE_CRC |TRANSIENT , ctx -> bb );
18441859
18451860 /* Send what we have right now to the next filter. */
18461861 rv = ap_pass_brigade (f -> next , ctx -> bb );
0 commit comments