From: Graham Leggett Date: Thu, 9 Jun 2011 23:41:00 +0000 (+0000) Subject: For safety, pass trailing buckets following EOS down the stack. Pass flush X-Git-Tag: 2.3.13~64 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d39848b2b57c0f443c704f02d62c9ec47ad44c97;p=thirdparty%2Fapache%2Fhttpd.git For safety, pass trailing buckets following EOS down the stack. Pass flush buckets down the stack immediately. Move apr_brigade_partition() to be called as late as possible. git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1134130 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/modules/filters/mod_data.c b/modules/filters/mod_data.c index 7798a348335..0688f8622a5 100644 --- a/modules/filters/mod_data.c +++ b/modules/filters/mod_data.c @@ -64,7 +64,7 @@ typedef struct data_ctx */ static apr_status_t data_out_filter(ap_filter_t *f, apr_bucket_brigade *bb) { - apr_bucket *e; + apr_bucket *e, *ee; request_rec *r = f->r; data_ctx *ctx = f->ctx; apr_status_t rv = APR_SUCCESS; @@ -134,9 +134,6 @@ static apr_status_t data_out_filter(ap_filter_t *f, apr_bucket_brigade *bb) char buffer[APR_BUCKET_BUFF_SIZE + 1]; char encoded[((sizeof(ctx->overflow)) / 3) * 4 + 1]; - /* make sure we don't read more than 6000 bytes at a time */ - apr_brigade_partition(bb, (APR_BUCKET_BUFF_SIZE / 4 * 3), &e); - e = APR_BRIGADE_FIRST(bb); /* EOS means we are done. */ @@ -157,6 +154,23 @@ static apr_status_t data_out_filter(ap_filter_t *f, apr_bucket_brigade *bb) /* pass what we have down the chain */ ap_remove_output_filter(f); rv = ap_pass_brigade(f->next, ctx->bb); + + /* pass any stray buckets after the EOS down the stack */ + if ((APR_SUCCESS == rv) && (!APR_BRIGADE_EMPTY(bb))) { + rv = ap_pass_brigade(f->next, bb); + } + continue; + } + + /* flush what we can, we can't flush the tail until EOS */ + if (APR_BUCKET_IS_FLUSH(e)) { + + /* pass the flush bucket across */ + APR_BUCKET_REMOVE(e); + APR_BRIGADE_INSERT_TAIL(ctx->bb, e); + + /* pass what we have down the chain */ + rv = ap_pass_brigade(f->next, ctx->bb); continue; } @@ -171,6 +185,9 @@ static apr_status_t data_out_filter(ap_filter_t *f, apr_bucket_brigade *bb) continue; } + /* make sure we don't read more than 6000 bytes at a time */ + apr_brigade_partition(bb, (APR_BUCKET_BUFF_SIZE / 4 * 3), &ee); + /* size will never be more than 6000 bytes */ if (APR_SUCCESS == (rv = apr_bucket_read(e, &data, &size, APR_BLOCK_READ))) {