summaryrefslogtreecommitdiffstats
path: root/modules/proxy
diff options
context:
space:
mode:
authorYann Ylavic <ylavic@apache.org>2024-10-10 17:42:49 +0200
committerYann Ylavic <ylavic@apache.org>2024-10-10 17:42:49 +0200
commitc717758efb3ea1a20c4aea6a7d64d3994a14a2ff (patch)
tree0b7ddbbdf45f4097a9995f322220c744ba36ca29 /modules/proxy
parentmod_proxy_fgci: Follow up to r1919628: Simplify. (diff)
downloadapache2-c717758efb3ea1a20c4aea6a7d64d3994a14a2ff.tar.xz
apache2-c717758efb3ea1a20c4aea6a7d64d3994a14a2ff.zip
mod_proxy_fggi: Follow up to r1919547: Accurate dirwalk for proxy-fcgi-pathinfo=full
Use the proxied uri-path, and try to resolve the script's path first without then with the DocumentRoot prefix. git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1921238 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'modules/proxy')
-rw-r--r--modules/proxy/mod_proxy_fcgi.c64
1 files changed, 50 insertions, 14 deletions
diff --git a/modules/proxy/mod_proxy_fcgi.c b/modules/proxy/mod_proxy_fcgi.c
index df8242a121..d5a5259696 100644
--- a/modules/proxy/mod_proxy_fcgi.c
+++ b/modules/proxy/mod_proxy_fcgi.c
@@ -28,7 +28,7 @@ typedef struct {
} sei_entry;
typedef struct {
- int need_dirwalk;
+ char *dirwalk_uri_path;
} fcgi_req_config_t;
/* We will assume FPM, but still differentiate */
@@ -141,11 +141,13 @@ static int proxy_fcgi_canon(request_rec *r, char *url)
rconf = apr_pcalloc(r->pool, sizeof(fcgi_req_config_t));
ap_set_module_config(r->request_config, &proxy_fcgi_module, rconf);
}
+ rconf->dirwalk_uri_path = 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;
+ rconf->dirwalk_uri_path = apr_pstrcat(r->pool, "/", url, NULL);
}
else if (!strcasecmp(pathinfo_type, "first-dot")) {
char *split = ap_strchr(path, '.');
@@ -359,16 +361,45 @@ static apr_status_t send_environment(proxy_conn_rec *conn, request_rec *r,
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;
+
+ /* Resolve SCRIPT_NAME/FILENAME from the filesystem? */
+ if (rconf && rconf->dirwalk_uri_path) {
+ char *saved_uri = r->uri;
+ char *saved_path_info = r->path_info;
+ char *saved_canonical_filename = r->canonical_filename;
+ int saved_filetype = r->finfo.filetype;
+ int i = 0;
+
+ r->proxyreq = PROXYREQ_NONE;
+ do {
+ r->path_info = NULL;
+ r->finfo.filetype = APR_NOFILE;
+ r->uri = r->filename = r->canonical_filename = rconf->dirwalk_uri_path;
+ /* Try without than with DocumentRoot prefix */
+ if (i && ap_core_translate(r) != OK) {
+ continue;
+ }
+ ap_directory_walk(r);
+ } while (r->finfo.filetype != APR_REG && ++i < 2);
+ r->proxyreq = PROXYREQ_REVERSE;
+
+ /* If no actual script was found, fall back to the "proxy:"
+ * SCRIPT_FILENAME dealt with below or by FPM directly.
+ */
+ if (r->finfo.filetype != APR_REG) {
+ r->filename = proxy_filename;
+ r->canonical_filename = saved_canonical_filename;
+ r->finfo.filetype = saved_filetype;
+ r->path_info = saved_path_info;
+ }
- if (rconf && rconf->need_dirwalk) {
- char *saved_filename = r->filename;
- r->filename = r->uri;
- ap_directory_walk(r);
- r->filename = saved_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)) {
@@ -383,9 +414,12 @@ static apr_status_t send_environment(proxy_conn_rec *conn, request_rec *r,
*/
newfname = apr_pstrdup(r->pool, r->filename+13);
}
- /* Query string in environment only */
+
+ /* Strip potential query string (nocanon) from SCRIPT_FILENAME
+ * if it's the same as QUERY_STRING.
+ */
if (newfname && r->args && *r->args) {
- char *qs = strrchr(newfname, '?');
+ char *qs = strchr(newfname, '?');
if (qs && !strcmp(qs+1, r->args)) {
*qs = '\0';
}
@@ -393,14 +427,16 @@ static apr_status_t send_environment(proxy_conn_rec *conn, request_rec *r,
}
if (newfname) {
- newfname = ap_strchr(newfname, '/');
- r->filename = newfname;
+ r->filename = ap_strchr(newfname, '/');
}
}
ap_add_common_vars(r);
ap_add_cgi_vars(r);
+ /* SCRIPT_NAME/FILENAME set, restore original */
+ 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 */