On Fri, Aug 2, 2024 at 3:10 PM Yann Ylavic <ylavic....@gmail.com> wrote:
>
> On Fri, Aug 2, 2024 at 1:06 PM Eric Covener <cove...@gmail.com> wrote:
> >
> > > Yeah, if not under DocumentRoot I don't see how ProxyPass could work,
> > > but SetHandler should since it's following the whole request
> > > processing to resolve the filesystem r->filename?
> >
> > In the examples I am seeing spot-checking google results, people who
> > use ProxyPass + FPM hard-code the document root (or wherever the stuff
> > is) in the 2nd parameter. This includes our own manual and the
> > unofficial confluence wiki.
>
> Ah ok, I think we can do something like this:
>         if (rconf->need_dirwalk) {
>             const char *docroot = ap_document_root(r);
>             if (strncmp(docroot, r->filename, strlen(docroot)) != 0) {
>                 r->proxyreq = PROXYREQ_NONE;
>                 ap_core_translate(r);
>             }
>             ap_directory_walk(r);
>         }
> ?

Full patch (v2).
Index: modules/proxy/mod_proxy_fcgi.c
===================================================================
--- modules/proxy/mod_proxy_fcgi.c	(revision 1919628)
+++ modules/proxy/mod_proxy_fcgi.c	(working copy)
@@ -29,6 +29,7 @@ typedef struct {
 
 typedef struct {
     int need_dirwalk;
+    char *filename;
 } fcgi_req_config_t;
 
 /* We will assume FPM, but still differentiate */
@@ -141,8 +142,10 @@ static int proxy_fcgi_canon(request_rec *r, char *
         rconf = apr_pcalloc(r->pool, sizeof(fcgi_req_config_t));
         ap_set_module_config(r->request_config, &proxy_fcgi_module, rconf);
     }
+    rconf->filename = apr_pstrcat(r->pool, "/", url, NULL);
 
-    if (NULL != (pathinfo_type = apr_table_get(r->subprocess_env, "proxy-fcgi-pathinfo"))) {
+    pathinfo_type = apr_table_get(r->subprocess_env, "proxy-fcgi-pathinfo");
+    if (pathinfo_type) {
         /* It has to be on disk for this to work */
         if (!strcasecmp(pathinfo_type, "full")) {
             rconf->need_dirwalk = 1;
@@ -181,6 +184,9 @@ static int proxy_fcgi_canon(request_rec *r, char *
                     "set r->path_info to %s", r->path_info);
         }
     }
+    else if (FCGI_MAY_BE_FPM(dconf) && !from_handler) {
+        rconf->need_dirwalk = 1;
+    }
 
     return OK;
 }
@@ -359,18 +365,26 @@ static apr_status_t send_environment(proxy_conn_re
     int next_elem, starting_elem;
     fcgi_req_config_t *rconf = ap_get_module_config(r->request_config, &proxy_fcgi_module);
     fcgi_dirconf_t *dconf = ap_get_module_config(r->per_dir_config, &proxy_fcgi_module);
+    char *saved_filename = r->filename;
 
-    if (rconf && rconf->need_dirwalk) {
-        char *saved_filename = r->filename;
-        r->filename = r->uri;
-        ap_directory_walk(r);
-        r->filename = saved_filename;
+    if (rconf) {
+        r->filename = rconf->filename;
+
+        /* To fix/set r->filename/path_info, do now what ProxyPass skipped */
+        if (rconf->need_dirwalk) {
+            const char *docroot = ap_document_root(r);
+            if (strncmp(r->filename, docroot, strlen(docroot)) != 0) {
+                r->proxyreq = PROXYREQ_NONE;
+                ap_core_translate(r);
+            }
+            ap_directory_walk(r);
+        }
     }
-
-    /* Strip proxy: prefixes */
-    if (r->filename) {
+    else if (r->filename) {
         char *newfname = NULL;
 
+        /* Strip proxy: prefixes */
+
         if (!strncmp(r->filename, "proxy:balancer://", 17)) {
             newfname = apr_pstrdup(r->pool, r->filename+17);
         }
@@ -401,6 +415,9 @@ static apr_status_t send_environment(proxy_conn_re
     ap_add_common_vars(r);
     ap_add_cgi_vars(r);
 
+    r->filename = saved_filename;
+    r->proxyreq = PROXYREQ_REVERSE;
+
     /* XXX are there any FastCGI specific env vars we need to send? */
 
     /* Give admins final option to fine-tune env vars */

Reply via email to