Skip to content

Commit 7441bb4

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 b207f20 commit 7441bb4

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 */
@@ -141,11 +141,13 @@ static int proxy_fcgi_canon(request_rec *r, char *url)
141141
rconf = apr_pcalloc(r->pool, sizeof(fcgi_req_config_t));
142142
ap_set_module_config(r->request_config, &proxy_fcgi_module, rconf);
143143
}
144+
rconf->dirwalk_uri_path = NULL;
144145

145-
if (NULL != (pathinfo_type = apr_table_get(r->subprocess_env, "proxy-fcgi-pathinfo"))) {
146+
pathinfo_type = apr_table_get(r->subprocess_env, "proxy-fcgi-pathinfo");
147+
if (pathinfo_type) {
146148
/* It has to be on disk for this to work */
147149
if (!strcasecmp(pathinfo_type, "full")) {
148-
rconf->need_dirwalk = 1;
150+
rconf->dirwalk_uri_path = apr_pstrcat(r->pool, "/", url, NULL);
149151
}
150152
else if (!strcasecmp(pathinfo_type, "first-dot")) {
151153
char *split = ap_strchr(path, '.');
@@ -359,16 +361,45 @@ static apr_status_t send_environment(proxy_conn_rec *conn, request_rec *r,
359361
int next_elem, starting_elem;
360362
fcgi_req_config_t *rconf = ap_get_module_config(r->request_config, &proxy_fcgi_module);
361363
fcgi_dirconf_t *dconf = ap_get_module_config(r->per_dir_config, &proxy_fcgi_module);
364+
char *proxy_filename = r->filename;
365+
366+
/* Resolve SCRIPT_NAME/FILENAME from the filesystem? */
367+
if (rconf && rconf->dirwalk_uri_path) {
368+
char *saved_uri = r->uri;
369+
char *saved_path_info = r->path_info;
370+
char *saved_canonical_filename = r->canonical_filename;
371+
int saved_filetype = r->finfo.filetype;
372+
int i = 0;
373+
374+
r->proxyreq = PROXYREQ_NONE;
375+
do {
376+
r->path_info = NULL;
377+
r->finfo.filetype = APR_NOFILE;
378+
r->uri = r->filename = r->canonical_filename = rconf->dirwalk_uri_path;
379+
/* Try without than with DocumentRoot prefix */
380+
if (i && ap_core_translate(r) != OK) {
381+
continue;
382+
}
383+
ap_directory_walk(r);
384+
} while (r->finfo.filetype != APR_REG && ++i < 2);
385+
r->proxyreq = PROXYREQ_REVERSE;
386+
387+
/* If no actual script was found, fall back to the "proxy:"
388+
* SCRIPT_FILENAME dealt with below or by FPM directly.
389+
*/
390+
if (r->finfo.filetype != APR_REG) {
391+
r->filename = proxy_filename;
392+
r->canonical_filename = saved_canonical_filename;
393+
r->finfo.filetype = saved_filetype;
394+
r->path_info = saved_path_info;
395+
}
362396

363-
if (rconf && rconf->need_dirwalk) {
364-
char *saved_filename = r->filename;
365-
r->filename = r->uri;
366-
ap_directory_walk(r);
367-
r->filename = saved_filename;
397+
/* Restore REQUEST_URI in any case */
398+
r->uri = saved_uri;
368399
}
369400

370-
/* Strip proxy: prefixes */
371-
if (r->filename) {
401+
/* Strip "proxy:" prefixes? */
402+
if (r->filename == proxy_filename) {
372403
char *newfname = NULL;
373404

374405
if (!strncmp(r->filename, "proxy:balancer://", 17)) {
@@ -383,24 +414,29 @@ static apr_status_t send_environment(proxy_conn_rec *conn, request_rec *r,
383414
*/
384415
newfname = apr_pstrdup(r->pool, r->filename+13);
385416
}
386-
/* Query string in environment only */
417+
418+
/* Strip potential query string (nocanon) from SCRIPT_FILENAME
419+
* if it's the same as QUERY_STRING.
420+
*/
387421
if (newfname && r->args && *r->args) {
388-
char *qs = strrchr(newfname, '?');
422+
char *qs = strchr(newfname, '?');
389423
if (qs && !strcmp(qs+1, r->args)) {
390424
*qs = '\0';
391425
}
392426
}
393427
}
394428

395429
if (newfname) {
396-
newfname = ap_strchr(newfname, '/');
397-
r->filename = newfname;
430+
r->filename = ap_strchr(newfname, '/');
398431
}
399432
}
400433

401434
ap_add_common_vars(r);
402435
ap_add_cgi_vars(r);
403436

437+
/* SCRIPT_NAME/FILENAME set, restore original */
438+
r->filename = proxy_filename;
439+
404440
/* XXX are there any FastCGI specific env vars we need to send? */
405441

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

0 commit comments

Comments
 (0)