On 01/23/2017 09:05 AM, Jim Jagielski wrote:
OK, I was thinking something like this, which tries to "compartmentalize"
it to where we actually create the CGI vars...

Anyone able to test?

This patch doesn't seem to change anything in my limited tests so far. Comments inline:

diff --git a/modules/mappers/mod_actions.c b/modules/mappers/mod_actions.c
index 2a67a2742..efe22f814 100644
--- a/modules/mappers/mod_actions.c
+++ b/modules/mappers/mod_actions.c
@@ -186,7 +186,8 @@ static int action_handler(request_rec *r)
         ap_field_noparam(r->pool, r->content_type);

     if (action && (t = apr_table_get(conf->action_types, action))) {
-        if (*t++ == '0' && r->finfo.filetype == APR_NOFILE) {
+        int virtual = (*t++ == '0' ? 0 : 1);
+        if (!virtual && r->finfo.filetype == APR_NOFILE) {
             ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, APLOGNO(00652)
                           "File does not exist: %s", r->filename);
             return HTTP_NOT_FOUND;
@@ -197,6 +198,9 @@ static int action_handler(request_rec *r)
          * (will be REDIRECT_HANDLER there)
          */
         apr_table_setn(r->subprocess_env, "HANDLER", action);
+        if (virtual) {
+            apr_table_setn(r->subprocess_env, "virtual_script", "1");
+        }
     }

     if (script == NULL)
diff --git a/modules/proxy/mod_proxy_fcgi.c b/modules/proxy/mod_proxy_fcgi.c
index 6f7bda009..ff7f58b90 100644
--- a/modules/proxy/mod_proxy_fcgi.c
+++ b/modules/proxy/mod_proxy_fcgi.c
@@ -141,9 +141,12 @@ static int proxy_fcgi_canon(request_rec *r, char *url)
             if (!strcasecmp(pathinfo_type, "unescape")) {
                 ap_unescape_url_keep2f(r->path_info, 0);
             }
+        }
+        if (r->path_info && *r->path_info) {
             ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01061)
-                    "set r->path_info to %s", r->path_info);
+                          "set r->path_info to %s", r->path_info);
         }
+
     }

     return OK;
diff --git a/server/util_script.c b/server/util_script.c
index 0f12bacc2..0d6ec9313 100644
--- a/server/util_script.c
+++ b/server/util_script.c
@@ -381,6 +381,7 @@ AP_DECLARE(void) ap_add_cgi_vars(request_rec *r)
     core_dir_config *conf =
         (core_dir_config *)ap_get_core_module_config(r->per_dir_config);
     int request_uri_from_original = 1;
+    int path_info_exists = r->path_info && r->path_info[0];
     const char *request_uri_rule;

     apr_table_setn(e, "GATEWAY_INTERFACE", "CGI/1.1");
@@ -406,13 +407,43 @@ AP_DECLARE(void) ap_add_cgi_vars(request_rec *r)

     if (!strcmp(r->protocol, "INCLUDED")) {
         apr_table_setn(e, "SCRIPT_NAME", r->uri);
-        if (r->path_info && *r->path_info) {
+        if (path_info_exists) {
             apr_table_setn(e, "PATH_INFO", r->path_info);
         }
     }
-    else if (!r->path_info || !*r->path_info) {
+    else if (!path_info_exists) {
         apr_table_setn(e, "SCRIPT_NAME", r->uri);
     }
+    /*
+     * Deal with special cases where the scripts are virtual
+     * (external) and we have r->filename of the form:
+     *     proxy:fcgi://127.0.0.1:9000/path/to/test.php/foo/bar/
+     *     proxy:balancer://127.0.0.1:9000/path/to/test.php/foo1/bar2/
+     */
+
+    else if (apr_table_get(e, "virtual_script")) {

By the time we get here for my Action tests, "virtual_script" has already been renamed to "REDIRECT_virtual_script".

+        char *path;
+        char *script;
+        char *scan;
+        script = apr_pstrdup(r->pool, r->path_info);
+        scan = (char *)apr_table_get(e, "CONTENT_TYPE");

What situations lead to CONTENT_TYPE being set to a PATH_INFO delimiter? I'm not sure what this is supposed to do.

+        if (!scan) {
+            scan = ".";
+        }
+        path = ap_strstr(script, scan);
+        if (path) {
+            while (*path && *path != '/') {
+                path++;
+            }
+            if (*path) {
+                *path = '\0';
+                path++;
+            }
+        }
+        apr_table_setn(e, "SCRIPT_NAME", script);
+        apr_table_setn(e, "PATH_INFO", apr_pstrcat(r->pool, "/",
+                       ((path && *path) ? path : ""), NULL));

This appears to give PATH_INFO a leading slash even if there was no slash after the script in the URI.

+    }
     else {
         int path_info_start = ap_find_path_info(r->uri, r->path_info);

@@ -422,7 +453,7 @@ AP_DECLARE(void) ap_add_cgi_vars(request_rec *r)
         apr_table_setn(e, "PATH_INFO", r->path_info);
     }

-    if (r->path_info && r->path_info[0]) {
+    if (path_info_exists) {
         /*
          * To get PATH_TRANSLATED, treat PATH_INFO as a URI path.
          * Need to re-escape it for this, since the entire URI was


Reply via email to