On Fri, Aug 2, 2024 at 3:26 PM Eric Covener <cove...@gmail.com> wrote: > > On Fri, Aug 2, 2024 at 9:10 AM 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); > > } > > ? > > I think users could be happily humming along with some other absolute > filesystem path in the ProxyPass 2nd arg and would now see it > docroot-prefixed. > Are you trying to make the ProxyPass+FPM vars better because they will > no longer be fixed up by apache_was_here side effects? I think it is > probably bes to just retain/restore some of the historical bogus > values if MAY_BE_FPM -- maybe doing them at the last moment where we'd > do the above.
Maybe this: if (rconf) { if (!rconf->need_dirwalk) { r->filename = rconf->filename; } else { char *saved_uri = r->uri; char *saved_path_info = r->path_info; int i = 0; /* Try to find the script without DocumentRoot than with */ do { r->path_info = NULL; r->filename = r->uri = rconf->filename; if (i) { r->proxyreq = PROXYREQ_NONE; ap_core_translate(r); r->proxyreq = PROXYREQ_REVERSE; } ap_directory_walk(r); } while (r->finfo.filetype != APR_REG && ++i < 2); /* If no actual script was found, fall back to the "proxy:" * SCRIPT_FILENAME dealt with below or by php-fpm directly. */ if (i == 2) { r->path_info = saved_path_info; r->filename = proxy_filename; } /* Restore REQUEST_URI in any case */ r->uri = saved_uri; } } ?
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,16 +365,43 @@ 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 *proxy_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) { + if (!rconf->need_dirwalk) { + r->filename = rconf->filename; + } + else { + char *saved_uri = r->uri; + char *saved_path_info = r->path_info; + int i = 0; + + /* Try to find the script without DocumentRoot than with */ + do { + r->path_info = NULL; + r->filename = r->uri = rconf->filename; + if (i) { + r->proxyreq = PROXYREQ_NONE; + ap_core_translate(r); + r->proxyreq = PROXYREQ_REVERSE; + } + ap_directory_walk(r); + } while (r->finfo.filetype != APR_REG && ++i < 2); + + /* If no actual script was found, fall back to the "proxy:" + * SCRIPT_FILENAME dealt with below or by php-fpm directly. + */ + if (i == 2) { + r->path_info = saved_path_info; + r->filename = proxy_filename; + } + /* Restore REQUEST_URI in any case */ + r->uri = saved_uri; + } } - /* Strip proxy: prefixes */ - if (r->filename) { + /* Strip "proxy:" prefixes? */ + if (r->filename == proxy_filename) { char *newfname = NULL; if (!strncmp(r->filename, "proxy:balancer://", 17)) { @@ -401,6 +434,8 @@ static apr_status_t send_environment(proxy_conn_re ap_add_common_vars(r); ap_add_cgi_vars(r); + r->filename = proxy_filename; + /* XXX are there any FastCGI specific env vars we need to send? */ /* Give admins final option to fine-tune env vars */