]> granicus.if.org Git - apache/commitdiff
Merge r1647035 from trunk:
authorEric Covener <covener@apache.org>
Wed, 14 Jan 2015 13:28:47 +0000 (13:28 +0000)
committerEric Covener <covener@apache.org>
Wed, 14 Jan 2015 13:28:47 +0000 (13:28 +0000)
provide alternative PATH_INFO calculation options for proxy_fcgi.
PR 55329

git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1651663 13f79535-47bb-0310-9956-ffa450edef68

CHANGES
docs/manual/mod/mod_proxy_fcgi.xml
modules/proxy/mod_proxy_fcgi.c

diff --git a/CHANGES b/CHANGES
index 8714492413d6bb57ed83de5de053f58cdc04370d..3b2282233b21eacc2290bac728cc82273d3c7122 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -22,6 +22,10 @@ Changes with Apache 2.4.11
      request headers earlier.  Adds "MergeTrailers" directive to restore
      legacy behavior.  [Edward Lu, Yann Ylavic, Joe Orton, Eric Covener]
 
+  *) mod_proxy_fcgi: Provide some basic alternate options for specifying 
+     how PATH_INFO is passed to FastCGI backends by adding significance to
+     the value of proxy-fcgi-pathinfo. PR 55329. [Eric Covener]
   *) mod_proxy_fcgi: Enable UDS backends configured with SetHandler/RewriteRule
      to opt-in to connection reuse and other Proxy options via explicitly
      declared "proxy workers" (<Proxy unix:... enablereuse=on max=...)
index 6fddb4403ceebdba7fa2d8996577be441db6e86a..3c4d0760233f2ef38948ea4fc79c6f2621d0a2c7 100644 (file)
@@ -150,7 +150,27 @@ ProxyPass /myapp/ balancer://myappcluster/
         and <var>Script-URI</var> and be compliant with RFC 3875 section 3.3.
         If instead you need <module>mod_proxy_fcgi</module> to generate
         a "best guess" for <var>PATH_INFO</var>, set this env-var.
-        This is a workaround for a bug in some FCGI implementations.</dd>
+        This is a workaround for a bug in some FCGI implementations.  This
+        variable can be set to multiple values to tweak at how the best guess
+        is chosen:
+        <dl>
+          <dt>first-dot</dt>
+          <dd>PATH_INFO is split from the slash following the 
+              <em>first</em> "." in the URL.</dd>
+          <dt>last-dot</dt>
+          <dd>PATH_INFO is split from the slash following the 
+              <em>last</em> "." in the URL.</dd>
+          <dt>full</dt> 
+          <dd>PATH_INFO is calculated by an attempt to map the URL to the 
+              local filesystem.</dd>
+          <dt>unescape</dt>
+          <dd>PATH_INFO is the path component of the URL, unescaped / 
+              decoded.</dd>
+          <dt>any other value</dt>
+          <dd>PATH_INFO is the same as the path component of the URL.  
+              Originally, this was the only proxy-fcgi-pathinfo option.</dd>
+         </dl>
+        </dd>
     </dl>
 </section>
 
index 54a4e8dc4813a07c6e4a882fc71109bb120683af..f528b3dfddc59afd5fcff04c4ac190b8f95d10d9 100644 (file)
 
 module AP_MODULE_DECLARE_DATA proxy_fcgi_module;
 
+typedef struct {
+    int need_dirwalk;
+} fcgi_req_config_t;
+
 /*
  * Canonicalise http-like URLs.
  * scheme is the scheme for the URL
@@ -29,8 +33,11 @@ module AP_MODULE_DECLARE_DATA proxy_fcgi_module;
 static int proxy_fcgi_canon(request_rec *r, char *url)
 {
     char *host, sport[7];
-    const char *err, *path;
+    const char *err;
+    char *path;
     apr_port_t port, def_port;
+    fcgi_req_config_t *rconf = NULL;
+    const char *pathinfo_type = NULL;
 
     if (strncasecmp(url, "fcgi:", 5) == 0) {
         url += 5;
@@ -76,11 +83,51 @@ static int proxy_fcgi_canon(request_rec *r, char *url)
     ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01060)
                   "set r->filename to %s", r->filename);
 
-    if (apr_table_get(r->subprocess_env, "proxy-fcgi-pathinfo")) {
-        r->path_info = apr_pstrcat(r->pool, "/", path, NULL);
+    rconf = ap_get_module_config(r->request_config, &proxy_fcgi_module);
+    if (rconf == NULL) { 
+        rconf = apr_pcalloc(r->pool, sizeof(fcgi_req_config_t));
+        ap_set_module_config(r->request_config, &proxy_fcgi_module, rconf);
+    }
 
-        ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01061)
-                      "set r->path_info to %s", r->path_info);
+    if (NULL != (pathinfo_type = apr_table_get(r->subprocess_env, "proxy-fcgi-pathinfo"))) {
+        /* It has to be on disk for this to work */
+        if (!strcasecmp(pathinfo_type, "full")) { 
+            rconf->need_dirwalk = 1;
+            ap_unescape_url_keep2f(path, 0);
+        }
+        else if (!strcasecmp(pathinfo_type, "first-dot")) { 
+            char *split = ap_strchr(path, '.');
+            if (split) { 
+                char *slash = ap_strchr(split, '/');
+                if (slash) { 
+                    r->path_info = apr_pstrdup(r->pool, slash);
+                    ap_unescape_url_keep2f(r->path_info, 0);
+                    *slash = '\0'; /* truncate path */
+                }
+            }
+        }
+        else if (!strcasecmp(pathinfo_type, "last-dot")) { 
+            char *split = ap_strrchr(path, '.');
+            if (split) { 
+                char *slash = ap_strchr(split, '/');
+                if (slash) { 
+                    r->path_info = apr_pstrdup(r->pool, slash);
+                    ap_unescape_url_keep2f(r->path_info, 0);
+                    *slash = '\0'; /* truncate path */
+                }
+            }
+        }
+        else { 
+            /* before proxy-fcgi-pathinfo had multi-values. This requires the
+             * the FCGI server to fixup PATH_INFO because it's the entire path
+             */
+            r->path_info = apr_pstrcat(r->pool, "/", path, NULL);
+            if (!strcasecmp(pathinfo_type, "unescape")) { 
+                ap_unescape_url_keep2f(r->path_info, 0);
+            }
+            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01061)
+                    "set r->path_info to %s", r->path_info);
+        }
     }
 
     return OK;
@@ -205,12 +252,19 @@ static apr_status_t send_environment(proxy_conn_rec *conn, request_rec *r,
     apr_size_t avail_len, len, required_len;
     int next_elem, starting_elem;
     char *proxyfilename = r->filename;
+    fcgi_req_config_t *rconf = ap_get_module_config(r->request_config, &proxy_fcgi_module);
+
+    if (rconf) { 
+       if (rconf->need_dirwalk) { 
+          ap_directory_walk(r);
+       }
+    }
 
     /* Strip balancer prefix */
     if (r->filename && !strncmp(r->filename, "proxy:balancer://", 17)) { 
         char *newfname = apr_pstrdup(r->pool, r->filename+17);
         newfname = ap_strchr(newfname, '/');
-        r->filename  = newfname;
+        r->filename = newfname;
     }
 
     ap_add_common_vars(r);