Commit a506ad53 authored by Graham Leggett's avatar Graham Leggett
Browse files

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
parent aa0e95ad
Loading
Loading
Loading
Loading
+21 −4
Changes for modules/filters/mod_data.c: 21 added lines, 4 removed lines.
Original line number Diff line number Diff line
@@ -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))) {