libapreq2

 view release on metacpan or  search on metacpan

module/apache2/filter.c  view on Meta::CPAN

            ctx->parser->temp_dir = ctx->temp_dir;
        if (ctx->hook_queue != NULL)
            apreq_parser_add_hook(ctx->parser, ctx->hook_queue);
    }

    ctx->hook_queue = NULL;
    ctx->bb    = apr_brigade_create(r->pool, ba);
    ctx->bbtmp = apr_brigade_create(r->pool, ba);
    ctx->spool = apr_brigade_create(r->pool, ba);
    ctx->body  = apr_table_make(r->pool, APREQ_DEFAULT_NELTS);
    ctx->body_status = APR_INCOMPLETE;
}


/*
 * Situations to contend with:
 *
 * 1) Often the filter will be added by the content handler itself,
 *    so the apreq_filter_init hook will not be run.
 * 2) If an auth handler uses apreq, the apreq_filter will ensure
 *    it's part of the protocol filters.  apreq_filter_init does NOT need
 *    to notify the protocol filter that it must not continue parsing,
 *    the apreq filter can perform this check itself.  apreq_filter_init
 *    just needs to ensure cfg->f does not point at it.
 * 3) If req->proto_input_filters and req->input_filters are apreq
 *    filters, and req->input_filters->next == req->proto_input_filters,
 *    it is safe for apreq_filter to "steal" the proto filter's context
 *    and subsequently drop it from the chain.
 */


/* Examines the input_filter chain and moves the apreq filter(s) around
 * before the filter chain is stacked by ap_get_brigade.
 */


static apr_status_t apreq_filter_init(ap_filter_t *f)
{
    request_rec *r = f->r;
    struct filter_ctx *ctx = f->ctx;
    struct apache2_handle *handle =
        (struct apache2_handle *)apreq_handle_apache2(r);

    /* Don't parse GET (this protects against subrequest body parsing). */
    if (f->r->method_number == M_GET)
        return APR_SUCCESS;

    if (ctx == NULL || ctx->body_status == APR_EINIT) {
        if (f == r->input_filters) {
            handle->f = f;
        }
        else if (r->input_filters->frec->filter_func.in_func == apreq_filter) {
            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, APR_SUCCESS, r,
                          "removing intermediate apreq filter");
            if (handle->f == f)
                handle->f = r->input_filters;
            ap_remove_input_filter(f);
        }
        else {
            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, APR_SUCCESS, r,
                          "relocating intermediate apreq filter");
            apreq_filter_relocate(f);
            handle->f = f;
        }
        return APR_SUCCESS;
    }

    /* else this is a protocol filter which may still be active.
     * if it is, we must deregister it now.
     */
    if (handle->f == f) {
        ap_log_rerror(APLOG_MARK, APLOG_DEBUG, APR_SUCCESS, r,
                     "disabling stale protocol filter");
        if (ctx->body_status == APR_INCOMPLETE)
            ctx->body_status = APREQ_ERROR_INTERRUPT;
        handle->f = NULL;
    }
    return APR_SUCCESS;
}



apr_status_t apreq_filter_prefetch(ap_filter_t *f, apr_off_t readbytes)
{
    struct filter_ctx *ctx = f->ctx;
    request_rec *r = f->r;
    apr_status_t rv;
    apr_off_t len;

    if (ctx->body_status == APR_EINIT)
        apreq_filter_init_context(f);

    if (ctx->body_status != APR_INCOMPLETE || readbytes == 0)
        return ctx->body_status;

    ap_log_rerror(APLOG_MARK, APLOG_DEBUG, APR_SUCCESS, r,
                  "prefetching %" APR_OFF_T_FMT " bytes", readbytes);

    rv = ap_get_brigade(f->next, ctx->bb, AP_MODE_READBYTES,
                       APR_BLOCK_READ, readbytes);

    if (rv != APR_SUCCESS) {
        ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r,
                      "ap_get_brigade failed during prefetch");
        ctx->filter_error = rv;
        return ctx->body_status = APREQ_ERROR_GENERAL;
    }

    apreq_brigade_setaside(ctx->bb, r->pool);
    apreq_brigade_copy(ctx->bbtmp, ctx->bb);

    rv = apreq_brigade_concat(r->pool, ctx->temp_dir, ctx->brigade_limit,
                              ctx->spool, ctx->bbtmp);
    if (rv != APR_SUCCESS && rv != APR_EOF) {
        ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r,
                      "apreq_brigade_concat failed; TempDir problem?");
        ctx->filter_error = APR_EGENERAL;
        return ctx->body_status = rv;
    }

    /* Adding "f" to the protocol filter chain ensures the
     * spooled data is preserved across internal redirects.



( run in 0.506 second using v1.01-cache-2.11-cpan-5b529ec07f3 )