1 /* Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements. See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * The ASF licenses this file to You under the Apache License, Version 2.0
5 * (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 #define APR_WANT_STRFUNC
21 #include "apr_strings.h"
24 #include "http_config.h"
25 #include "http_core.h"
27 #include "util_filter.h"
29 /* NOTE: Apache's current design doesn't allow a pool to be passed thru,
30 so we depend on a global to hold the correct pool
32 #define FILTER_POOL apr_hook_global_pool
33 #include "ap_hooks.h" /* for apr_hook_global_pool */
36 ** This macro returns true/false if a given filter should be inserted BEFORE
37 ** another filter. This will happen when one of: 1) there isn't another
38 ** filter; 2) that filter has a higher filter type (class); 3) that filter
39 ** corresponds to a different request.
41 #define INSERT_BEFORE(f, before_this) ((before_this) == NULL \
42 || (before_this)->frec->ftype > (f)->frec->ftype \
43 || (before_this)->r != (f)->r)
45 /* Trie structure to hold the mapping from registered
46 * filter names to filters
49 /* we know core's module_index is 0 */
50 #undef APLOG_MODULE_INDEX
51 #define APLOG_MODULE_INDEX AP_CORE_MODULE_INDEX
53 typedef struct filter_trie_node filter_trie_node;
57 filter_trie_node *child;
58 } filter_trie_child_ptr;
60 /* Each trie node has an array of pointers to its children.
61 * The array is kept in sorted order so that add_any_filter()
62 * can do a binary search
64 struct filter_trie_node {
65 ap_filter_rec_t *frec;
66 filter_trie_child_ptr *children;
71 #define TRIE_INITIAL_SIZE 4
73 /* Link a trie node to its parent
75 static void trie_node_link(apr_pool_t *p, filter_trie_node *parent,
76 filter_trie_node *child, int c)
80 if (parent->nchildren == parent->size) {
81 filter_trie_child_ptr *new;
83 new = (filter_trie_child_ptr *)apr_palloc(p, parent->size *
84 sizeof(filter_trie_child_ptr));
85 memcpy(new, parent->children, parent->nchildren *
86 sizeof(filter_trie_child_ptr));
87 parent->children = new;
90 for (i = 0; i < parent->nchildren; i++) {
91 if (c == parent->children[i].c) {
94 else if (c < parent->children[i].c) {
98 for (j = parent->nchildren; j > i; j--) {
99 parent->children[j].c = parent->children[j - 1].c;
100 parent->children[j].child = parent->children[j - 1].child;
102 parent->children[i].c = c;
103 parent->children[i].child = child;
108 /* Allocate a new node for a trie.
109 * If parent is non-NULL, link the new node under the parent node with
110 * key 'c' (or, if an existing child node matches, return that one)
112 static filter_trie_node *trie_node_alloc(apr_pool_t *p,
113 filter_trie_node *parent, char c)
115 filter_trie_node *new_node;
118 for (i = 0; i < parent->nchildren; i++) {
119 if (c == parent->children[i].c) {
120 return parent->children[i].child;
122 else if (c < parent->children[i].c) {
127 (filter_trie_node *)apr_palloc(p, sizeof(filter_trie_node));
128 trie_node_link(p, parent, new_node, c);
130 else { /* No parent node */
131 new_node = (filter_trie_node *)apr_palloc(p,
132 sizeof(filter_trie_node));
135 new_node->frec = NULL;
136 new_node->nchildren = 0;
137 new_node->size = TRIE_INITIAL_SIZE;
138 new_node->children = (filter_trie_child_ptr *)apr_palloc(p,
139 new_node->size * sizeof(filter_trie_child_ptr));
143 static filter_trie_node *registered_output_filters = NULL;
144 static filter_trie_node *registered_input_filters = NULL;
147 static apr_status_t filter_cleanup(void *ctx)
149 registered_output_filters = NULL;
150 registered_input_filters = NULL;
154 static ap_filter_rec_t *get_filter_handle(const char *name,
155 const filter_trie_node *filter_set)
159 const filter_trie_node *node;
162 for (n = name; *n; n++) {
165 end = node->nchildren - 1;
166 while (end >= start) {
167 int middle = (end + start) / 2;
168 char ch = node->children[middle].c;
170 node = node->children[middle].child;
186 if (node && node->frec) {
193 AP_DECLARE(ap_filter_rec_t *)ap_get_output_filter_handle(const char *name)
195 return get_filter_handle(name, registered_output_filters);
198 AP_DECLARE(ap_filter_rec_t *)ap_get_input_filter_handle(const char *name)
200 return get_filter_handle(name, registered_input_filters);
203 static ap_filter_rec_t *register_filter(const char *name,
204 ap_filter_func filter_func,
205 ap_init_filter_func filter_init,
206 ap_filter_type ftype,
207 filter_trie_node **reg_filter_set)
209 ap_filter_rec_t *frec;
210 char *normalized_name;
212 filter_trie_node *node;
214 if (!*reg_filter_set) {
215 *reg_filter_set = trie_node_alloc(FILTER_POOL, NULL, 0);
218 normalized_name = apr_pstrdup(FILTER_POOL, name);
219 ap_str_tolower(normalized_name);
221 node = *reg_filter_set;
222 for (n = normalized_name; *n; n++) {
223 filter_trie_node *child = trie_node_alloc(FILTER_POOL, node, *n);
224 if (apr_isalpha(*n)) {
225 trie_node_link(FILTER_POOL, node, child, apr_toupper(*n));
233 frec = apr_pcalloc(FILTER_POOL, sizeof(*frec));
235 frec->name = normalized_name;
237 frec->filter_func = filter_func;
238 frec->filter_init_func = filter_init;
241 apr_pool_cleanup_register(FILTER_POOL, NULL, filter_cleanup,
242 apr_pool_cleanup_null);
246 AP_DECLARE(ap_filter_rec_t *) ap_register_input_filter(const char *name,
247 ap_in_filter_func filter_func,
248 ap_init_filter_func filter_init,
249 ap_filter_type ftype)
252 f.in_func = filter_func;
253 return register_filter(name, f, filter_init, ftype,
254 ®istered_input_filters);
257 AP_DECLARE(ap_filter_rec_t *) ap_register_output_filter(const char *name,
258 ap_out_filter_func filter_func,
259 ap_init_filter_func filter_init,
260 ap_filter_type ftype)
262 return ap_register_output_filter_protocol(name, filter_func,
263 filter_init, ftype, 0);
266 AP_DECLARE(ap_filter_rec_t *) ap_register_output_filter_protocol(
268 ap_out_filter_func filter_func,
269 ap_init_filter_func filter_init,
270 ap_filter_type ftype,
271 unsigned int proto_flags)
273 ap_filter_rec_t* ret ;
275 f.out_func = filter_func;
276 ret = register_filter(name, f, filter_init, ftype,
277 ®istered_output_filters);
278 ret->proto_flags = proto_flags ;
282 static ap_filter_t *add_any_filter_handle(ap_filter_rec_t *frec, void *ctx,
283 request_rec *r, conn_rec *c,
284 ap_filter_t **r_filters,
285 ap_filter_t **p_filters,
286 ap_filter_t **c_filters)
288 apr_pool_t *p = frec->ftype < AP_FTYPE_CONNECTION && r ? r->pool : c->pool;
289 ap_filter_t *f = apr_palloc(p, sizeof(*f));
292 if (frec->ftype < AP_FTYPE_PROTOCOL) {
297 ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, c,
298 "a content filter was added without a request: %s", frec->name);
302 else if (frec->ftype < AP_FTYPE_CONNECTION) {
307 ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, c,
308 "a protocol filter was added without a request: %s", frec->name);
318 /* f->r must always be NULL for connection filters */
319 f->r = frec->ftype < AP_FTYPE_CONNECTION ? r : NULL;
323 if (INSERT_BEFORE(f, *outf)) {
327 ap_filter_t *first = NULL;
330 /* If we are adding our first non-connection filter,
331 * Then don't try to find the right location, it is
332 * automatically first.
334 if (*r_filters != *c_filters) {
336 while (first && (first->next != (*outf))) {
341 if (first && first != (*outf)) {
348 ap_filter_t *fscan = *outf;
349 while (!INSERT_BEFORE(f, fscan->next))
352 f->next = fscan->next;
356 if (frec->ftype < AP_FTYPE_CONNECTION && (*r_filters == *c_filters)) {
357 *r_filters = *p_filters;
362 static ap_filter_t *add_any_filter(const char *name, void *ctx,
363 request_rec *r, conn_rec *c,
364 const filter_trie_node *reg_filter_set,
365 ap_filter_t **r_filters,
366 ap_filter_t **p_filters,
367 ap_filter_t **c_filters)
369 if (reg_filter_set) {
371 const filter_trie_node *node;
373 node = reg_filter_set;
374 for (n = name; *n; n++) {
377 end = node->nchildren - 1;
378 while (end >= start) {
379 int middle = (end + start) / 2;
380 char ch = node->children[middle].c;
382 node = node->children[middle].child;
398 if (node && node->frec) {
399 return add_any_filter_handle(node->frec, ctx, r, c, r_filters,
400 p_filters, c_filters);
404 ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, r ? r->connection : c,
405 "an unknown filter was not added: %s", name);
409 AP_DECLARE(ap_filter_t *) ap_add_input_filter(const char *name, void *ctx,
410 request_rec *r, conn_rec *c)
412 return add_any_filter(name, ctx, r, c, registered_input_filters,
413 r ? &r->input_filters : NULL,
414 r ? &r->proto_input_filters : NULL, &c->input_filters);
417 AP_DECLARE(ap_filter_t *) ap_add_input_filter_handle(ap_filter_rec_t *f,
422 return add_any_filter_handle(f, ctx, r, c, r ? &r->input_filters : NULL,
423 r ? &r->proto_input_filters : NULL,
427 AP_DECLARE(ap_filter_t *) ap_add_output_filter(const char *name, void *ctx,
428 request_rec *r, conn_rec *c)
430 return add_any_filter(name, ctx, r, c, registered_output_filters,
431 r ? &r->output_filters : NULL,
432 r ? &r->proto_output_filters : NULL, &c->output_filters);
435 AP_DECLARE(ap_filter_t *) ap_add_output_filter_handle(ap_filter_rec_t *f,
440 return add_any_filter_handle(f, ctx, r, c, r ? &r->output_filters : NULL,
441 r ? &r->proto_output_filters : NULL,
445 static void remove_any_filter(ap_filter_t *f, ap_filter_t **r_filt, ap_filter_t **p_filt,
446 ap_filter_t **c_filt)
448 ap_filter_t **curr = r_filt ? r_filt : c_filt;
449 ap_filter_t *fscan = *curr;
451 if (p_filt && *p_filt == f)
452 *p_filt = (*p_filt)->next;
455 *curr = (*curr)->next;
459 while (fscan->next != f) {
460 if (!(fscan = fscan->next)) {
465 fscan->next = f->next;
468 AP_DECLARE(void) ap_remove_input_filter(ap_filter_t *f)
470 remove_any_filter(f, f->r ? &f->r->input_filters : NULL,
471 f->r ? &f->r->proto_input_filters : NULL,
472 &f->c->input_filters);
475 AP_DECLARE(void) ap_remove_output_filter(ap_filter_t *f)
477 remove_any_filter(f, f->r ? &f->r->output_filters : NULL,
478 f->r ? &f->r->proto_output_filters : NULL,
479 &f->c->output_filters);
483 * Read data from the next filter in the filter stack. Data should be
484 * modified in the bucket brigade that is passed in. The core allocates the
485 * bucket brigade, modules that wish to replace large chunks of data or to
486 * save data off to the side should probably create their own temporary
487 * brigade especially for that use.
489 AP_DECLARE(apr_status_t) ap_get_brigade(ap_filter_t *next,
490 apr_bucket_brigade *bb,
491 ap_input_mode_t mode,
492 apr_read_type_e block,
496 return next->frec->filter_func.in_func(next, bb, mode, block,
499 return AP_NOBODY_READ;
502 /* Pass the buckets to the next filter in the filter stack. If the
503 * current filter is a handler, we should get NULL passed in instead of
504 * the current filter. At that point, we can just call the first filter in
505 * the stack, or r->output_filters.
507 AP_DECLARE(apr_status_t) ap_pass_brigade(ap_filter_t *next,
508 apr_bucket_brigade *bb)
512 if ((e = APR_BRIGADE_LAST(bb)) && APR_BUCKET_IS_EOS(e) && next->r) {
513 /* This is only safe because HTTP_HEADER filter is always in
514 * the filter stack. This ensures that there is ALWAYS a
515 * request-based filter that we can attach this to. If the
516 * HTTP_FILTER is removed, and another filter is not put in its
517 * place, then handlers like mod_cgi, which attach their own
518 * EOS bucket to the brigade will be broken, because we will
519 * get two EOS buckets on the same request.
521 next->r->eos_sent = 1;
523 /* remember the eos for internal redirects, too */
525 request_rec *prev = next->r->prev;
533 return next->frec->filter_func.out_func(next, bb);
535 return AP_NOBODY_WROTE;
538 /* Pass the buckets to the next filter in the filter stack
539 * checking return status for filter errors.
540 * returns: OK if ap_pass_brigade returns APR_SUCCESS
541 * AP_FILTER_ERROR if filter error exists
542 * HTTP_INTERNAL_SERVER_ERROR for all other cases
543 * logged with optional errmsg
545 AP_DECLARE(apr_status_t) ap_pass_brigade_fchk(request_rec *r,
546 apr_bucket_brigade *bb,
552 rv = ap_pass_brigade(r->output_filters, bb);
553 if (rv != APR_SUCCESS) {
554 if (rv != AP_FILTER_ERROR) {
556 ap_log_rerror(APLOG_MARK, APLOG_DEBUG, rv, r,
557 "ap_pass_brigade returned %d", rv);
562 res = apr_pvsprintf(r->pool, fmt, ap);
564 ap_log_rerror(APLOG_MARK, APLOG_DEBUG, rv, r, res, NULL);
566 return HTTP_INTERNAL_SERVER_ERROR;
568 return AP_FILTER_ERROR;
573 AP_DECLARE(apr_status_t) ap_save_brigade(ap_filter_t *f,
574 apr_bucket_brigade **saveto,
575 apr_bucket_brigade **b, apr_pool_t *p)
578 apr_status_t rv, srv = APR_SUCCESS;
580 /* If have never stored any data in the filter, then we had better
581 * create an empty bucket brigade so that we can concat.
584 *saveto = apr_brigade_create(p, f->c->bucket_alloc);
587 for (e = APR_BRIGADE_FIRST(*b);
588 e != APR_BRIGADE_SENTINEL(*b);
589 e = APR_BUCKET_NEXT(e))
591 rv = apr_bucket_setaside(e, p);
593 /* If the bucket type does not implement setaside, then
594 * (hopefully) morph it into a bucket type which does, and set
596 if (rv == APR_ENOTIMPL) {
600 rv = apr_bucket_read(e, &s, &n, APR_BLOCK_READ);
601 if (rv == APR_SUCCESS) {
602 rv = apr_bucket_setaside(e, p);
606 if (rv != APR_SUCCESS) {
608 /* Return an error but still save the brigade if
609 * ->setaside() is really not implemented. */
610 if (rv != APR_ENOTIMPL) {
615 APR_BRIGADE_CONCAT(*saveto, *b);
619 AP_DECLARE_NONSTD(apr_status_t) ap_filter_flush(apr_bucket_brigade *bb,
622 ap_filter_t *f = ctx;
625 rv = ap_pass_brigade(f, bb);
627 /* Before invocation of the flush callback, apr_brigade_write et
628 * al may place transient buckets in the brigade, which will fall
629 * out of scope after returning. Empty the brigade here, to avoid
630 * issues with leaving such buckets in the brigade if some filter
631 * fails and leaves a non-empty brigade. */
632 apr_brigade_cleanup(bb);
637 AP_DECLARE(apr_status_t) ap_fflush(ap_filter_t *f, apr_bucket_brigade *bb)
641 b = apr_bucket_flush_create(f->c->bucket_alloc);
642 APR_BRIGADE_INSERT_TAIL(bb, b);
643 return ap_pass_brigade(f, bb);
646 AP_DECLARE_NONSTD(apr_status_t) ap_fputstrs(ap_filter_t *f,
647 apr_bucket_brigade *bb, ...)
653 rv = apr_brigade_vputstrs(bb, ap_filter_flush, f, args);
658 AP_DECLARE_NONSTD(apr_status_t) ap_fprintf(ap_filter_t *f,
659 apr_bucket_brigade *bb,
667 rv = apr_brigade_vprintf(bb, ap_filter_flush, f, fmt, args);
671 AP_DECLARE(void) ap_filter_protocol(ap_filter_t *f, unsigned int flags)
673 f->frec->proto_flags = flags ;