From: Christopher Faulet Date: Fri, 14 Feb 2020 15:55:52 +0000 (+0100) Subject: MINOR: mux-fcgi: Make the capture of the path-info optional in pathinfo regex X-Git-Tag: v2.2-dev3~74 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=6c57f2da4326768c08603480f0ee2fa0a7f73231;p=thirdparty%2Fhaproxy.git MINOR: mux-fcgi: Make the capture of the path-info optional in pathinfo regex Now, only one capture is mandatory in the path-info regex, the one matching the script-name. The path-info capture is optional. Of couse, it must be defined to fill the PATH_INFO parameter. But it is not mandatory. This way, it is possible to get the script-name part from the path, excluding the path-info. This patch is small enough to be backported to 2.1. --- diff --git a/doc/configuration.txt b/doc/configuration.txt index f2124db95e..aa4826fc2d 100644 --- a/doc/configuration.txt +++ b/doc/configuration.txt @@ -18727,10 +18727,13 @@ pass-header [ { if | unless } ] path-info Define a regular expression to extract the script-name and the path-info from - the URL-decoded path. Thus, should have two captures: the first one - to capture the script name and the second one to capture the path-info. It is - an optional setting. If it is not defined, no matching is performed on the - path. and the FastCGI parameters PATH_INFO and PATH_TRANSLATED are not filled. + the URL-decoded path. Thus, may have two captures: the first one to + capture the script name and the second one to capture the path-info. The + first one is mandatory, the second one is optional. This way, it is possible + to extract the script-name from the path ignoring the path-info. It is an + optional setting. If it is not defined, no matching is performed on the + path. and the FastCGI parameters PATH_INFO and PATH_TRANSLATED are not + filled. For security reason, when this regular expression is defined, the newline and the null characters are forbiden from the path, once URL-decoded. The reason @@ -18740,7 +18743,8 @@ path-info returned to the client. The principle of least astonishment is applied here. Example : - path-info ^(/.+\.php)(/.*)?$ + path-info ^(/.+\.php)(/.*)?$ # both script-name and path-info may be set + path-info ^(/.+\.php) # the path-info is ignored option get-values no option get-values diff --git a/src/mux_fcgi.c b/src/mux_fcgi.c index 12d29d6863..27f5edce0c 100644 --- a/src/mux_fcgi.c +++ b/src/mux_fcgi.c @@ -1360,16 +1360,19 @@ static int fcgi_set_default_param(struct fcgi_conn *fconn, struct fcgi_strm *fst if (!regex_exec_match2(fconn->app->pathinfo_re, path.ptr, len, MAX_MATCH, pmatch, 0)) goto check_index; - /* We must have at least 2 captures, otherwise we do nothing and - * jump to the last part. Only first 2 ones will be considered + /* We must have at least 1 capture for the script name, + * otherwise we do nothing and jump to the last part. */ - if (pmatch[1].rm_so == -1 || pmatch[1].rm_eo == -1 || - pmatch[2].rm_so == -1 || pmatch[2].rm_eo == -1) + if (pmatch[1].rm_so == -1 || pmatch[1].rm_eo == -1) goto check_index; - /* Finally we can set the script_name and the path_info */ + /* Finally we can set the script_name and the path_info. The + * path_info is set if not already defined, and if it was + * captured + */ params->scriptname = ist2(path.ptr + pmatch[1].rm_so, pmatch[1].rm_eo - pmatch[1].rm_so); - params->pathinfo = ist2(path.ptr + pmatch[2].rm_so, pmatch[2].rm_eo - pmatch[2].rm_so); + if (!(params->mask & FCGI_SP_PATH_INFO) && (pmatch[2].rm_so == -1 || pmatch[2].rm_eo == -1)) + params->pathinfo = ist2(path.ptr + pmatch[2].rm_so, pmatch[2].rm_eo - pmatch[2].rm_so); check_index: len = params->scriptname.len;