diff options
author | Graham Leggett <minfrin@apache.org> | 2015-10-06 22:33:03 +0000 |
---|---|---|
committer | Graham Leggett <minfrin@apache.org> | 2015-10-06 22:33:03 +0000 |
commit | 2da6c9a57a7473c52d81b87e541228225691db6f (patch) | |
tree | 9aab1827521baf55de358244cf616bedd219b03c /server | |
parent | f296d2b85b51618ee76b4dfa96673887c4ab909f (diff) | |
download | httpd-2da6c9a57a7473c52d81b87e541228225691db6f.tar.gz |
Add the AsyncFilter directive that allows the asynchronous filter
functionality to be switched off for certain classes of filters.
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1707161 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'server')
-rw-r--r-- | server/core.c | 45 | ||||
-rw-r--r-- | server/request.c | 9 | ||||
-rw-r--r-- | server/util_filter.c | 8 |
3 files changed, 58 insertions, 4 deletions
diff --git a/server/core.c b/server/core.c index de3fa23f91..d340d5e3de 100644 --- a/server/core.c +++ b/server/core.c @@ -481,7 +481,8 @@ static void *create_core_server_config(apr_pool_t *a, server_rec *s) conf->protocols = apr_array_make(a, 5, sizeof(const char *)); conf->protocols_honor_order = -1; - + conf->async_filter = 0; + return (void *)conf; } @@ -555,12 +556,16 @@ static void *merge_core_server_configs(apr_pool_t *p, void *basev, void *virtv) ? virt->merge_trailers : base->merge_trailers; - conf->protocols = ((virt->protocols->nelts > 0)? + conf->protocols = ((virt->protocols->nelts > 0) ? virt->protocols : base->protocols); - conf->protocols_honor_order = ((virt->protocols_honor_order < 0)? + conf->protocols_honor_order = ((virt->protocols_honor_order < 0) ? base->protocols_honor_order : virt->protocols_honor_order); - + conf->async_filter = ((virt->async_filter_set) ? + virt->async_filter : + base->async_filter); + conf->async_filter_set = base->async_filter_set || virt->async_filter_set; + return conf; } @@ -3887,6 +3892,34 @@ static const char *set_http_protocol(cmd_parms *cmd, void *dummy, return NULL; } +static const char *set_async_filter(cmd_parms *cmd, void *dummy, + const char *arg) +{ + core_server_config *conf = + ap_get_core_module_config(cmd->server->module_config); + const char *err = ap_check_cmd_context(cmd, NOT_IN_DIR_LOC_FILE); + + if (err) { + return err; + } + + if (strcasecmp(arg, "network") == 0) { + conf->async_filter = AP_FTYPE_NETWORK; + } + else if (strcasecmp(arg, "connection") == 0) { + conf->async_filter = AP_FTYPE_CONNECTION; + } + else if (strcasecmp(arg, "request") == 0) { + conf->async_filter = 0; + } + else { + return "AsyncFilter must be 'network', 'connection' or 'request'"; + } + conf->async_filter_set = 1; + + return NULL; +} + static const char *set_http_method(cmd_parms *cmd, void *conf, const char *arg) { const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); @@ -4502,6 +4535,9 @@ AP_INIT_ITERATE("Protocols", set_protocols, NULL, RSRC_CONF, AP_INIT_TAKE1("ProtocolsHonorOrder", set_protocols_honor_order, NULL, RSRC_CONF, "'off' (default) or 'on' to respect given order of protocols, " "by default the client specified order determines selection"), +AP_INIT_TAKE1("AsyncFilter", set_async_filter, NULL, RSRC_CONF, + "'network', 'connection' (default) or 'request' to limit the " + "types of filters that support asynchronous handling"), { NULL } }; @@ -5010,6 +5046,7 @@ static conn_rec *core_create_conn(apr_pool_t *ptrans, server_rec *s, c->bucket_alloc = alloc; c->empty = apr_brigade_create(c->pool, c->bucket_alloc); c->filters = apr_hash_make(c->pool); + c->async_filter = sconf->async_filter; c->clogging_input_filters = 0; diff --git a/server/request.c b/server/request.c index 9c9ad9f93b..abf084e31a 100644 --- a/server/request.c +++ b/server/request.c @@ -2043,6 +2043,15 @@ AP_CORE_DECLARE_NONSTD(apr_status_t) ap_request_core_filter(ap_filter_t *f, apr_status_t status = APR_SUCCESS; apr_bucket_brigade *tmp_bb = f->ctx; + /* + * Handle the AsyncFilter directive. We limit the filters that are + * eligible for asynchronous handling here. + */ + if (f->frec->ftype < f->c->async_filter) { + ap_remove_output_filter(f); + return ap_pass_brigade(f->next, bb); + } + if (!tmp_bb) { tmp_bb = f->ctx = apr_brigade_create(f->r->pool, f->c->bucket_alloc); } diff --git a/server/util_filter.c b/server/util_filter.c index ad14112ddb..949d13e0a8 100644 --- a/server/util_filter.c +++ b/server/util_filter.c @@ -894,6 +894,14 @@ AP_DECLARE(apr_status_t) ap_filter_reinstate_brigade(ap_filter_t *f, AP_DECLARE(int) ap_filter_should_yield(ap_filter_t *f) { /* + * Handle the AsyncFilter directive. We limit the filters that are + * eligible for asynchronous handling here. + */ + if (f->frec->ftype < f->c->async_filter) { + return 0; + } + + /* * This function decides whether a filter should yield due to buffered * data in a downstream filter. If a downstream filter buffers we * must back off so we don't overwhelm the server. If this function |