httpd-cvs mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From n..@apache.org
Subject svn commit: r808240 - in /httpd/httpd/trunk: CHANGES docs/manual/mod/mod_headers.xml modules/metadata/mod_headers.c
Date Thu, 27 Aug 2009 01:02:42 GMT
Author: niq
Date: Thu Aug 27 01:02:42 2009
New Revision: 808240

URL: http://svn.apache.org/viewvc?rev=808240&view=rev
Log:
mod_headers: generalise the envclause to support conditional
header rules via ap_expr.

Modified:
    httpd/httpd/trunk/CHANGES
    httpd/httpd/trunk/docs/manual/mod/mod_headers.xml
    httpd/httpd/trunk/modules/metadata/mod_headers.c

Modified: httpd/httpd/trunk/CHANGES
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/CHANGES?rev=808240&r1=808239&r2=808240&view=diff
==============================================================================
--- httpd/httpd/trunk/CHANGES [utf-8] (original)
+++ httpd/httpd/trunk/CHANGES [utf-8] Thu Aug 27 01:02:42 2009
@@ -2,6 +2,9 @@
 
 Changes with Apache 2.3.3
 
+  *) mod_headers: generalise the envclause to support expression
+     evaluation with ap_expr parser [Nick Kew]
+
   *) mod_cache: Introduce the thundering herd lock, a mechanism to keep
      the flood of requests at bay that strike a backend webserver as
      a cached entity goes stale. [Graham Leggett]

Modified: httpd/httpd/trunk/docs/manual/mod/mod_headers.xml
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/docs/manual/mod/mod_headers.xml?rev=808240&r1=808239&r2=808240&view=diff
==============================================================================
--- httpd/httpd/trunk/docs/manual/mod/mod_headers.xml (original)
+++ httpd/httpd/trunk/docs/manual/mod/mod_headers.xml Thu Aug 27 01:02:42 2009
@@ -181,6 +181,12 @@
           Cache-Control: no-cache, no-cache, no-store
         </example>
       </li>
+      <li>
+        Set a test cookie if and only if the client didn't send us a cookie
+        <example>
+          Header set Set-Cookie testcookie !$req{Cookie}
+        </example>
+      </li>
     </ol>
 </section>
 
@@ -258,15 +264,20 @@
     replacement string respectively.</p>
 
     <p>The <directive>RequestHeader</directive> directive may be followed
by
-    an additional argument, which may be used to specify conditions under
-    which the action will be taken, or may be the keyword <code>early</code>
-    to specify <a href="#early">early processing</a>. If the
-    <a href="../env.html">environment
-    variable</a> specified in the <code>env=<var>...</var></code>
argument
-    exists (or if the environment variable does not exist and
-    <code>env=!<var>...</var></code> is specified) then the action
specified
-    by the <directive>RequestHeader</directive> directive will take effect.
-    Otherwise, the directive will have no effect on the request.</p>
+    an additional argument, which may be any of:</p>
+    <dl>
+    <dt><code>early</code></dt>
+    <dd>Specifies <a href="#early">early processing</a>.</dd>
+    <dt><code>env=[!]varname</code></dt>
+    <dd>The directive is applied if and only if the <a href="../env.html"
+        >environment variable</a> <code>varname</code> exists.
+        A <code>!</code> in front of <code>varname</code> reverses
the test,
+        so the directive applies only if <code>varname</code> is unset.</dd>
+    <dt><code>expr</code></dt>
+    <dd>An string that matches neither of the above is parsed as an
+        expression.  Details of expression syntax and evaluation are
+        currently best documented on the <module>mod_filter</module> page.</dd>
+    </dl>
 
     <p>Except in <a href="#early">early</a> mode, the
     <directive>RequestHeader</directive> directive is processed
@@ -404,16 +415,21 @@
     which is a <glossary ref="regex">regular expression</glossary>,
     and an additional <var>replacement</var> string.</p>
 
-    <p>The <directive>Header</directive> directive may be followed by an
-    an additional argument, which may be used to specify conditions under
-    which the action will be taken, or may be the keyword <code>early</code>
-    to specify <a href="#early">early processing</a>. If the
-    <a href="../env.html">environment variable</a> specified in the
-    <code>env=<var>...</var></code> argument exists (or if the environment
-    variable does not exist and <code>env=!<var>...</var></code>
is specified)
-    then the action specified by the <directive>Header</directive> directive
-    will take effect. Otherwise, the directive will have no effect
-    on the request.</p>
+    <p>The <directive>Header</directive> directive may be followed by
+    an additional argument, which may be any of:</p>
+    <dl>
+    <dt><code>early</code></dt>
+    <dd>Specifies <a href="#early">early processing</a>.</dd>
+    <dt><code>env=[!]varname</code></dt>
+    <dd>The directive is applied if and only if the <a href="../env.html"
+        >environment variable</a> <code>varname</code> exists.
+        A <code>!</code> in front of <code>varname</code> reverses
the test,
+        so the directive applies only if <code>varname</code> is unset.</dd>
+    <dt><code>expr</code></dt>
+    <dd>An string that matches neither of the above is parsed as an
+        expression.  Details of expression syntax and evaluation are
+        currently best documented on the <module>mod_filter</module> page.</dd>
+    </dl>
 
     <p>Except in <a href="#early">early</a> mode, the
     <directive>Header</directive> directives are processed just

Modified: httpd/httpd/trunk/modules/metadata/mod_headers.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/metadata/mod_headers.c?rev=808240&r1=808239&r2=808240&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/metadata/mod_headers.c (original)
+++ httpd/httpd/trunk/modules/metadata/mod_headers.c Thu Aug 27 01:02:42 2009
@@ -81,6 +81,7 @@
 #include "http_log.h"
 #include "util_filter.h"
 #include "http_protocol.h"
+#include "ap_expr.h"
 
 #include "mod_ssl.h" /* for the ssl_var_lookup optional function defn */
 
@@ -125,6 +126,7 @@
     ap_regex_t *regex;
     const char *condition_var;
     const char *subs;
+    ap_parse_node_t *expr;
 } header_entry;
 
 /* echo_do is used for Header echo to iterate through the request headers*/
@@ -391,6 +393,7 @@
     const char *condition_var = NULL;
     const char *colon;
     header_entry *new;
+    ap_parse_node_t *expr = NULL;
 
     apr_array_header_t *fixup = (cmd->info == &hdr_in)
         ? dirconf->fixup_in   : (cmd->info == &hdr_err)
@@ -472,10 +475,7 @@
         if (strcasecmp(envclause, "early") == 0) {
             condition_var = condition_early;
         }
-        else {
-            if (strncasecmp(envclause, "env=", 4) != 0) {
-                return "error: envclause should be in the form env=envar";
-            }
+        else if (strncasecmp(envclause, "env=", 4) == 0) {
             if ((envclause[4] == '\0')
                 || ((envclause[4] == '!') && (envclause[5] == '\0'))) {
                 return "error: missing environment variable name. "
@@ -483,6 +483,13 @@
             }
             condition_var = envclause + 4;
         }
+        else {
+            int err = 0;
+            expr = ap_expr_parse(cmd->pool, envclause, &err);
+            if (err) {
+                return "Can't parse envclause/expression";
+            }
+        }
     }
 
     if ((colon = ap_strchr_c(hdr, ':'))) {
@@ -491,6 +498,7 @@
 
     new->header = hdr;
     new->condition_var = condition_var;
+    new->expr = expr;
 
     return parse_format_string(cmd->pool, new, value);
 }
@@ -620,6 +628,19 @@
         else if (early && (envar != condition_early)) {
             continue;
         }
+        /* Do we have an expression to evaluate? */
+        else if (hdr->expr != NULL) {
+            int err = 0;
+            int eval = ap_expr_eval(r, hdr->expr, &err, NULL,
+                                    ap_expr_string, NULL);
+            if (err) {
+                ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
+                              "Failed to evaluate expression - ignoring");
+            }
+            else if (!eval) {
+                continue;
+            }
+        }
         /* Have any conditional envar-controlled Header processing to do? */
         else if (envar && !early) {
             if (*envar != '!') {



Mime
View raw message