On Fri, Aug 2, 2024 at 3:26 PM Eric Covener <[email protected]> wrote:
>
> On Fri, Aug 2, 2024 at 9:10 AM Yann Ylavic <[email protected]> wrote:
> >
> > On Fri, Aug 2, 2024 at 1:06 PM Eric Covener <[email protected]> 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 */