From 08002aaebbc8c5196b4d7f960bc017e6ef75bce2 Mon Sep 17 00:00:00 2001 From: Brian Pane Date: Sun, 27 Jan 2002 01:54:54 +0000 Subject: [PATCH] Added new functions ap_add_input_filter_handle() and ap_add_output_filter_handle() There are many places in the core modules where we do ap_add_input_filter() or ap_add_output_filter() on a hardcoded filter name (e.g., "CORE" or "BYTERANGE"). This requires a string-to-filter mapping that wastes CPU time. (Even though the string lookup uses a trie for speed, it still ranks as a big consumer of CPU time because of the large number of filters added per request.) The new ap_add_*_filter_handle() functions will allow us to skip the string-to-filter mapping in cases where the module adding the filter happens to have the ap_filter_rec_t* for the registered filter (e.g., because it's the same module that registered the filter in the first place). git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@93039 13f79535-47bb-0310-9956-ffa450edef68 --- CHANGES | 4 +++ include/util_filter.h | 26 ++++++++++++++++ server/util_filter.c | 69 ++++++++++++++++++++++++++++++++++++++----- 3 files changed, 92 insertions(+), 7 deletions(-) diff --git a/CHANGES b/CHANGES index ef0dcae158..7757b8e79c 100644 --- a/CHANGES +++ b/CHANGES @@ -1,5 +1,9 @@ Changes with Apache 2.0.31-dev + *) Added new functions ap_add_(input|output)_filter_handle to + allow modules to bypass the usual filter name lookup when + adding hard-coded filters to a request [Brian Pane] + *) caching should now work on subrequests (still very experimental) [Ian Holsman] diff --git a/include/util_filter.h b/include/util_filter.h index f15c6deebc..0af2d37302 100644 --- a/include/util_filter.h +++ b/include/util_filter.h @@ -352,6 +352,19 @@ AP_DECLARE(ap_filter_rec_t *) ap_register_output_filter(const char *name, AP_DECLARE(ap_filter_t *) ap_add_input_filter(const char *name, void *ctx, request_rec *r, conn_rec *c); +/** + * Variant of ap_add_input_filter() that accepts a registered filter handle + * (as returned by ap_register_input_filter()) rather than a filter name + * + * @param name The filter to add + * @param r The request to add this filter for (or NULL if it isn't associated with a request) + * @param c The connection to add the fillter for + */ +AP_DECLARE(ap_filter_t *) ap_add_input_filter_handle(ap_filter_rec_t *f, + void *ctx, + request_rec *r, + conn_rec *c); + /** * Add a filter to the current request. Filters are added in a FIFO manner. * The first filter added will be the first filter called. @@ -363,6 +376,19 @@ AP_DECLARE(ap_filter_t *) ap_add_input_filter(const char *name, void *ctx, AP_DECLARE(ap_filter_t *) ap_add_output_filter(const char *name, void *ctx, request_rec *r, conn_rec *c); +/** + * Variant of ap_add_output_filter() that accepts a registered filter handle + * (as returned by ap_register_output_filter()) rather than a filter name + * + * @param name The filter to add + * @param r The request to add this filter for (or NULL if it isn't associated with a request) + * @param c The connection to add the fillter for + */ +AP_DECLARE(ap_filter_t *) ap_add_output_filter_handle(ap_filter_rec_t *f, + void *ctx, + request_rec *r, + conn_rec *c); + /** * Remove an input filter from either the request or connection stack * it is associated with. diff --git a/server/util_filter.c b/server/util_filter.c index 0282cca8bc..ddda05c1d4 100644 --- a/server/util_filter.c +++ b/server/util_filter.c @@ -188,7 +188,8 @@ static ap_filter_rec_t *register_filter(const char *name, ap_filter_type ftype, filter_trie_node **reg_filter_set) { - ap_filter_rec_t *frec = apr_palloc(FILTER_POOL, sizeof(*frec)); + ap_filter_rec_t *frec; + char *normalized_name; const char *n; filter_trie_node *node; @@ -196,20 +197,27 @@ static ap_filter_rec_t *register_filter(const char *name, *reg_filter_set = trie_node_alloc(FILTER_POOL, NULL, 0); } - frec->name = apr_pstrdup(FILTER_POOL, name); - ap_str_tolower((char *)frec->name); - frec->filter_func = filter_func; - frec->ftype = ftype; + normalized_name = apr_pstrdup(FILTER_POOL, name); + ap_str_tolower(normalized_name); node = *reg_filter_set; - for (n = frec->name; *n; n++) { + for (n = normalized_name; *n; n++) { filter_trie_node *child = trie_node_alloc(FILTER_POOL, node, *n); if (apr_isalpha(*n)) { trie_node_link(FILTER_POOL, node, child, apr_toupper(*n)); } node = child; } - node->frec = frec; + if (node->frec) { + frec = node->frec; + } + else { + frec = apr_palloc(FILTER_POOL, sizeof(*frec)); + node->frec = frec; + frec->name = normalized_name; + } + frec->filter_func = filter_func; + frec->ftype = ftype; apr_pool_cleanup_register(FILTER_POOL, NULL, filter_cleanup, apr_pool_cleanup_null); @@ -300,6 +308,35 @@ static ap_filter_t *add_any_filter(const char *name, void *ctx, return NULL; } +static ap_filter_t *add_any_filter_handle(ap_filter_rec_t *frec, void *ctx, + request_rec *r, conn_rec *c, + ap_filter_t **r_filters, + ap_filter_t **c_filters) +{ + apr_pool_t* p = r ? r->pool : c->pool; + ap_filter_t *f = apr_palloc(p, sizeof(*f)); + ap_filter_t **outf = r ? r_filters : c_filters; + + f->frec = frec; + f->ctx = ctx; + f->r = r; + f->c = c; + + if (INSERT_BEFORE(f, *outf)) { + f->next = *outf; + *outf = f; + } + else { + ap_filter_t *fscan = *outf; + while (!INSERT_BEFORE(f, fscan->next)) + fscan = fscan->next; + f->next = fscan->next; + fscan->next = f; + } + + return f; +} + AP_DECLARE(ap_filter_t *) ap_add_input_filter(const char *name, void *ctx, request_rec *r, conn_rec *c) { @@ -307,6 +344,15 @@ AP_DECLARE(ap_filter_t *) ap_add_input_filter(const char *name, void *ctx, r ? &r->input_filters : NULL, &c->input_filters); } +AP_DECLARE(ap_filter_t *) ap_add_input_filter_handle(ap_filter_rec_t *f, + void *ctx, + request_rec *r, + conn_rec *c) +{ + return add_any_filter_handle(f, ctx, r, c, r ? &r->input_filters : NULL, + &c->input_filters); +} + AP_DECLARE(ap_filter_t *) ap_add_output_filter(const char *name, void *ctx, request_rec *r, conn_rec *c) { @@ -314,6 +360,15 @@ AP_DECLARE(ap_filter_t *) ap_add_output_filter(const char *name, void *ctx, r ? &r->output_filters : NULL, &c->output_filters); } +AP_DECLARE(ap_filter_t *) ap_add_output_filter_handle(ap_filter_rec_t *f, + void *ctx, + request_rec *r, + conn_rec *c) +{ + return add_any_filter_handle(f, ctx, r, c, r ? &r->output_filters : NULL, + &c->output_filters); +} + static void remove_any_filter(ap_filter_t *f, ap_filter_t **r_filt, ap_filter_t **c_filt) { -- 2.50.1