]> granicus.if.org Git - apache/commitdiff
allow expressions to be used in SetHandler. Opt-in with expr= prefix.
authorEric Covener <covener@apache.org>
Sun, 17 Jan 2016 23:40:09 +0000 (23:40 +0000)
committerEric Covener <covener@apache.org>
Sun, 17 Jan 2016 23:40:09 +0000 (23:40 +0000)
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1725149 13f79535-47bb-0310-9956-ffa450edef68

CHANGES
docs/manual/mod/core.xml
include/ap_mmn.h
include/http_core.h
server/core.c

diff --git a/CHANGES b/CHANGES
index 33666a4be574855841e99c8f3833405e2526f727..b13c091ebcc2d661d5ae65f3f197c1a757e023c5 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,6 +1,9 @@
                                                          -*- coding: utf-8 -*-
 Changes with Apache 2.5.0
 
+  *) core: Add expression support to SetHandler.
+     [Eric Covener]
+
   *) mod_proxy_fcgi: Suppress HTTP error 503 and message 01075, 
      "Error dispatching request", when the cause appears to be 
      due to the client closing the connection. 
index 682792083c49f3cf336972700adcfb4e70d20f11..1035178ce218269ba5423ea8a227b25a198c23e1 100644 (file)
@@ -4318,11 +4318,12 @@ header</description>
 <name>SetHandler</name>
 <description>Forces all matching files to be processed by a
 handler</description>
-<syntax>SetHandler <var>handler-name</var>|None</syntax>
+<syntax>SetHandler <var>handler-name</var>|None|expr=<var>expression</var></syntax>
 <contextlist><context>server config</context><context>virtual host</context>
 <context>directory</context><context>.htaccess</context>
 </contextlist>
 <override>FileInfo</override>
+<compatibility>2.5 and later</compatibility>
 
 <usage>
     <p>When placed into an <code>.htaccess</code> file or a
@@ -4359,6 +4360,15 @@ SetHandler imap-file
 &lt;/FilesMatch&gt;
     </highlight>
 
+    <p>String-valued expressions can be used to reference per-request 
+    variables, including backreferences to named regular expressions:</p>
+
+    <highlight language="config">
+&lt;LocationMatch ^/app/(?&lt;sub&gt;[^/]+)/&gt;
+     SetHandler "expr=proxy:unix:/var/run/app_%{env:MATCH_sub}.sock|fcgi://localhost:8080"
+&lt;/FilesMatch&gt;
+    </highlight>
+
     <p>You can override an earlier defined <directive>SetHandler</directive>
     directive by using the value <code>None</code>.</p>
 
index 53e2f1e1b25d7e0f32361aaae9f5d575bbcfff9d..6930e269265055cf0907dd3fb0554db7063996dc 100644 (file)
  * 20150222.6 (2.5.0-dev)  Add async_filter to conn_rec.
  * 20150222.7 (2.5.0-dev)  Add ap_casecmpstr[n]();
  * 20150222.8 (2.5.0-dev)  Add ap_getword_conf2[_nc]();
+ * 20150222.9 (2.5.0-dev)  Add epxr_hander to core_dir_config.
  */
 
 #define MODULE_MAGIC_COOKIE 0x41503235UL /* "AP25" */
index 3ecd5f119f00d0c6d77745bc0200f3fed41322b7..eaff248575c54e5a0c69da13c0c5a733d40b523a 100644 (file)
@@ -646,7 +646,7 @@ typedef struct {
     apr_hash_t *response_code_exprs;
 
     unsigned int qualify_redirect_url :2;
-
+    ap_expr_info_t  *expr_handler;         /* forced with SetHandler expr= */
 } core_dir_config;
 
 /* macro to implement off by default behaviour */
index c9150b443d89836682af35101d9157b6bd284571..1a464c13228dd34e17369d71dfa2dc24d0b5b4b0 100644 (file)
@@ -356,6 +356,9 @@ static void *merge_core_dir_configs(apr_pool_t *a, void *basev, void *newv)
     if (new->handler) {
         conf->handler = new->handler;
     }
+    if (new->expr_handler) {
+        conf->expr_handler = new->expr_handler;
+    }
 
     if (new->output_filters) {
         conf->output_filters = new->output_filters;
@@ -1967,7 +1970,18 @@ static const char *set_sethandler(cmd_parms *cmd,
 {
     core_dir_config *dirconf = d_;
 
-    if (arg_ == ap_strstr_c(arg_, "proxy:unix")) { 
+    if (!strncmp(arg_, "expr=", 5)) {
+        const char *err;
+        dirconf->expr_handler = ap_expr_parse_cmd(cmd, arg_+5,
+                                          AP_EXPR_FLAG_STRING_RESULT,
+                                          &err, NULL);
+        if (err) {
+            return apr_pstrcat(cmd->pool,
+                    "Can't parse expression : ", err, NULL);
+        }
+        return NULL;
+    }
+    else if (arg_ == ap_strstr_c(arg_, "proxy:unix")) { 
         dirconf->handler = arg_;
     }
     else { 
@@ -4644,8 +4658,22 @@ static int core_override_type(request_rec *r)
     if (conf->mime_type && strcmp(conf->mime_type, "none"))
         ap_set_content_type(r, (char*) conf->mime_type);
 
-    if (conf->handler && strcmp(conf->handler, "none"))
+    if (conf->expr_handler) { 
+        const char *err;
+        const char *val;
+        val = ap_expr_str_exec(r, conf->expr_handler, &err);
+        if (err) {
+            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO()
+                          "Can't evaluate handler expression: %s", err);
+            return HTTP_INTERNAL_SERVER_ERROR;
+        }
+        if (strcmp(val, "none")) { 
+            r->handler = apr_pstrdup(r->pool, val);
+        }
+    }
+    else if (conf->handler && strcmp(conf->handler, "none")) { 
         r->handler = conf->handler;
+    }
 
     /* Deal with the poor soul who is trying to force path_info to be
      * accepted within the core_handler, where they will let the subreq