Commit 10eac7c0 authored by Jeff Trawick's avatar Jeff Trawick
Browse files

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
parent cd07c612
Loading
Loading
Loading
Loading
+5 −1
Original line number Diff line number Diff line
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:.
+18 −2
Original line number Diff line number Diff line
@@ -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;
}