diff options
Diffstat (limited to 'server')
-rw-r--r-- | server/core.c | 4 | ||||
-rw-r--r-- | server/core_filters.c | 35 | ||||
-rw-r--r-- | server/mpm/event/event.c | 4 | ||||
-rw-r--r-- | server/mpm/motorz/motorz.c | 4 | ||||
-rw-r--r-- | server/mpm/simple/simple_io.c | 4 | ||||
-rw-r--r-- | server/mpm_common.c | 7 | ||||
-rw-r--r-- | server/util_filter.c | 82 |
7 files changed, 93 insertions, 47 deletions
diff --git a/server/core.c b/server/core.c index f0c6c5c813..d7187beb52 100644 --- a/server/core.c +++ b/server/core.c @@ -5559,8 +5559,8 @@ static void register_hooks(apr_pool_t *p) ap_hook_open_htaccess(ap_open_htaccess, NULL, NULL, APR_HOOK_REALLY_LAST); ap_hook_optional_fn_retrieve(core_optional_fn_retrieve, NULL, NULL, APR_HOOK_MIDDLE); - ap_hook_complete_connection(ap_filter_complete_connection, NULL, NULL, - APR_HOOK_MIDDLE); + ap_hook_output_pending(ap_filter_output_pending, NULL, NULL, + APR_HOOK_MIDDLE); /* register the core's insert_filter hook and register core-provided * filters diff --git a/server/core_filters.c b/server/core_filters.c index 60194f28db..e0a38ddb37 100644 --- a/server/core_filters.c +++ b/server/core_filters.c @@ -84,7 +84,6 @@ struct core_output_filter_ctx { }; struct core_filter_ctx { - apr_bucket_brigade *b; apr_bucket_brigade *tmpbb; }; @@ -116,19 +115,19 @@ apr_status_t ap_core_input_filter(ap_filter_t *f, apr_bucket_brigade *b, if (!ctx) { net->in_ctx = ctx = apr_palloc(f->c->pool, sizeof(*ctx)); - ctx->b = apr_brigade_create(f->c->pool, f->c->bucket_alloc); + ap_filter_prepare_brigade(f, NULL); ctx->tmpbb = apr_brigade_create(f->c->pool, f->c->bucket_alloc); /* seed the brigade with the client socket. */ - rv = ap_run_insert_network_bucket(f->c, ctx->b, net->client_socket); + rv = ap_run_insert_network_bucket(f->c, f->bb, net->client_socket); if (rv != APR_SUCCESS) return rv; } - else if (APR_BRIGADE_EMPTY(ctx->b)) { + else if (APR_BRIGADE_EMPTY(f->bb)) { return APR_EOF; } /* ### This is bad. */ - BRIGADE_NORMALIZE(ctx->b); + BRIGADE_NORMALIZE(f->bb); /* check for empty brigade again *AFTER* BRIGADE_NORMALIZE() * If we have lost our socket bucket (see above), we are EOF. @@ -136,13 +135,13 @@ apr_status_t ap_core_input_filter(ap_filter_t *f, apr_bucket_brigade *b, * Ideally, this should be returning SUCCESS with EOS bucket, but * some higher-up APIs (spec. read_request_line via ap_rgetline) * want an error code. */ - if (APR_BRIGADE_EMPTY(ctx->b)) { + if (APR_BRIGADE_EMPTY(f->bb)) { return APR_EOF; } if (mode == AP_MODE_GETLINE) { /* we are reading a single LF line, e.g. the HTTP headers */ - rv = apr_brigade_split_line(b, ctx->b, block, HUGE_STRING_LEN); + rv = apr_brigade_split_line(b, f->bb, block, HUGE_STRING_LEN); /* We should treat EAGAIN here the same as we do for EOF (brigade is * empty). We do this by returning whatever we have read. This may * or may not be bogus, but is consistent (for now) with EOF logic. @@ -170,10 +169,10 @@ apr_status_t ap_core_input_filter(ap_filter_t *f, apr_bucket_brigade *b, * mean that there is another request, just a blank line. */ while (1) { - if (APR_BRIGADE_EMPTY(ctx->b)) + if (APR_BRIGADE_EMPTY(f->bb)) return APR_EOF; - e = APR_BRIGADE_FIRST(ctx->b); + e = APR_BRIGADE_FIRST(f->bb); rv = apr_bucket_read(e, &str, &len, APR_NONBLOCK_READ); @@ -212,7 +211,7 @@ apr_status_t ap_core_input_filter(ap_filter_t *f, apr_bucket_brigade *b, apr_bucket *e; /* Tack on any buckets that were set aside. */ - APR_BRIGADE_CONCAT(b, ctx->b); + APR_BRIGADE_CONCAT(b, f->bb); /* Since we've just added all potential buckets (which will most * likely simply be the socket bucket) we know this is the end, @@ -230,7 +229,7 @@ apr_status_t ap_core_input_filter(ap_filter_t *f, apr_bucket_brigade *b, AP_DEBUG_ASSERT(readbytes > 0); - e = APR_BRIGADE_FIRST(ctx->b); + e = APR_BRIGADE_FIRST(f->bb); rv = apr_bucket_read(e, &str, &len, block); if (APR_STATUS_IS_EAGAIN(rv) && block == APR_NONBLOCK_READ) { @@ -267,7 +266,7 @@ apr_status_t ap_core_input_filter(ap_filter_t *f, apr_bucket_brigade *b, /* We already registered the data in e in len */ e = APR_BUCKET_NEXT(e); while ((len < readbytes) && (rv == APR_SUCCESS) - && (e != APR_BRIGADE_SENTINEL(ctx->b))) { + && (e != APR_BRIGADE_SENTINEL(f->bb))) { /* Check for the availability of buckets with known length */ if (e->length != -1) { len += e->length; @@ -295,22 +294,22 @@ apr_status_t ap_core_input_filter(ap_filter_t *f, apr_bucket_brigade *b, readbytes = len; } - rv = apr_brigade_partition(ctx->b, readbytes, &e); + rv = apr_brigade_partition(f->bb, readbytes, &e); if (rv != APR_SUCCESS) { return rv; } /* Must do move before CONCAT */ - ctx->tmpbb = apr_brigade_split_ex(ctx->b, e, ctx->tmpbb); + ctx->tmpbb = apr_brigade_split_ex(f->bb, e, ctx->tmpbb); if (mode == AP_MODE_READBYTES) { - APR_BRIGADE_CONCAT(b, ctx->b); + APR_BRIGADE_CONCAT(b, f->bb); } else if (mode == AP_MODE_SPECULATIVE) { apr_bucket *copy_bucket; - for (e = APR_BRIGADE_FIRST(ctx->b); - e != APR_BRIGADE_SENTINEL(ctx->b); + for (e = APR_BRIGADE_FIRST(f->bb); + e != APR_BRIGADE_SENTINEL(f->bb); e = APR_BUCKET_NEXT(e)) { rv = apr_bucket_copy(e, ©_bucket); @@ -322,7 +321,7 @@ apr_status_t ap_core_input_filter(ap_filter_t *f, apr_bucket_brigade *b, } /* Take what was originally there and place it back on ctx->b */ - APR_BRIGADE_CONCAT(ctx->b, ctx->tmpbb); + APR_BRIGADE_CONCAT(f->bb, ctx->tmpbb); } return APR_SUCCESS; } diff --git a/server/mpm/event/event.c b/server/mpm/event/event.c index 0d6d9584fe..76ed0d4dd5 100644 --- a/server/mpm/event/event.c +++ b/server/mpm/event/event.c @@ -1151,7 +1151,7 @@ read_request: ap_update_child_status_from_conn(sbh, SERVER_BUSY_WRITE, c); - not_complete_yet = ap_run_complete_connection(c); + not_complete_yet = ap_run_output_pending(c); if (not_complete_yet > OK) { cs->pub.state = CONN_STATE_LINGER; @@ -1177,7 +1177,7 @@ read_request: listener_may_exit) { cs->pub.state = CONN_STATE_LINGER; } - else if (c->data_in_input_filters) { + else if (ap_run_input_pending(c) == OK) { cs->pub.state = CONN_STATE_READ_REQUEST_LINE; goto read_request; } diff --git a/server/mpm/motorz/motorz.c b/server/mpm/motorz/motorz.c index 4d0eb70ab5..1f5453ef43 100644 --- a/server/mpm/motorz/motorz.c +++ b/server/mpm/motorz/motorz.c @@ -402,7 +402,7 @@ read_request: ap_update_child_status_from_conn(scon->sbh, SERVER_BUSY_WRITE, c); - not_complete_yet = ap_run_complete_connection(c); + not_complete_yet = ap_run_output_pending(c); if (not_complete_yet > OK) { scon->cs.state = CONN_STATE_LINGER; @@ -433,7 +433,7 @@ read_request: else if (c->keepalive != AP_CONN_KEEPALIVE || c->aborted) { scon->cs.state = CONN_STATE_LINGER; } - else if (c->data_in_input_filters) { + else if (ap_run_input_pending(c) == OK) { scon->cs.state = CONN_STATE_READ_REQUEST_LINE; goto read_request; } diff --git a/server/mpm/simple/simple_io.c b/server/mpm/simple/simple_io.c index 83cbe04cc1..dcd1c75d84 100644 --- a/server/mpm/simple/simple_io.c +++ b/server/mpm/simple/simple_io.c @@ -96,7 +96,7 @@ static apr_status_t simple_io_process(simple_conn_t * scon) int not_complete_yet; ap_update_child_status_from_conn(c->sbh, SERVER_BUSY_WRITE, c); - not_complete_yet = ap_run_complete_connection(c); + not_complete_yet = ap_run_output_pending(c); if (not_complete_yet > OK) { scon->cs.state = CONN_STATE_LINGER; @@ -133,7 +133,7 @@ static apr_status_t simple_io_process(simple_conn_t * scon) else if (c->keepalive != AP_CONN_KEEPALIVE || c->aborted) { scon->cs.state = CONN_STATE_LINGER; } - else if (c->data_in_input_filters) { + else if (ap_run_input_pending(c) == OK) { scon->cs.state = CONN_STATE_READ_REQUEST_LINE; } else { diff --git a/server/mpm_common.c b/server/mpm_common.c index b2133df1a1..3fdfcddb42 100644 --- a/server/mpm_common.c +++ b/server/mpm_common.c @@ -75,7 +75,8 @@ APR_HOOK_LINK(mpm_resume_suspended) \ APR_HOOK_LINK(end_generation) \ APR_HOOK_LINK(child_status) \ - APR_HOOK_LINK(complete_connection) \ + APR_HOOK_LINK(output_pending) \ + APR_HOOK_LINK(input_pending) \ APR_HOOK_LINK(suspend_connection) \ APR_HOOK_LINK(resume_connection) @@ -118,7 +119,9 @@ AP_IMPLEMENT_HOOK_RUN_FIRST(apr_status_t, mpm_register_socket_callback_timeout, AP_IMPLEMENT_HOOK_RUN_FIRST(apr_status_t, mpm_unregister_socket_callback, (apr_socket_t **s, apr_pool_t *p), (s, p), APR_ENOTIMPL) -AP_IMPLEMENT_HOOK_RUN_FIRST(int, complete_connection, +AP_IMPLEMENT_HOOK_RUN_FIRST(int, output_pending, + (conn_rec *c), (c), DECLINED) +AP_IMPLEMENT_HOOK_RUN_FIRST(int, input_pending, (conn_rec *c), (c), DECLINED) AP_IMPLEMENT_HOOK_VOID(end_generation, 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, ®istered_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, ®istered_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) { |