@@ -28,7 +28,7 @@ typedef struct {
2828} sei_entry ;
2929
3030typedef 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