summaryrefslogtreecommitdiff
path: root/server/util_filter.c
diff options
context:
space:
mode:
authorGraham Leggett <minfrin@apache.org>2016-03-12 00:43:58 +0000
committerGraham Leggett <minfrin@apache.org>2016-03-12 00:43:58 +0000
commit64eaf888e9208f6ae0370812de7746ea94099588 (patch)
tree84c5be5a3b5b8115363a475b7de198302785704c /server/util_filter.c
parent9fbfe2fc9060a9c464e56499ae68693d01210801 (diff)
downloadhttpd-64eaf888e9208f6ae0370812de7746ea94099588.tar.gz
core: Extend support for setting aside data from the network input filter
to any connection or request input filter. git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1734656 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'server/util_filter.c')
-rw-r--r--server/util_filter.c82
1 files changed, 63 insertions, 19 deletions
diff --git a/server/util_filter.c b/server/util_filter.c
index aaf0173a5a..b3ea895b95 100644
--- a/server/util_filter.c
+++ b/server/util_filter.c
@@ -209,6 +209,7 @@ static ap_filter_rec_t *register_filter(const char *name,
ap_filter_func filter_func,
ap_init_filter_func filter_init,
ap_filter_type ftype,
+ ap_filter_direction_e direction,
filter_trie_node **reg_filter_set)
{
ap_filter_rec_t *frec;
@@ -242,6 +243,7 @@ static ap_filter_rec_t *register_filter(const char *name,
frec->filter_func = filter_func;
frec->filter_init_func = filter_init;
frec->ftype = ftype;
+ frec->direction = direction;
apr_pool_cleanup_register(FILTER_POOL, NULL, filter_cleanup,
apr_pool_cleanup_null);
@@ -255,7 +257,7 @@ AP_DECLARE(ap_filter_rec_t *) ap_register_input_filter(const char *name,
{
ap_filter_func f;
f.in_func = filter_func;
- return register_filter(name, f, filter_init, ftype,
+ return register_filter(name, f, filter_init, ftype, AP_FILTER_INPUT,
&registered_input_filters);
}
@@ -278,7 +280,7 @@ AP_DECLARE(ap_filter_rec_t *) ap_register_output_filter_protocol(
ap_filter_rec_t* ret ;
ap_filter_func f;
f.out_func = filter_func;
- ret = register_filter(name, f, filter_init, ftype,
+ ret = register_filter(name, f, filter_init, ftype, AP_FILTER_OUTPUT,
&registered_output_filters);
ret->proto_flags = proto_flags ;
return ret ;
@@ -702,6 +704,33 @@ static apr_status_t filters_cleanup(void *data)
return APR_SUCCESS;
}
+AP_DECLARE(int) ap_filter_prepare_brigade(ap_filter_t *f, apr_pool_t **p)
+{
+ apr_pool_t *pool;
+ ap_filter_t **key;
+
+ if (!f->bb) {
+
+ pool = f->r ? f->r->pool : f->c->pool;
+
+ key = apr_palloc(pool, sizeof(ap_filter_t **));
+ *key = f;
+ apr_hash_set(f->c->filters, key, sizeof(ap_filter_t **), f);
+
+ f->bb = apr_brigade_create(pool, f->c->bucket_alloc);
+
+ apr_pool_pre_cleanup_register(pool, key, filters_cleanup);
+
+ if (p) {
+ *p = pool;
+ }
+
+ return OK;
+ }
+
+ return DECLINED;
+}
+
AP_DECLARE(apr_status_t) ap_filter_setaside_brigade(ap_filter_t *f,
apr_bucket_brigade *bb)
{
@@ -716,24 +745,11 @@ AP_DECLARE(apr_status_t) ap_filter_setaside_brigade(ap_filter_t *f,
}
if (!APR_BRIGADE_EMPTY(bb)) {
- apr_pool_t *pool;
+ apr_pool_t *pool = NULL;
/*
* Set aside the brigade bb within f->bb.
*/
- if (!f->bb) {
- ap_filter_t **key;
-
- pool = f->r ? f->r->pool : f->c->pool;
-
- key = apr_palloc(pool, sizeof(ap_filter_t **));
- *key = f;
- apr_hash_set(f->c->filters, key, sizeof(ap_filter_t **), f);
-
- f->bb = apr_brigade_create(pool, f->c->bucket_alloc);
-
- apr_pool_pre_cleanup_register(pool, key, filters_cleanup);
-
- }
+ ap_filter_prepare_brigade(f, &pool);
/* decide what pool we setaside to, request pool or deferred pool? */
if (f->r) {
@@ -953,7 +969,7 @@ AP_DECLARE(int) ap_filter_should_yield(ap_filter_t *f)
return 0;
}
-AP_DECLARE(int) ap_filter_complete_connection(conn_rec *c)
+AP_DECLARE(int) ap_filter_output_pending(conn_rec *c)
{
apr_hash_index_t *rindex;
int data_in_output_filters = DECLINED;
@@ -962,7 +978,8 @@ AP_DECLARE(int) ap_filter_complete_connection(conn_rec *c)
while (rindex) {
ap_filter_t *f = apr_hash_this_val(rindex);
- if (!APR_BRIGADE_EMPTY(f->bb)) {
+ if (f->frec->direction == AP_FILTER_OUTPUT && f->bb
+ && !APR_BRIGADE_EMPTY(f->bb)) {
apr_status_t rv;
@@ -986,6 +1003,33 @@ AP_DECLARE(int) ap_filter_complete_connection(conn_rec *c)
return data_in_output_filters;
}
+AP_DECLARE(int) ap_filter_input_pending(conn_rec *c)
+{
+ apr_hash_index_t *rindex;
+
+ rindex = apr_hash_first(NULL, c->filters);
+ while (rindex) {
+ ap_filter_t *f = apr_hash_this_val(rindex);
+
+ if (f->frec->direction == AP_FILTER_INPUT && f->bb) {
+ apr_bucket *e = APR_BRIGADE_FIRST(f->bb);
+
+ /* if there is at least one non-morphing bucket
+ * in place, then we have data pending
+ */
+ if (e != APR_BRIGADE_SENTINEL(f->bb)
+ && e->length != (apr_size_t)(-1)) {
+ return OK;
+ }
+
+ }
+
+ rindex = apr_hash_next(rindex);
+ }
+
+ return DECLINED;
+}
+
AP_DECLARE_NONSTD(apr_status_t) ap_filter_flush(apr_bucket_brigade *bb,
void *ctx)
{