Changes with Apache 2.0.40
+ *) mod_ext_filter: Add the ability to enable or disable a filter via
+ an environment variable. Add the ability to register a filter of
+ type other than AP_FTYPE_RESOURCE. [Jeff Trawick]
+
*) Restore the ability to specify host names on Listen directives.
PR 11030. [Jeff Trawick, David Shane Holden <dpejesh@yahoo.com>]
</code></td></tr></table></blockquote>
+<h3>Tracing another filter</h3>
+<blockquote><table cellpadding="10"><tr><td bgcolor="#eeeeee"><code>
+<pre>
+ # Trace the data read and written by mod_deflate for a particuar
+ # client (IP 192.168.1.31) experiencing compression problems.
+ # This filter will trace what goes into mod_deflate.
+ ExtFilterDefine tracebefore cmd="/bin/tracefilter.pl /tmp/tracebefore" \
+ EnableEnv=trace_this_client
+ # This filter will trace what goes after mod_deflate. Note that without
+ # the ftype parameter, the default filter type of AP_FTYPE_RESOURCE would
+ # cause the filter to be placed *before* mod_deflate in the filter
+ # chain. Giving it a numeric value slightly higher than
+ # AP_FTYPE_CONTENT_SET will ensure that it is placed after mod_deflate.
+ ExtFilterDefine traceafter cmd="/bin/tracefilter.pl /tmp/traceafter" \
+ EnableEnv=trace_this_client ftype=21
+
+ <Directory /usr/local/docs>
+ SetEnvIf Remote_Addr 192.168.1.31 trace_this_client
+ SetOutputFilter tracebefore;deflate;traceafter
+ </Directory>
+</pre>
+Here is the filter which traces the data:
+<pre>
+#!/usr/local/bin/perl -w
+
+use strict;
+
+open(SAVE, ">$ARGV[0]") or die "can't open $ARGV[0]: $?";
+
+while (<STDIN>)
+{
+ print SAVE $_;
+ print $_;
+}
+
+close(SAVE);
+</pre>
+</code></td></tr></table></blockquote>
+
+
<hr/><h2><a name="ExtFilterDefine">ExtFilterDefine</a> <a name="extfilterdefine">Directive</a></h2><table cellpadding="1" cellspacing="0" border="0" bgcolor="#cccccc"><tr><td><table bgcolor="#ffffff"><tr><td nowrap="nowrap"><strong>Description:
</strong></td><td/></tr><tr><td nowrap="nowrap"><a href="directive-dict.html#Syntax" class="help">Syntax:
</a></td><td>ExtFilterDefine <em>filtername</em> <em>parameters</em></td></tr><tr><td nowrap="nowrap"><a href="directive-dict.html#Context" class="help">Context:
default, as most filters change the content length. In the
event that the filter doesn't modify the length, this keyword
should be specified.</dd>
+
+ <dt>ftype=<em>filtertype</em></dt>
+
+ <dd>This parameter specifies the numeric value for filter type
+ that the filter should be registered as. The default value,
+ AP_FTYPE_RESOURCE, is sufficient in most cases. If the filter
+ needs to operate at a different point in the filter chain than
+ resource filters, then this parameter will be necessary. See
+ the AP_FTYPE_foo definitions in util_filter.h for appropriate
+ values.</dd>
+
+ <dt>disableenv=<em>env</em></dt>
+
+ <dd>This parameter specifies the name of an environment variable
+ which, if set, will disable the filter.</dd>
+
+ <dt>enableenv=<em>env</em></dt>
+
+ <dd>This parameter specifies the name of an environment variable
+ which must be set, or the filter will be disabled.</dd>
+
</dl>
<hr/><h2><a name="ExtFilterOptions">ExtFilterOptions</a> <a name="extfilteroptions">Directive</a></h2><table cellpadding="1" cellspacing="0" border="0" bgcolor="#cccccc"><tr><td><table bgcolor="#ffffff"><tr><td nowrap="nowrap"><strong>Description:
</strong></td><td/></tr><tr><td nowrap="nowrap"><a href="directive-dict.html#Syntax" class="help">Syntax:
</example>
</section>
+<section><title>Tracing another filter</title>
+<example>
+<pre>
+ # Trace the data read and written by mod_deflate for a particuar
+ # client (IP 192.168.1.31) experiencing compression problems.
+ # This filter will trace what goes into mod_deflate.
+ ExtFilterDefine tracebefore cmd="/bin/tracefilter.pl /tmp/tracebefore" \
+ EnableEnv=trace_this_client
+ # This filter will trace what goes after mod_deflate. Note that without
+ # the ftype parameter, the default filter type of AP_FTYPE_RESOURCE would
+ # cause the filter to be placed *before* mod_deflate in the filter
+ # chain. Giving it a numeric value slightly higher than
+ # AP_FTYPE_CONTENT_SET will ensure that it is placed after mod_deflate.
+ ExtFilterDefine traceafter cmd="/bin/tracefilter.pl /tmp/traceafter" \
+ EnableEnv=trace_this_client ftype=21
+
+ <Directory /usr/local/docs>
+ SetEnvIf Remote_Addr 192.168.1.31 trace_this_client
+ SetOutputFilter tracebefore;deflate;traceafter
+ </Directory>
+</pre>
+Here is the filter which traces the data:
+<pre>
+#!/usr/local/bin/perl -w
+
+use strict;
+
+open(SAVE, ">$ARGV[0]") or die "can't open $ARGV[0]: $?";
+
+while (<STDIN>)
+{
+ print SAVE $_;
+ print $_;
+}
+
+close(SAVE);
+</pre>
+</example>
+</section>
+
</section> <!-- Examples -->
<directivesynopsis>
default, as most filters change the content length. In the
event that the filter doesn't modify the length, this keyword
should be specified.</dd>
+
+ <dt>ftype=<em>filtertype</em></dt>
+
+ <dd>This parameter specifies the numeric value for filter type
+ that the filter should be registered as. The default value,
+ AP_FTYPE_RESOURCE, is sufficient in most cases. If the filter
+ needs to operate at a different point in the filter chain than
+ resource filters, then this parameter will be necessary. See
+ the AP_FTYPE_foo definitions in util_filter.h for appropriate
+ values.</dd>
+
+ <dt>disableenv=<em>env</em></dt>
+
+ <dd>This parameter specifies the name of an environment variable
+ which, if set, will disable the filter.</dd>
+
+ <dt>enableenv=<em>env</em></dt>
+
+ <dd>This parameter specifies the name of an environment variable
+ which must be set, or the filter will be disabled.</dd>
+
</dl>
</usage>
</directivesynopsis>
typedef struct ef_filter_t {
const char *name;
enum {INPUT_FILTER=1, OUTPUT_FILTER} mode;
+ ap_filter_type ftype;
const char *command;
+ const char *enable_env;
+ const char *disable_env;
int numArgs;
char *args[30];
const char *intype; /* list of IMTs we process (well, just one for now) */
filter = (ef_filter_t *)apr_pcalloc(conf->p, sizeof(ef_filter_t));
filter->name = name;
filter->mode = OUTPUT_FILTER;
+ filter->ftype = AP_FTYPE_RESOURCE;
apr_hash_set(conf->h, name, APR_HASH_KEY_STRING, filter);
while (*args) {
continue;
}
+ if (!strncasecmp(args, "ftype=", 6)) {
+ args += 6;
+ token = ap_getword_white(cmd->pool, &args);
+ filter->ftype = atoi(token);
+ continue;
+ }
+
+ if (!strncasecmp(args, "enableenv=", 10)) {
+ args += 10;
+ token = ap_getword_white(cmd->pool, &args);
+ filter->enable_env = token;
+ continue;
+ }
+
+ if (!strncasecmp(args, "disableenv=", 11)) {
+ args += 11;
+ token = ap_getword_white(cmd->pool, &args);
+ filter->disable_env = token;
+ continue;
+ }
+
if (!strncasecmp(args, "intype=", 7)) {
args += 7;
filter->intype = ap_getword_white(cmd->pool, &args);
*/
if (filter->mode == OUTPUT_FILTER) {
/* XXX need a way to ensure uniqueness among all filters */
- ap_register_output_filter(filter->name, ef_output_filter, NULL, AP_FTYPE_RESOURCE);
+ ap_register_output_filter(filter->name, ef_output_filter, NULL, filter->ftype);
}
#if 0 /* no input filters yet */
else if (filter->mode == INPUT_FILTER) {
}
}
}
+ if (ctx->filter->enable_env &&
+ !apr_table_get(f->r->subprocess_env, ctx->filter->enable_env)) {
+ /* an environment variable that enables the filter isn't set; bail */
+ ctx->noop = 1;
+ }
+ if (ctx->filter->disable_env &&
+ apr_table_get(f->r->subprocess_env, ctx->filter->disable_env)) {
+ /* an environment variable that disables the filter is set; bail */
+ ctx->noop = 1;
+ }
if (!ctx->noop) {
rv = init_ext_filter_process(f);
if (rv != APR_SUCCESS) {