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 )