Skip to content

Commit b5e7cf3

Browse files
committed
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
1 parent 628711b commit b5e7cf3

File tree

1 file changed

+50
-14
lines changed

1 file changed

+50
-14
lines changed

modules/proxy/mod_proxy_fcgi.c

Lines changed: 50 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ typedef struct {
2828
} sei_entry;
2929

3030
typedef struct {
31-
int need_dirwalk;
31+
char *dirwalk_uri_path;
3232
} fcgi_req_config_t;
3333

3434
/* We will assume FPM, but still differentiate */
@@ -128,11 +128,13 @@ static int proxy_fcgi_canon(request_rec *r, char *url)
128128
rconf = apr_pcalloc(r->pool, sizeof(fcgi_req_config_t));
129129
ap_set_module_config(r->request_config, &proxy_fcgi_module, rconf);
130130
}
131+
rconf->dirwalk_uri_path = NULL;
131132

132-
if (NULL != (pathinfo_type = apr_table_get(r->subprocess_env, "proxy-fcgi-pathinfo"))) {
133+
pathinfo_type = apr_table_get(r->subprocess_env, "proxy-fcgi-pathinfo");
134+
if (pathinfo_type) {
133135
/* It has to be on disk for this to work */
134136
if (!strcasecmp(pathinfo_type, "full")) {
135-
rconf->need_dirwalk = 1;
137+
rconf->dirwalk_uri_path = apr_pstrcat(r->pool, "/", url, NULL);
136138
}
137139
else if (!strcasecmp(pathinfo_type, "first-dot")) {
138140
char *split = ap_strchr(path, '.');
@@ -346,16 +348,45 @@ static apr_status_t send_environment(proxy_conn_rec *conn, request_rec *r,
346348
int next_elem, starting_elem;
347349
fcgi_req_config_t *rconf = ap_get_module_config(r->request_config, &proxy_fcgi_module);
348350
fcgi_dirconf_t *dconf = ap_get_module_config(r->per_dir_config, &proxy_fcgi_module);
351+
char *proxy_filename = r->filename;
352+
353+
/* Resolve SCRIPT_NAME/FILENAME from the filesystem? */
354+
if (rconf && rconf->dirwalk_uri_path) {
355+
char *saved_uri = r->uri;
356+
char *saved_path_info = r->path_info;
357+
char *saved_canonical_filename = r->canonical_filename;
358+
int saved_filetype = r->finfo.filetype;
359+
int i = 0;
360+
361+
r->proxyreq = PROXYREQ_NONE;
362+
do {
363+
r->path_info = NULL;
364+
r->finfo.filetype = APR_NOFILE;
365+
r->uri = r->filename = r->canonical_filename = rconf->dirwalk_uri_path;
366+
/* Try without than with DocumentRoot prefix */
367+
if (i && ap_core_translate(r) != OK) {
368+
continue;
369+
}
370+
ap_directory_walk(r);
371+
} while (r->finfo.filetype != APR_REG && ++i < 2);
372+
r->proxyreq = PROXYREQ_REVERSE;
373+
374+
/* If no actual script was found, fall back to the "proxy:"
375+
* SCRIPT_FILENAME dealt with below or by FPM directly.
376+
*/
377+
if (r->finfo.filetype != APR_REG) {
378+
r->filename = proxy_filename;
379+
r->canonical_filename = saved_canonical_filename;
380+
r->finfo.filetype = saved_filetype;
381+
r->path_info = saved_path_info;
382+
}
349383

350-
if (rconf && rconf->need_dirwalk) {
351-
char *saved_filename = r->filename;
352-
r->filename = r->uri;
353-
ap_directory_walk(r);
354-
r->filename = saved_filename;
384+
/* Restore REQUEST_URI in any case */
385+
r->uri = saved_uri;
355386
}
356387

357-
/* Strip proxy: prefixes */
358-
if (r->filename) {
388+
/* Strip "proxy:" prefixes? */
389+
if (r->filename == proxy_filename) {
359390
char *newfname = NULL;
360391

361392
if (!strncmp(r->filename, "proxy:balancer://", 17)) {
@@ -370,24 +401,29 @@ static apr_status_t send_environment(proxy_conn_rec *conn, request_rec *r,
370401
*/
371402
newfname = apr_pstrdup(r->pool, r->filename+13);
372403
}
373-
/* Query string in environment only */
404+
405+
/* Strip potential query string (nocanon) from SCRIPT_FILENAME
406+
* if it's the same as QUERY_STRING.
407+
*/
374408
if (newfname && r->args && *r->args) {
375-
char *qs = strrchr(newfname, '?');
409+
char *qs = strchr(newfname, '?');
376410
if (qs && !strcmp(qs+1, r->args)) {
377411
*qs = '\0';
378412
}
379413
}
380414
}
381415

382416
if (newfname) {
383-
newfname = ap_strchr(newfname, '/');
384-
r->filename = newfname;
417+
r->filename = ap_strchr(newfname, '/');
385418
}
386419
}
387420

388421
ap_add_common_vars(r);
389422
ap_add_cgi_vars(r);
390423

424+
/* SCRIPT_NAME/FILENAME set, restore original */
425+
r->filename = proxy_filename;
426+
391427
/* XXX are there any FastCGI specific env vars we need to send? */
392428

393429
/* Give admins final option to fine-tune env vars */

0 commit comments

Comments
 (0)