Commit 9be56a70 authored by Paul Querna's avatar Paul Querna
Browse files

core_input_filter: Stop leaking a brigade by moving buckets to an existing...

core_input_filter: Stop leaking a brigade by moving buckets to an existing brigade instead of calling brigade_split.

PR: 33382
Reviewed By: Justin Erenkrantz, Jeff Trawick


git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.0.x@155391 13f79535-47bb-0310-9956-ffa450edef68
parent 73961d8d
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
Changes with Apache 2.0.54
  *) core_input_filter: Move buckets to a persistent brigade instead of
     creating a new brigade. This stop a memory leak when proxying a 
     Streaming Media Server. PR 33382. [Paul Querna]
  *) mod_win32: Ignore both PATH_INFO as well as PATH_TRANSLATED to avoid 
     hiccups from additional path information passed in non-utf-8 format.
     [Richard Donkin <rd9 donkin.org]
+0 −6
Original line number Diff line number Diff line
@@ -94,12 +94,6 @@ PATCHES TO BACKPORT FROM TRUNK:
    identify exactly what the proposed changes are! ]
  [ please append new backports at the end of this list not the top. ]

    *) core_input_filter: Fix leak of a brigade by moving buckets to an 
       existing brigade instead of calling brigade_split which creates a 
       new brigade. PR 33382. r154200
       Patch for 2.0: http://www.apache.org/~pquerna/c-i-f-leak.patch
       +1: pquerna, trawick, jerenkrantz

    *) mod_ssl: Set r->user from SSLUsername earlier so that it's
       actually useful.
       http://svn.apache.org/viewcvs.cgi?rev=153280&view=rev
+1 −0
Original line number Diff line number Diff line
@@ -1100,6 +1100,7 @@ typedef struct core_output_filter_ctx {
 
typedef struct core_filter_ctx {
    apr_bucket_brigade *b;
    apr_bucket_brigade *tmpbb;
} core_ctx_t;
 
typedef struct core_net_rec {
+26 −4
Original line number Diff line number Diff line
@@ -3674,6 +3674,28 @@ do { \
    } while (!APR_BRIGADE_EMPTY(b) && (e != APR_BRIGADE_SENTINEL(b))); \
} while (0)


/**
 * Split the contents of a brigade after bucket 'e' to an existing brigade
 *
 * XXXX: Should this function be added to APR-Util?
 */
static void brigade_move(apr_bucket_brigade *b, apr_bucket_brigade *a,
                         apr_bucket *e)
{
    apr_bucket *f;     

    if (e != APR_BRIGADE_SENTINEL(b)) {
        f = APR_RING_LAST(&b->list);
        APR_RING_UNSPLICE(e, f, link);
        APR_RING_SPLICE_HEAD(&a->list, e, f, apr_bucket, link);
    }

    APR_BRIGADE_CHECK_CONSISTENCY(a);
    APR_BRIGADE_CHECK_CONSISTENCY(b);
}


static int core_input_filter(ap_filter_t *f, apr_bucket_brigade *b,
                             ap_input_mode_t mode, apr_read_type_e block,
                             apr_off_t readbytes)
@@ -3703,6 +3725,7 @@ static int core_input_filter(ap_filter_t *f, apr_bucket_brigade *b,
    {
        ctx = apr_pcalloc(f->c->pool, sizeof(*ctx));
        ctx->b = apr_brigade_create(f->c->pool, f->c->bucket_alloc);
        ctx->tmpbb = apr_brigade_create(ctx->b->p, ctx->b->bucket_alloc);

        /* seed the brigade with the client socket. */
        e = apr_bucket_socket_create(net->client_socket, f->c->bucket_alloc);
@@ -3814,7 +3837,6 @@ static int core_input_filter(ap_filter_t *f, apr_bucket_brigade *b,
    /* read up to the amount they specified. */
    if (mode == AP_MODE_READBYTES || mode == AP_MODE_SPECULATIVE) {
        apr_bucket *e;
        apr_bucket_brigade *newbb;

        AP_DEBUG_ASSERT(readbytes > 0);

@@ -3855,8 +3877,8 @@ static int core_input_filter(ap_filter_t *f, apr_bucket_brigade *b,
            return rv;
        }

        /* Must do split before CONCAT */
        newbb = apr_brigade_split(ctx->b, e);
        /* Must do move before CONCAT */
        brigade_move(ctx->b, ctx->tmpbb, e);

        if (mode == AP_MODE_READBYTES) {
            APR_BRIGADE_CONCAT(b, ctx->b);
@@ -3873,7 +3895,7 @@ static int core_input_filter(ap_filter_t *f, apr_bucket_brigade *b,
        }

        /* Take what was originally there and place it back on ctx->b */
        APR_BRIGADE_CONCAT(ctx->b, newbb);
        APR_BRIGADE_CONCAT(ctx->b, ctx->tmpbb);
    }
    return APR_SUCCESS;
}