From: Jim Jagielski Date: Sun, 7 Jul 2013 13:51:48 +0000 (+0000) Subject: Merge r1484832, r1484914 from trunk: X-Git-Tag: 2.4.5~28 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=c9bdb2b3d4252f84d00f04a0b91b308728f121a3;p=apache Merge r1484832, r1484914 from trunk: mod_deflate: Remove assumptions as to when an EOS bucket might arrive. Gracefully step aside if the body size is zero. mod_deflate: Make sure we process any EOS bucket in our brigade and save going the long way round. Submitted by: minfrin Reviewed/backported by: jim git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1500429 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/CHANGES b/CHANGES index 4ddbde0587..6cf9cd9b74 100644 --- a/CHANGES +++ b/CHANGES @@ -2,6 +2,9 @@ Changes with Apache 2.4.5 + *) mod_deflate: Remove assumptions as to when an EOS bucket might arrive. + Gracefully step aside if the body size is zero. [Graham Leggett] + *) mod_session_dbd: Make sure that dirty flag is respected when saving sessions, and ensure the session ID is changed each time the session changes. [Takashi Sato , Graham Leggett] diff --git a/STATUS b/STATUS index 8a3d7840de..371ae12c48 100644 --- a/STATUS +++ b/STATUS @@ -91,27 +91,6 @@ RELEASE SHOWSTOPPERS: PATCHES ACCEPTED TO BACKPORT FROM TRUNK: [ start all new proposals below, under PATCHES PROPOSED. ] - * mod_deflate: Remove assumptions as to when an EOS bucket might arrive. - Gracefully step aside if the body size is zero. - trunk patch: http://svn.apache.org/r1484832 - http://svn.apache.org/r1484914 - 2.4.x patch: trunk works, modulo CHANGES - +1: minfrin, jim, sf - sf: The check for data after the compressed stream does not work - (see commented out test in r1499704). - But I think this can be fixed/removed later and vote +1 to get - the other fixes into 2.4.5. - - * mod_session_dbd: Make sure that dirty flag is respected when saving - sessions, and ensure the session ID is changed each time the session - changes. - trunk patch: http://svn.apache.org/r1488158 - trunk patch: http://svn.apache.org/r1488164 - 2.4.x patch: trunk patch works modulo CHANGES - +1: minfrin, jim, sf - sf says: Something like this should be added to CHANGES: - This changes the format of the updatesession SQL statement. Existing - configurations must be changed. PATCHES PROPOSED TO BACKPORT FROM TRUNK: diff --git a/modules/filters/mod_deflate.c b/modules/filters/mod_deflate.c index 48d37b1392..79f6f8d1ca 100644 --- a/modules/filters/mod_deflate.c +++ b/modules/filters/mod_deflate.c @@ -304,8 +304,9 @@ typedef struct deflate_ctx_t int (*libz_end_func)(z_streamp); unsigned char *validation_buffer; apr_size_t validation_buffer_length; - int inflate_init; - int filter_init; + unsigned int inflate_init:1; + unsigned int filter_init:1; + unsigned int done:1; } deflate_ctx; /* Number of validation bytes (CRC and length) after the compressed data */ @@ -942,6 +943,13 @@ static apr_status_t deflate_in_filter(ap_filter_t *f, return rv; } + /* zero length body? step aside */ + bkt = APR_BRIGADE_FIRST(ctx->bb); + if (APR_BUCKET_IS_EOS(bkt)) { + ap_remove_input_filter(f); + return ap_get_brigade(f->next, bb, mode, block, readbytes); + } + apr_table_unset(r->headers_in, "Content-Length"); apr_table_unset(r->headers_in, "Content-MD5"); @@ -1002,12 +1010,19 @@ static apr_status_t deflate_in_filter(ap_filter_t *f, const char *data; apr_size_t len; - /* If we actually see the EOS, that means we screwed up! */ if (APR_BUCKET_IS_EOS(bkt)) { - inflateEnd(&ctx->stream); - ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01390) - "Encountered EOS bucket in inflate filter (bug?)"); - return APR_EGENERAL; + if (!ctx->done) { + inflateEnd(&ctx->stream); + ap_log_rerror( + APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02481) "Encountered premature end-of-stream while inflating"); + return APR_EGENERAL; + } + + /* Move everything to the returning brigade. */ + APR_BUCKET_REMOVE(bkt); + APR_BRIGADE_INSERT_TAIL(ctx->proc_bb, bkt); + ap_remove_input_filter(f); + break; } if (APR_BUCKET_IS_FLUSH(bkt)) { @@ -1036,6 +1051,13 @@ static apr_status_t deflate_in_filter(ap_filter_t *f, break; } + /* sanity check - data after completed compressed body and before eos? */ + if (ctx->done) { + ap_log_rerror( + APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02482) "Encountered extra data after compressed data"); + return APR_EGENERAL; + } + /* read */ apr_bucket_read(bkt, &data, &len, APR_BLOCK_READ); @@ -1073,7 +1095,7 @@ static apr_status_t deflate_in_filter(ap_filter_t *f, } } if (zRC == Z_STREAM_END) { - apr_bucket *tmp_heap, *eos; + apr_bucket *tmp_heap; ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01393) "Zlib: Inflated %ld to %ld : URL %s", @@ -1120,9 +1142,7 @@ static apr_status_t deflate_in_filter(ap_filter_t *f, inflateEnd(&ctx->stream); - eos = apr_bucket_eos_create(f->c->bucket_alloc); - APR_BRIGADE_INSERT_TAIL(ctx->proc_bb, eos); - break; + ctx->done = 1; } } @@ -1356,7 +1376,8 @@ static apr_status_t inflate_out_filter(ap_filter_t *f, apr_bucket_read(e, &data, &len, APR_BLOCK_READ); /* first bucket contains zlib header */ - if (!ctx->inflate_init++) { + if (!ctx->inflate_init) { + ctx->inflate_init = 1; if (len < 10) { ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01403) "Insufficient data for inflate");