OK, I was thinking something like this, which tries to "compartmentalize" it to where we actually create the CGI vars...
Anyone able to test? 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")) { + char *path; + char *script; + char *scan; + script = apr_pstrdup(r->pool, r->path_info); + scan = (char *)apr_table_get(e, "CONTENT_TYPE"); + 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)); + } 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