From: Jeff Trawick Date: Mon, 27 Aug 2001 20:48:00 +0000 (+0000) Subject: Fix a growing connection pool in core_output_filter() for X-Git-Tag: 2.0.25~22 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=9855487db69acb8118c43d4ac4baeff0fa73058f;p=thirdparty%2Fapache%2Fhttpd.git Fix a growing connection pool in core_output_filter() for keepalive requests. We were allocating a brigade out of the connection pool; the number of these brigades allocated per connection was theoretically unlimited. git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@90736 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/CHANGES b/CHANGES index d6a0ca63cbd..76606e3d339 100644 --- a/CHANGES +++ b/CHANGES @@ -1,8 +1,12 @@ Changes with Apache 2.0.25-dev + + *) Fix a growing connection pool in core_output_filter() for + keepalive requests. [Jeff Trawick] + *) Moved split_and_pass_pretag_buckets back to being a macro at Ryans's request. Removed the return from it by setting and returning a return code instead. Updated - the code to check the return code from teh macro and + the code to check the return code from the macro and do the right thing. [Paul J. Reder] *) Fix a segfault when a numeric value was received for Host:. diff --git a/server/core.c b/server/core.c index cd5d09ddd12..63c4dc9cba2 100644 --- a/server/core.c +++ b/server/core.c @@ -3070,6 +3070,10 @@ static int core_input_filter(ap_filter_t *f, apr_bucket_brigade *b, ap_input_mod */ typedef struct CORE_OUTPUT_FILTER_CTX { apr_bucket_brigade *b; + apr_pool_t *subpool; /* subpool of c->pool used for data saved after a + * request is finished + */ + int subpool_has_stuff; /* anything in the subpool? */ } core_output_filter_ctx_t; #define MAX_IOVEC_TO_WRITE 16 @@ -3191,6 +3195,11 @@ static apr_status_t core_output_filter(ap_filter_t *f, apr_bucket_brigade *b) if ((!fd && !more && (nbytes + flen < AP_MIN_BYTES_TO_WRITE) && !APR_BUCKET_IS_FLUSH(last_e)) || (nbytes + flen < AP_MIN_BYTES_TO_WRITE && APR_BUCKET_IS_EOS(last_e) && c->keepalive)) { + + if (ctx->subpool == NULL) { + apr_pool_create(&ctx->subpool, f->c->pool); + } + /* NEVER save an EOS in here. If we are saving a brigade with * an EOS bucket, then we are doing keepalive connections, and * we want to process to second request fully. @@ -3202,7 +3211,7 @@ static apr_status_t core_output_filter(ap_filter_t *f, apr_bucket_brigade *b) * after the request_pool is cleared. */ if (ctx->b == NULL) { - ctx->b = apr_brigade_create(f->c->pool); + ctx->b = apr_brigade_create(ctx->subpool); } APR_BRIGADE_FOREACH(bucket, b) { @@ -3227,11 +3236,13 @@ static apr_status_t core_output_filter(ap_filter_t *f, apr_bucket_brigade *b) return rv; } apr_brigade_write(ctx->b, NULL, NULL, str, n); + ctx->subpool_has_stuff = 1; } apr_brigade_destroy(b); } else { - ap_save_brigade(f, &ctx->b, &b, c->pool); + ap_save_brigade(f, &ctx->b, &b, ctx->subpool); + ctx->subpool_has_stuff = 1; } return APR_SUCCESS; } @@ -3305,6 +3316,11 @@ static apr_status_t core_output_filter(ap_filter_t *f, apr_bucket_brigade *b) more = NULL; } /* end while () */ + if (ctx->subpool && ctx->subpool_has_stuff) { + apr_pool_clear(ctx->subpool); + ctx->subpool_has_stuff = 0; + } + return APR_SUCCESS; }