@@ -59,10 +59,13 @@ static int proxy_fcgi_canon(request_rec *r, char *url)
5959{
6060 char * host , sport [7 ];
6161 const char * err ;
62- char * path , * pc ;
62+ char * path ;
6363 apr_port_t port , def_port ;
6464 fcgi_req_config_t * rconf = NULL ;
6565 const char * pathinfo_type = NULL ;
66+ fcgi_dirconf_t * dconf = ap_get_module_config (r -> per_dir_config ,
67+ & proxy_fcgi_module );
68+ int from_handler ;
6669
6770 if (ap_cstr_casecmpn (url , "fcgi:" , 5 ) == 0 ) {
6871 url += 5 ;
@@ -71,12 +74,11 @@ static int proxy_fcgi_canon(request_rec *r, char *url)
7174 return DECLINED ;
7275 }
7376
74- path = url ;
7577 port = def_port = ap_proxy_port_of_scheme ("fcgi" );
7678
7779 ap_log_rerror (APLOG_MARK , APLOG_TRACE1 , 0 , r ,
7880 "canonicalising URL %s" , url );
79- err = ap_proxy_canon_netloc (r -> pool , & path , NULL , NULL , & host , & port );
81+ err = ap_proxy_canon_netloc (r -> pool , & url , NULL , NULL , & host , & port );
8082 if (err ) {
8183 ap_log_rerror (APLOG_MARK , APLOG_ERR , 0 , r , APLOGNO (01059 )
8284 "error parsing URL %s: %s" , url , err );
@@ -93,20 +95,40 @@ static int proxy_fcgi_canon(request_rec *r, char *url)
9395 host = apr_pstrcat (r -> pool , "[" , host , "]" , NULL );
9496 }
9597
96- /* We do not call ap_proxy_canonenc_ex() on the path here because the CGI
97- * environment variable SCRIPT_FILENAME based on it want the decoded/local
98- * path, don't let control characters pass still.
99- *
100- * XXX: should we encode based on dconf->backend_type though?
101- */
102- for (pc = path ; * pc ; pc ++ ) {
103- if (apr_iscntrl (* pc )) {
98+ from_handler = apr_table_get (r -> notes , "proxy-sethandler" ) != NULL ;
99+ if (from_handler
100+ || apr_table_get (r -> notes , "proxy-nocanon" )
101+ || apr_table_get (r -> notes , "proxy-noencode" )) {
102+ char * c = path = url ; /* this is the raw path */
103+
104+ /* We do not call ap_proxy_canonenc_ex() on the path here, don't
105+ * let control characters pass still, and for php-fpm no '?' either.
106+ */
107+ if (FCGI_MAY_BE_FPM (dconf )) {
108+ while (!apr_iscntrl (* c ) && * c != '?' )
109+ c ++ ;
110+ }
111+ else {
112+ while (!apr_iscntrl (* c ))
113+ c ++ ;
114+ }
115+ if (* c ) {
104116 ap_log_rerror (APLOG_MARK , APLOG_ERR , 0 , r , APLOGNO (10414 )
105- "To be forwarded path contains control "
106- "characters " );
117+ "To be forwarded path contains control characters%s" ,
118+ FCGI_MAY_BE_FPM ( dconf ) ? " or '?'" : " " );
107119 return HTTP_FORBIDDEN ;
108120 }
109121 }
122+ else {
123+ core_dir_config * d = ap_get_core_module_config (r -> per_dir_config );
124+ int flags = d -> allow_encoded_slashes && !d -> decode_encoded_slashes ? PROXY_CANONENC_NOENCODEDSLASHENCODING : 0 ;
125+
126+ path = ap_proxy_canonenc_ex (r -> pool , url , strlen (url ), enc_path , flags ,
127+ r -> proxyreq );
128+ if (!path ) {
129+ return HTTP_BAD_REQUEST ;
130+ }
131+ }
110132
111133 r -> filename = apr_pstrcat (r -> pool , "proxy:fcgi://" , host , sport , "/" ,
112134 path , NULL );
0 commit comments