]> granicus.if.org Git - apache/commitdiff
Add CGIVar directive for configuring REQUEST_URI behavior
authorJeff Trawick <trawick@apache.org>
Mon, 14 Mar 2016 15:42:45 +0000 (15:42 +0000)
committerJeff Trawick <trawick@apache.org>
Mon, 14 Mar 2016 15:42:45 +0000 (15:42 +0000)
The goal is to use this one directive to handle any configurable
CGI variable behavior; only one CGI variable is supported initially.

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

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

diff --git a/CHANGES b/CHANGES
index b3e2f2b403d05fb20ae0df44b8dc7c9b6719d971..e76fdbdad9a31d98d0536e72e1d5001a202537f0 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,6 +1,10 @@
                                                          -*- coding: utf-8 -*-
 Changes with Apache 2.5.0
 
+  *) core: New CGIVar directive can configure REQUEST_URI to represent the
+     current URI being processed instead of always the original request.
+     [Jeff Trawick]
+
   *) mod_include: Add variable DOCUMENT_ARGS, with the arguments to the
      request for the SSI document.  [Jeff Trawick]
 
index bcf824870123647ee810bd5b051a2d648f5c0fc6..ce9b85a10663c2cb79b603a6cb05ca739f37d0d7 100644 (file)
@@ -627,6 +627,32 @@ variables</description>
 </usage>
 </directivesynopsis>
 
+<directivesynopsis>
+<name>CGIVar</name>
+<description>Controls how some CGI variables are set</description>
+<syntax>CGIVar <var>variable</var> <var>rule</var></syntax>
+<contextlist><context>directory</context><context>.htaccess</context>
+</contextlist>
+<override>FileInfo</override>
+<compatibility>Available in Apache HTTP Server 2.5 and later</compatibility>
+
+<usage>
+  <p>This directive controls how some CGI variables are set.</p>
+
+  <p><strong>REQUEST_URI</strong> rules:</p>
+  <dl>
+    <dt><code>original-uri</code> (default)</dt>
+    <dd>The value is taken from the original request line, and will not
+    reflect internal redirects or subrequests which change the requested
+    resource.</dd>
+    <dt><code>current-uri</code></dt>
+    <dd>The value reflects the resource currently being processed,
+    which may be different than the original request from the client
+    due to internal redirects or subrequests.</dd>
+  </dl>
+</usage>
+</directivesynopsis>
+
 <directivesynopsis>
 <name>ContentDigest</name>
 <description>Enables the generation of <code>Content-MD5</code> HTTP Response
index 1e1882d679518b57768d66ed45f02e47c797f88c..3bd6663657aa6136a497699678a0e06fcaffe40a 100644 (file)
@@ -673,6 +673,9 @@ typedef struct {
 
     unsigned int qualify_redirect_url :2;
     ap_expr_info_t  *expr_handler;         /* forced with SetHandler */
+
+    /** Table of rules for building CGI variables, NULL if none configured */
+    apr_hash_t *cgi_var_rules;
 } core_dir_config;
 
 /* macro to implement off by default behaviour */
index 20ac3d0b2c6d3aba1216127f86878dd20a3b77ec..db003169ba0d5d4c52578f7197ba536d51e19286 100644 (file)
@@ -420,6 +420,15 @@ static void *merge_core_dir_configs(apr_pool_t *a, void *basev, void *newv)
 
     conf->cgi_pass_auth = new->cgi_pass_auth != AP_CGI_PASS_AUTH_UNSET ? new->cgi_pass_auth : base->cgi_pass_auth;
 
+    if (new->cgi_var_rules) {
+        if (!conf->cgi_var_rules) {
+            conf->cgi_var_rules = new->cgi_var_rules;
+        }
+        else {
+            conf->cgi_var_rules = apr_hash_overlay(a, new->cgi_var_rules, conf->cgi_var_rules);
+        }
+    }
+
     AP_CORE_MERGE_FLAG(qualify_redirect_url, conf, base, new);
 
     return (void*)conf;
@@ -1872,6 +1881,31 @@ static const char *set_cgi_pass_auth(cmd_parms *cmd, void *d_, int flag)
     return NULL;
 }
 
+static const char *set_cgi_var(cmd_parms *cmd, void *d_,
+                               const char *var, const char *rule_)
+{
+    core_dir_config *d = d_;
+    char *rule = apr_pstrdup(cmd->pool, rule_);
+
+    ap_str_tolower(rule);
+
+    if (!strcmp(var, "REQUEST_URI")) {
+        if (strcmp(rule, "current-uri") && strcmp(rule, "original-uri")) {
+            return "Valid rules for REQUEST_URI are 'current-uri' and 'original-uri'";
+        }
+    }
+    else {
+        return apr_pstrcat(cmd->pool, "Unrecognized CGI variable: \"",
+                           var, "\"", NULL);
+    }
+
+    if (!d->cgi_var_rules) {
+        d->cgi_var_rules = apr_hash_make(cmd->pool);
+    }
+    apr_hash_set(d->cgi_var_rules, var, APR_HASH_KEY_STRING, rule);
+    return NULL;
+}
+
 static const char *set_qualify_redirect_url(cmd_parms *cmd, void *d_, int flag)
 {
     core_dir_config *d = d_;
@@ -4565,6 +4599,8 @@ AP_INIT_TAKE12("LimitInternalRecursion", set_recursion_limit, NULL, RSRC_CONF,
 AP_INIT_FLAG("CGIPassAuth", set_cgi_pass_auth, NULL, OR_AUTHCFG,
              "Controls whether HTTP authorization headers, normally hidden, will "
              "be passed to scripts"),
+AP_INIT_TAKE2("CGIVar", set_cgi_var, NULL, OR_FILEINFO,
+              "Controls how some CGI variables are set"),
 AP_INIT_FLAG("QualifyRedirectURL", set_qualify_redirect_url, NULL, OR_FILEINFO,
              "Controls whether the REDIRECT_URL environment variable is fully "
              "qualified"),
index b6d361222c5ab93be9cdb7f0104fcc9a3850bb12..ff692b95d9e15ffe89753cdca289021040cec8c6 100644 (file)
@@ -370,12 +370,25 @@ static char *original_uri(request_rec *r)
 AP_DECLARE(void) ap_add_cgi_vars(request_rec *r)
 {
     apr_table_t *e = r->subprocess_env;
+    core_dir_config *conf =
+        (core_dir_config *)ap_get_core_module_config(r->per_dir_config);
+    int request_uri_from_original = 1;
+    const char *request_uri_rule;
 
     apr_table_setn(e, "GATEWAY_INTERFACE", "CGI/1.1");
     apr_table_setn(e, "SERVER_PROTOCOL", r->protocol);
     apr_table_setn(e, "REQUEST_METHOD", r->method);
     apr_table_setn(e, "QUERY_STRING", r->args ? r->args : "");
-    apr_table_setn(e, "REQUEST_URI", original_uri(r));
+
+    if (conf->cgi_var_rules) {
+        request_uri_rule = apr_hash_get(conf->cgi_var_rules, "REQUEST_URI",
+                                        APR_HASH_KEY_STRING);
+        if (request_uri_rule && !strcmp(request_uri_rule, "current-uri")) {
+            request_uri_from_original = 0;
+        }
+    }
+    apr_table_setn(e, "REQUEST_URI",
+                   request_uri_from_original ? original_uri(r) : r->uri);
 
     /* Note that the code below special-cases scripts run from includes,
      * because it "knows" that the sub_request has been hacked to have the