Apache HTTPD
mod_filter.c
Go to the documentation of this file.
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
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
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.
15 */
16
17#define APR_WANT_STRFUNC
18#include "apr_want.h"
19#include "apr_lib.h"
20#include "apr_strings.h"
21#include "apr_hash.h"
22#include "httpd.h"
23#include "http_config.h"
24#include "http_request.h"
25#include "http_log.h"
26#include "util_filter.h"
27#include "ap_expr.h"
28
29module AP_MODULE_DECLARE_DATA filter_module;
30
48
61
62typedef struct mod_filter_chain {
63 const char *fname;
66
71
72typedef struct {
73 const char* range ;
75
76
77static void filter_trace(conn_rec *c, int debug, const char *fname,
79{
81
82 switch (debug) {
83 case 0: /* normal, operational use */
84 return;
85 case 1: /* mod_diagnostics level */
87 for (b = APR_BRIGADE_FIRST(bb);
89 b = APR_BUCKET_NEXT(b)) {
90
92 "%s: type: %s, length: %" APR_SIZE_T_FMT,
93 fname, b->type->name ? b->type->name : "(unknown)",
94 b->length);
95 }
96 break;
97 }
98}
99
101{
104 int err;
105 ap_filter_rec_t *filter = f->frec;
106
107 harness_ctx *fctx = apr_pcalloc(f->r->pool, sizeof(harness_ctx));
108 for (p = filter->providers; p; p = p->next) {
109 if (p->frec->filter_init_func == filter_init) {
111 "Chaining of FilterProviders not supported");
113 }
114 else if (p->frec->filter_init_func) {
115 f->ctx = NULL;
116 if ((err = p->frec->filter_init_func(f)) != OK) {
118 "filter_init for %s failed", p->frec->name);
119 return err; /* if anyone errors out here, so do we */
120 }
121 if (f->ctx != NULL) {
122 /* the filter init function set a ctx - we need to record it */
123 pctx = apr_pcalloc(f->r->pool, sizeof(provider_ctx));
124 pctx->provider = p;
125 pctx->ctx = f->ctx;
126 pctx->next = fctx->init_ctx;
127 fctx->init_ctx = pctx;
128 }
129 }
130 }
131 f->ctx = fctx;
132 return OK;
133}
134
136{
137 ap_filter_provider_t *provider;
138 int match = 0;
139 const char *err = NULL;
140 request_rec *r = f->r;
141 harness_ctx *ctx = f->ctx;
143#ifndef NO_PROTOCOL
144 unsigned int proto_flags;
146 &filter_module);
147#endif
148
149 /* Check registered providers in order */
150 for (provider = filter->providers; provider; provider = provider->next) {
151 if (provider->expr) {
152 match = ap_expr_exec(r, provider->expr, &err);
153 if (err) {
155 "Error evaluating filter dispatch condition: %s",
156 err);
157 match = 0;
158 }
160 "Expression condition for '%s' %s",
161 provider->frec->name,
162 match ? "matched" : "did not match");
163 }
164 else if (r->content_type) {
165 const char **type = provider->types;
166 size_t len = strcspn(r->content_type, "; \t");
169 "Content-Type '%s' ...", r->content_type);
170 while (*type) {
171 /* Handle 'content-type;charset=...' correctly */
172 if (strncmp(*type, r->content_type, len) == 0
173 && (*type)[len] == '\0') {
175 "... matched '%s'", *type);
176 match = 1;
177 break;
178 }
179 else {
181 "... did not match '%s'", *type);
182 }
183 type++;
184 }
186 "Content-Type condition for '%s' %s",
187 provider->frec->name,
188 match ? "matched" : "did not match");
189 }
190 else {
192 "Content-Type condition for '%s' did not match: "
193 "no Content-Type", provider->frec->name);
194 }
195
196 if (match) {
197 /* condition matches this provider */
198#ifndef NO_PROTOCOL
199 /* check protocol
200 *
201 * FIXME:
202 * This is a quick hack and almost certainly buggy.
203 * The idea is that by putting this in mod_filter, we relieve
204 * filter implementations of the burden of fixing up HTTP headers
205 * for cases that are routinely affected by filters.
206 *
207 * Default is ALWAYS to do nothing, so as not to tread on the
208 * toes of filters which want to do it themselves.
209 *
210 */
211 proto_flags = provider->frec->proto_flags;
212
213 /* some specific things can't happen in a proxy */
214 if (r->proxyreq) {
215 if (proto_flags & AP_FILTER_PROTO_NO_PROXY) {
216 /* can't use this provider; try next */
217 continue;
218 }
219
220 if (proto_flags & AP_FILTER_PROTO_TRANSFORM) {
221 const char *str = apr_table_get(r->headers_out,
222 "Cache-Control");
223 if (str) {
224 if (ap_strcasestr(str, "no-transform")) {
225 /* can't use this provider; try next */
226 continue;
227 }
228 }
229 apr_table_addn(r->headers_out, "Warning",
231 "214 %s Transformation applied",
232 r->hostname));
233 }
234 }
235
236 /* things that are invalidated if the filter transforms content */
237 if (proto_flags & AP_FILTER_PROTO_CHANGE) {
238 apr_table_unset(r->headers_out, "Content-MD5");
239 apr_table_unset(r->headers_out, "ETag");
240 if (proto_flags & AP_FILTER_PROTO_CHANGE_LENGTH) {
241 apr_table_unset(r->headers_out, "Content-Length");
242 }
243 }
244
245 /* no-cache is for a filter that has different effect per-hit */
246 if (proto_flags & AP_FILTER_PROTO_NO_CACHE) {
247 apr_table_unset(r->headers_out, "Last-Modified");
248 apr_table_addn(r->headers_out, "Cache-Control", "no-cache");
249 }
250
251 if (proto_flags & AP_FILTER_PROTO_NO_BYTERANGE) {
252 apr_table_setn(r->headers_out, "Accept-Ranges", "none");
253 }
254 else if (rctx && rctx->range) {
255 /* restore range header we saved earlier */
256 apr_table_setn(r->headers_in, "Range", rctx->range);
257 rctx->range = NULL;
258 }
259#endif
260 for (pctx = ctx->init_ctx; pctx; pctx = pctx->next) {
261 if (pctx->provider == provider) {
262 ctx->fctx = pctx->ctx ;
263 }
264 }
265 ctx->func = provider->frec->filter_func.out_func;
266 return 1;
267 }
268 }
269
270 /* No provider matched */
271 return 0;
272}
273
275{
277#ifndef NO_PROTOCOL
278 const char *cachecontrol;
279#endif
280 harness_ctx *ctx = f->ctx;
281 ap_filter_rec_t *filter = f->frec;
282
283 if (f->r->status != 200
284 && !apr_table_get(f->r->subprocess_env, "filter-errordocs")) {
286 return ap_pass_brigade(f->next, bb);
287 }
288
289 filter_trace(f->c, filter->debug, f->frec->name, bb);
290
291 /* look up a handler function if we haven't already set it */
292 if (!ctx->func) {
293#ifndef NO_PROTOCOL
294 if (f->r->proxyreq) {
297 return ap_pass_brigade(f->next, bb);
298 }
299
301 cachecontrol = apr_table_get(f->r->headers_out,
302 "Cache-Control");
303 if (cachecontrol) {
304 if (ap_strcasestr(cachecontrol, "no-transform")) {
306 return ap_pass_brigade(f->next, bb);
307 }
308 }
309 }
310 }
311#endif
312 if (!filter_lookup(f, filter)) {
314 return ap_pass_brigade(f->next, bb);
315 }
316 AP_DEBUG_ASSERT(ctx->func != NULL);
317 }
318
319 /* call the content filter with its own context, then restore our
320 * context
321 */
322 f->ctx = ctx->fctx;
323 ret = ctx->func(f, bb);
324 ctx->fctx = f->ctx;
325 f->ctx = ctx;
326
327 return ret;
328}
329
330#ifndef NO_PROTOCOL
331static const char *filter_protocol(cmd_parms *cmd, void *CFG, const char *fname,
332 const char *pname, const char *proto)
333{
334 static const char *sep = ";, \t";
335 char *arg;
336 char *tok = 0;
337 unsigned int flags = 0;
338 mod_filter_cfg *cfg = CFG;
339 ap_filter_provider_t *provider = NULL;
342
343 if (!filter) {
344 return "FilterProtocol: No such filter";
345 }
346
347 /* Fixup the args: it's really pname that's optional */
348 if (proto == NULL) {
349 proto = pname;
350 pname = NULL;
351 }
352 else {
353 /* Find provider */
354 for (provider = filter->providers; provider; provider = provider->next) {
355 if (!strcasecmp(provider->frec->name, pname)) {
356 break;
357 }
358 }
359 if (!provider) {
360 return "FilterProtocol: No such provider for this filter";
361 }
362 }
363
364 /* Now set flags from our args */
365 for (arg = apr_strtok(apr_pstrdup(cmd->temp_pool, proto), sep, &tok);
366 arg; arg = apr_strtok(NULL, sep, &tok)) {
367
368 if (!strcasecmp(arg, "change=yes")) {
370 }
371 if (!strcasecmp(arg, "change=no")) {
373 }
374 else if (!strcasecmp(arg, "change=1:1")) {
376 }
377 else if (!strcasecmp(arg, "byteranges=no")) {
379 }
380 else if (!strcasecmp(arg, "proxy=no")) {
382 }
383 else if (!strcasecmp(arg, "proxy=transform")) {
385 }
386 else if (!strcasecmp(arg, "cache=no")) {
388 }
389 }
390
391 if (pname) {
392 provider->frec->proto_flags = flags;
393 }
394 else {
395 filter->proto_flags = flags;
396 }
397
398 return NULL;
399}
400#endif
401
402static const char *filter_declare(cmd_parms *cmd, void *CFG, const char *fname,
403 const char *place)
404{
406 ap_filter_rec_t *filter;
407
408 filter = apr_pcalloc(cmd->pool, sizeof(ap_filter_rec_t));
410
411 filter->name = fname;
414 filter->ftype = AP_FTYPE_RESOURCE;
415 filter->next = NULL;
416
417 if (place) {
418 if (!strcasecmp(place, "CONTENT_SET")) {
419 filter->ftype = AP_FTYPE_CONTENT_SET;
420 }
421 else if (!strcasecmp(place, "PROTOCOL")) {
422 filter->ftype = AP_FTYPE_PROTOCOL;
423 }
424 else if (!strcasecmp(place, "CONNECTION")) {
425 filter->ftype = AP_FTYPE_CONNECTION;
426 }
427 else if (!strcasecmp(place, "NETWORK")) {
428 filter->ftype = AP_FTYPE_NETWORK;
429 }
430 }
431
432 return NULL;
433}
434
435static const char *add_filter(cmd_parms *cmd, void *CFG,
436 const char *fname, const char *pname,
437 const char *expr, const char **types)
438{
439 mod_filter_cfg *cfg = CFG;
440 ap_filter_provider_t *provider;
441 const char *c;
442 ap_filter_rec_t* frec;
444 ap_expr_info_t *node;
445 const char *err = NULL;
446
447 /* if provider has been registered, we can look it up */
449 if (!provider_frec) {
450 return apr_psprintf(cmd->pool, "Unknown filter provider %s", pname);
451 }
452
453 /* fname has been declared with DeclareFilter, so we can look it up */
455
456 /* or if provider is mod_filter itself, we can also look it up */
457 if (!frec) {
459 if ( c ) {
460 return c;
461 }
463 frec->ftype = provider_frec->ftype;
464 }
465
466 if (!frec) {
467 return apr_psprintf(cmd->pool, "Undeclared smart filter %s", fname);
468 }
469
470 provider = apr_palloc(cmd->pool, sizeof(ap_filter_provider_t));
471 if (expr) {
472 node = ap_expr_parse_cmd(cmd, expr, 0, &err, NULL);
473 if (err) {
474 return apr_pstrcat(cmd->pool,
475 "Error parsing FilterProvider expression:", err,
476 NULL);
477 }
478 provider->expr = node;
479 provider->types = NULL;
480 }
481 else {
482 provider->types = types;
483 provider->expr = NULL;
484 }
485 provider->frec = provider_frec;
486 provider->next = frec->providers;
487 frec->providers = provider;
488 return NULL;
489}
490
491static const char *filter_provider(cmd_parms *cmd, void *CFG,
492 const char *fname, const char *pname,
493 const char *expr)
494{
495 return add_filter(cmd, CFG, fname, pname, expr, NULL);
496}
497
498static const char *filter_chain(cmd_parms *cmd, void *CFG, const char *arg)
499{
502 mod_filter_cfg *cfg = CFG;
503
504 switch (arg[0]) {
505 case '+': /* add to end of chain */
506 p = apr_pcalloc(cmd->pool, sizeof(mod_filter_chain));
507 p->fname = arg+1;
508 if (cfg->chain) {
509 for (q = cfg->chain; q->next; q = q->next);
510 q->next = p;
511 }
512 else {
513 cfg->chain = p;
514 }
515 break;
516
517 case '@': /* add to start of chain */
518 p = apr_palloc(cmd->pool, sizeof(mod_filter_chain));
519 p->fname = arg+1;
520 p->next = cfg->chain;
521 cfg->chain = p;
522 break;
523
524 case '-': /* remove from chain */
525 if (cfg->chain) {
526 if (strcasecmp(cfg->chain->fname, arg+1)) {
527 for (p = cfg->chain; p->next; p = p->next) {
528 if (!strcasecmp(p->next->fname, arg+1)) {
529 p->next = p->next->next;
530 }
531 }
532 }
533 else {
534 cfg->chain = cfg->chain->next;
535 }
536 }
537 break;
538
539 case '!': /* Empty the chain */
543 p = apr_pcalloc(cmd->pool, sizeof(mod_filter_chain));
544 p->fname = NULL;
545 cfg->chain = p;
546 break;
547
548 case '=': /* initialise chain with this arg */
550 p = apr_pcalloc(cmd->pool, sizeof(mod_filter_chain));
551 p->fname = NULL;
552 p->next = apr_pcalloc(cmd->pool, sizeof(mod_filter_chain));
553 p->next->fname = arg+1;
554 cfg->chain = p;
555 break;
556
557 default: /* add to end */
558 p = apr_pcalloc(cmd->pool, sizeof(mod_filter_chain));
559 p->fname = arg;
560 if (cfg->chain) {
561 for (q = cfg->chain; q->next; q = q->next);
562 q->next = p;
563 }
564 else {
565 cfg->chain = p;
566 }
567 break;
568 }
569
570 return NULL;
571}
572
573static const char *filter_bytype1(cmd_parms *cmd, void *CFG,
574 const char *pname, const char **types)
575{
576 const char *rv;
577 const char *fname;
578 int seen_name = 0;
579 mod_filter_cfg *cfg = CFG;
580
581 /* construct fname from name */
582 fname = apr_pstrcat(cmd->pool, "BYTYPE:", pname, NULL);
583
584 /* check whether this is already registered, in which case
585 * it's already in the filter chain
586 */
588 seen_name = 1;
589 }
590
591 rv = add_filter(cmd, CFG, fname, pname, NULL, types);
592
593 /* If it's the first time through, add to filterchain */
594 if (rv == NULL && !seen_name) {
595 rv = filter_chain(cmd, CFG, fname);
596 }
597 return rv;
598}
599
600static const char *filter_bytype(cmd_parms *cmd, void *CFG,
601 int argc, char *const argv[])
602{
603 /* back compatibility, need to parse multiple components in filter name */
604 char *pname;
605 char *strtok_state = NULL;
606 char *name;
607 const char **types;
608 const char *rv = NULL;
609 if (argc < 2)
610 return "AddOutputFilterByType requires at least two arguments";
611 name = apr_pstrdup(cmd->temp_pool, argv[0]);
612 types = apr_palloc(cmd->pool, argc * sizeof(char *));
613 memcpy(types, &argv[1], (argc - 1) * sizeof(char *));
614 types[argc-1] = NULL;
615 for (pname = apr_strtok(name, ";", &strtok_state);
616 pname != NULL && rv == NULL;
617 pname = apr_strtok(NULL, ";", &strtok_state)) {
618 rv = filter_bytype1(cmd, CFG, pname, types);
619 }
620 return rv;
621}
622
623static const char *filter_debug(cmd_parms *cmd, void *CFG, const char *fname,
624 const char *level)
625{
626 mod_filter_cfg *cfg = CFG;
629 if (!frec) {
630 return apr_psprintf(cmd->pool, "Undeclared smart filter %s", fname);
631 }
632 frec->debug = atoi(level);
633
634 return NULL;
635}
636
638{
640 ap_filter_rec_t *filter;
642 &filter_module);
643#ifndef NO_PROTOCOL
644 int ranges = 1;
646 ap_set_module_config(r->request_config, &filter_module, ctx);
647#endif
648
652 for (p = cfg->chain; p; p = p->next) {
653 if (p->fname == NULL)
654 cfg->chain = p->next;
655 }
656
657 for (p = cfg->chain; p; p = p->next) {
658 filter = apr_hash_get(cfg->live_filters, p->fname, APR_HASH_KEY_STRING);
659 if (filter == NULL) {
661 "Unknown filter %s not added", p->fname);
662 continue;
663 }
665#ifndef NO_PROTOCOL
666 if (ranges && (filter->proto_flags
669 ctx->range = apr_table_get(r->headers_in, "Range");
670 apr_table_unset(r->headers_in, "Range");
671 ranges = 0;
672 }
673#endif
674 }
675}
676
681
682static void *filter_config(apr_pool_t *pool, char *x)
683{
686 cfg->chain = NULL;
687 return cfg;
688}
689
690static void *filter_merge(apr_pool_t *pool, void *BASE, void *ADD)
691{
693 mod_filter_cfg *add = ADD;
698
700 base->live_filters);
701 if (base->chain && add->chain) {
702 for (p = base->chain; p; p = p->next) {
704 if (newlink->fname == NULL) {
705 conf->chain = savelink = newlink;
706 }
707 else if (savelink) {
710 }
711 else {
712 conf->chain = savelink = newlink;
713 }
714 }
715
716 for (p = add->chain; p; p = p->next) {
719 if (newlink->fname == NULL) {
720 conf->chain = savelink = newlink;
721 }
722 else if (savelink) {
725 }
726 else {
727 conf->chain = savelink = newlink;
728 }
729 }
730 }
731 else if (add->chain) {
732 conf->chain = add->chain;
733 }
734 else {
735 conf->chain = base->chain;
736 }
737
738 return conf;
739}
740
741static const command_rec filter_cmds[] = {
742 AP_INIT_TAKE12("FilterDeclare", filter_declare, NULL, OR_OPTIONS,
743 "filter-name [filter-type]"),
744 AP_INIT_TAKE3("FilterProvider", filter_provider, NULL, OR_OPTIONS,
745 "filter-name provider-name match-expression"),
747 "list of filter names with optional [+-=!@]"),
749 "filter-name debug-level"),
750 AP_INIT_TAKE_ARGV("AddOutputFilterByType", filter_bytype, NULL, OR_FILEINFO,
751 "output filter name followed by one or more content-types"),
752#ifndef NO_PROTOCOL
753 AP_INIT_TAKE23("FilterProtocol", filter_protocol, NULL, OR_OPTIONS,
754 "filter-name [provider-name] protocol-args"),
755#endif
756 { NULL }
757};
758
763 NULL,
764 NULL,
767};
Expression parser.
int int const char ** match
Definition ap_regex.h:279
const char apr_size_t len
Definition ap_regex.h:187
APR Hash Tables.
APR general purpose library routines.
APR Strings library.
APR Standard Headers Support.
#define ap_get_module_config(v, m)
#define AP_INIT_TAKE_ARGV(directive, func, mconfig, where, help)
#define AP_DECLARE_MODULE(foo)
ap_conf_vector_t * base
#define AP_INIT_ITERATE(directive, func, mconfig, where, help)
#define ap_set_module_config(v, m, val)
#define AP_INIT_TAKE12(directive, func, mconfig, where, help)
request_rec * r
#define AP_INIT_TAKE3(directive, func, mconfig, where, help)
#define AP_INIT_TAKE23(directive, func, mconfig, where, help)
#define AP_INIT_TAKE2(directive, func, mconfig, where, help)
#define OK
Definition httpd.h:456
#define AP_FILTER_PROTO_CHANGE
#define AP_FILTER_PROTO_NO_BYTERANGE
ap_filter_rec_t * ap_get_output_filter_handle(const char *name)
#define AP_FILTER_PROTO_CHANGE_LENGTH
apr_status_t(* ap_out_filter_func)(ap_filter_t *f, apr_bucket_brigade *b)
apr_status_t ap_pass_brigade(ap_filter_t *filter, apr_bucket_brigade *bucket)
#define AP_FILTER_PROTO_NO_CACHE
#define AP_FILTER_PROTO_TRANSFORM
ap_filter_t * ap_add_output_filter_handle(ap_filter_rec_t *f, void *ctx, request_rec *r, conn_rec *c)
#define AP_FILTER_PROTO_NO_PROXY
void ap_remove_output_filter(ap_filter_t *f)
@ AP_FTYPE_CONTENT_SET
@ AP_FTYPE_NETWORK
@ AP_FTYPE_CONNECTION
@ AP_FTYPE_PROTOCOL
@ AP_FTYPE_RESOURCE
#define APLOGNO(n)
Definition http_log.h:117
#define APLOG_TRACE4
Definition http_log.h:75
#define ap_log_rerror
Definition http_log.h:454
#define APLOG_ERR
Definition http_log.h:67
#define ap_log_cerror
Definition http_log.h:498
#define APLOG_MARK
Definition http_log.h:283
#define APLOG_WARNING
Definition http_log.h:68
#define APLOG_TRACE2
Definition http_log.h:73
#define APLOG_DEBUG
Definition http_log.h:71
void ap_hook_insert_filter(ap_HOOK_insert_filter_t *pf, const char *const *aszPre, const char *const *aszSucc, int nOrder)
Definition request.c:96
void const char * arg
Definition http_vhost.h:63
apr_file_t * f
#define APR_BUCKET_NEXT(e)
#define APR_BRIGADE_SENTINEL(b)
apr_brigade_flush void * ctx
#define APR_BRIGADE_FIRST(b)
const char apr_ssize_t int flags
Definition apr_encode.h:168
#define APR_HOOK_MIDDLE
Definition apr_hooks.h:303
#define ap_expr_parse_cmd(cmd, expr, flags, err, lookup_fn)
Definition ap_expr.h:340
int ap_expr_exec(request_rec *r, const ap_expr_info_t *expr, const char **err)
#define ACCESS_CONF
#define RSRC_CONF
#define OR_FILEINFO
#define OR_OPTIONS
#define HTTP_INTERNAL_SERVER_ERROR
Definition httpd.h:535
#define STANDARD20_MODULE_STUFF
char * ap_strcasestr(const char *s1, const char *s2)
Definition util.c:289
#define AP_DEBUG_ASSERT(exp)
Definition httpd.h:2283
apr_size_t size
const char int apr_pool_t * pool
Definition apr_cstr.h:84
int apr_status_t
Definition apr_errno.h:44
int type
const char * fname
int strcasecmp(const char *a, const char *b)
apr_pool_t int argc
Definition apr_getopt.h:104
#define APR_HASH_KEY_STRING
Definition apr_hash.h:47
apr_vformatter_buff_t * c
Definition apr_lib.h:175
apr_pool_t * b
Definition apr_pools.h:529
#define apr_pcalloc(p, size)
Definition apr_pools.h:465
const char * sep
apr_int32_t apr_int32_t apr_int32_t err
apr_cmdtype_e cmd
Apache Configuration.
Apache Logging library.
Apache Request library.
HTTP Daemon routines.
apr_pool_t * p
Definition md_event.c:32
static apr_status_t filter_harness(ap_filter_t *f, apr_bucket_brigade *bb)
Definition mod_filter.c:274
static const char * add_filter(cmd_parms *cmd, void *CFG, const char *fname, const char *pname, const char *expr, const char **types)
Definition mod_filter.c:435
static const char * filter_bytype1(cmd_parms *cmd, void *CFG, const char *pname, const char **types)
Definition mod_filter.c:573
static int filter_init(ap_filter_t *f)
Definition mod_filter.c:100
static const char * filter_protocol(cmd_parms *cmd, void *CFG, const char *fname, const char *pname, const char *proto)
Definition mod_filter.c:331
static void * filter_config(apr_pool_t *pool, char *x)
Definition mod_filter.c:682
static void * filter_merge(apr_pool_t *pool, void *BASE, void *ADD)
Definition mod_filter.c:690
static void filter_insert(request_rec *r)
Definition mod_filter.c:637
static const char * filter_provider(cmd_parms *cmd, void *CFG, const char *fname, const char *pname, const char *expr)
Definition mod_filter.c:491
static const command_rec filter_cmds[]
Definition mod_filter.c:741
static void filter_hooks(apr_pool_t *pool)
Definition mod_filter.c:677
static const char * filter_chain(cmd_parms *cmd, void *CFG, const char *arg)
Definition mod_filter.c:498
static const char * filter_bytype(cmd_parms *cmd, void *CFG, int argc, char *const argv[])
Definition mod_filter.c:600
static void filter_trace(conn_rec *c, int debug, const char *fname, apr_bucket_brigade *bb)
Definition mod_filter.c:77
static const char * filter_debug(cmd_parms *cmd, void *CFG, const char *fname, const char *level)
Definition mod_filter.c:623
static const char * filter_declare(cmd_parms *cmd, void *CFG, const char *fname, const char *place)
Definition mod_filter.c:402
static int filter_lookup(ap_filter_t *f, ap_filter_rec_t *filter)
Definition mod_filter.c:135
#define debug(stmt)
Definition mod_macro.c:43
const char * argv[3]
static const char *const types[]
return NULL
Definition mod_so.c:359
static char * place(sed_eval_t *eval, char *asp, char *al1, char *al2)
Definition sed1.c:747
char * name
is a filter provider, as defined and implemented by mod_filter.
Definition mod_filter.c:38
const char ** types
Definition mod_filter.c:40
ap_filter_provider_t * next
Definition mod_filter.c:46
ap_expr_info_t * expr
Definition mod_filter.c:39
ap_filter_rec_t * frec
Definition mod_filter.c:43
This structure is used for recording information about the registered filters. It associates a name w...
ap_filter_type ftype
ap_filter_provider_t * providers
ap_init_filter_func filter_init_func
ap_filter_func filter_func
unsigned int proto_flags
struct ap_filter_rec_t * next
const char * name
The representation of a filter chain.
apr_pool_t * pool
Structure to store things which are per connection.
Definition httpd.h:1152
ap_out_filter_func func
Definition mod_filter.c:57
void * fctx
Definition mod_filter.c:58
provider_ctx * init_ctx
Definition mod_filter.c:59
mod_filter_chain * chain
Definition mod_filter.c:69
apr_hash_t * live_filters
Definition mod_filter.c:68
struct mod_filter_chain * next
Definition mod_filter.c:64
const char * fname
Definition mod_filter.c:63
const char * range
Definition mod_filter.c:73
ap_filter_provider_t * provider
Definition mod_filter.c:52
provider_ctx * next
Definition mod_filter.c:54
A structure that represents the current request.
Definition httpd.h:845
const char * content_type
Definition httpd.h:992
const char * hostname
Definition httpd.h:883
apr_pool_t * pool
Definition httpd.h:847
int proxyreq
Definition httpd.h:873
conn_rec * connection
Definition httpd.h:849
struct ap_conf_vector_t * request_config
Definition httpd.h:1049
apr_table_t * headers_in
Definition httpd.h:976
struct ap_conf_vector_t * per_dir_config
Definition httpd.h:1047
apr_table_t * headers_out
Definition httpd.h:978
ap_out_filter_func out_func
#define str
Apache filter library.