Commit d1760ca3 authored by Greg Ames's avatar Greg Ames
Browse files

PR 45687: Detect and pass along error buckets

Submitted by: Dan Poirier <poirier pobox.org> 
Reviewed by:  trawick


git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@692567 13f79535-47bb-0310-9956-ffa450edef68
parent d117806a
Loading
Loading
Loading
Loading
+44 −4
Changes for modules/filters/mod_charset_lite.c: 44 added lines, 4 removed lines.
Original line number Diff line number Diff line
@@ -414,6 +414,23 @@ static apr_status_t send_eos(ap_filter_t *f)
    return rv;
}

static apr_status_t send_bucket_downstream(ap_filter_t *f, apr_bucket *b)
{
    request_rec *r = f->r;
    conn_rec *c = r->connection;
    apr_bucket_brigade *bb;
    charset_filter_ctx_t *ctx = f->ctx;
    apr_status_t rv;

    bb = apr_brigade_create(r->pool, c->bucket_alloc);
    APR_BRIGADE_INSERT_TAIL(bb, b);
    rv = ap_pass_brigade(f->next, bb);
    if (rv != APR_SUCCESS) {
        ctx->ees = EES_DOWNSTREAM;
    }
    return rv;
}

static apr_status_t set_aside_partial_char(charset_filter_ctx_t *ctx,
                                           const char *partial,
                                           apr_size_t partial_len)
@@ -632,12 +649,12 @@ static void chk_filter_chain(ap_filter_t *f)
 * we'll stop when one of the following occurs:
 * . we run out of buckets
 * . we run out of space in the output buffer
 * . we hit an error
 * . we hit an error or metadata
 *
 * inputs:
 *   bb:               brigade to process
 *   buffer:           storage to hold the translated characters
 *   buffer_size:      size of buffer
 *   buffer_avail:     size of buffer
 *   (and a few more uninteresting parms)
 *
 * outputs:
@@ -646,7 +663,7 @@ static void chk_filter_chain(ap_filter_t *f)
 *                     translated characters; the eos bucket, if
 *                     present, will be left in the brigade
 *   buffer:           filled in with translated characters
 *   buffer_size:      updated with the bytes remaining
 *   buffer_avail:     updated with the bytes remaining
 *   hit_eos:          did we hit an EOS bucket?
 */
static apr_status_t xlate_brigade(charset_filter_ctx_t *ctx,
@@ -673,7 +690,7 @@ static apr_status_t xlate_brigade(charset_filter_ctx_t *ctx,
            }
            b = APR_BRIGADE_FIRST(bb);
            if (b == APR_BRIGADE_SENTINEL(bb) ||
                APR_BUCKET_IS_EOS(b)) {
                APR_BUCKET_IS_METADATA(b)) {
                break;
            }
            rv = apr_bucket_read(b, &bucket, &bytes_in_bucket, APR_BLOCK_READ);
@@ -892,6 +909,17 @@ static apr_status_t xlate_out_filter(ap_filter_t *f, apr_bucket_brigade *bb)
                }
                break;
            }
            if (APR_BUCKET_IS_METADATA(dptr)) {
                apr_bucket *metadata_bucket;
                metadata_bucket = dptr;
                dptr = APR_BUCKET_NEXT(dptr);
                APR_BUCKET_REMOVE(metadata_bucket);
                rv = send_bucket_downstream(f, metadata_bucket);
                if (rv != APR_SUCCESS) {
                    done = 1;
                }
                continue;
            }
            rv = apr_bucket_read(dptr, &cur_str, &cur_len, APR_BLOCK_READ);
            if (rv != APR_SUCCESS) {
                done = 1;
@@ -1078,6 +1106,18 @@ static int xlate_in_filter(ap_filter_t *f, apr_bucket_brigade *bb,
             * empty brigade
             */
        }
        /* If we have any metadata at the head of ctx->bb, go ahead and move it
         * onto the end of bb to be returned to our caller.
         */
        if (!APR_BRIGADE_EMPTY(ctx->bb)) {
            apr_bucket *b = APR_BRIGADE_FIRST(ctx->bb);
            while (b != APR_BRIGADE_SENTINEL(ctx->bb)
                   && APR_BUCKET_IS_METADATA(b)) {
                APR_BUCKET_REMOVE(b);
                APR_BRIGADE_INSERT_TAIL(bb, b);
                b = APR_BRIGADE_FIRST(ctx->bb);
            }
        }
    }
    else {
        log_xlate_error(f, rv);