]> granicus.if.org Git - apache/commitdiff
mod_ext_filter: Add the ability to enable or disable a filter via
authorJeff Trawick <trawick@apache.org>
Thu, 1 Aug 2002 23:26:43 +0000 (23:26 +0000)
committerJeff Trawick <trawick@apache.org>
Thu, 1 Aug 2002 23:26:43 +0000 (23:26 +0000)
an environment variable.  Add the ability to register a filter of
type other than AP_FTYPE_RESOURCE.

git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@96283 13f79535-47bb-0310-9956-ffa450edef68

CHANGES
docs/manual/mod/mod_ext_filter.html.en
docs/manual/mod/mod_ext_filter.xml
modules/experimental/mod_ext_filter.c

diff --git a/CHANGES b/CHANGES
index ffc740db477ec69f41fede9858840339576a038f..b7bc31888428a398fc61ea500407dc8fa6ed46e5 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,5 +1,9 @@
 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>]
 
index 13841d687d08990f6d68be89f4d45ffd58f98b67..3a6320b95d9c9ec50fbc05c772a3375786c6d019 100644 (file)
 </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
+
+  &lt;Directory /usr/local/docs&gt;
+    SetEnvIf Remote_Addr 192.168.1.31 trace_this_client
+    SetOutputFilter tracebefore;deflate;traceafter
+  &lt;/Directory&gt;
+</pre>
+Here is the filter which traces the data:
+<pre>
+#!/usr/local/bin/perl -w
+
+use strict;
+
+open(SAVE, "&gt;$ARGV[0]") or die "can't open $ARGV[0]: $?";
+
+while (&lt;STDIN&gt;)
+{
+  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:
index de26a303199be3116fff9f573e9da14f6008c28f..970d84bb6883ab22a133d0b9cc40f146dab0f704 100644 (file)
 </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
+
+  &lt;Directory /usr/local/docs&gt;
+    SetEnvIf Remote_Addr 192.168.1.31 trace_this_client
+    SetOutputFilter tracebefore;deflate;traceafter
+  &lt;/Directory&gt;
+</pre>
+Here is the filter which traces the data:
+<pre>
+#!/usr/local/bin/perl -w
+
+use strict;
+
+open(SAVE, "&gt;$ARGV[0]") or die "can't open $ARGV[0]: $?";
+
+while (&lt;STDIN&gt;)
+{
+  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>
index eafe3adb0659658a3b622987543ec6c5263870f0..fb7bc5fb7338f66fe887c21862b195919a707553 100644 (file)
@@ -84,7 +84,10 @@ typedef struct ef_server_t {
 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) */
@@ -246,6 +249,7 @@ static const char *define_filter(cmd_parms *cmd, void *dummy, const char *args)
     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) {
@@ -286,6 +290,27 @@ static const char *define_filter(cmd_parms *cmd, void *dummy, const char *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);
@@ -314,7 +339,7 @@ static const char *define_filter(cmd_parms *cmd, void *dummy, const char *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) {
@@ -550,6 +575,16 @@ static apr_status_t init_filter_instance(ap_filter_t *f)
             }
         }
     }
+    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) {