|
php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login |
[2017-02-19 17:10 UTC] christian at groschupp dot org
Description:
------------
php version: 7.1.2
apache version: 2.4.6
apache configuration:
ProxyPassMatch ^/(.*\.php(/.*)?)$ fcgi://127.0.0.1:9000/var/www/html/$1
Working apache configuration
<FilesMatch "\.php$">
SetHandler "proxy:fcgi://localhost:9000"
</FilesMatch>
I need the ProxyPassMatch variant, because i have also a apache 2.2 and php 5.6 setup, where i can't use SetHandler.
Test script:
---------------
# Script to reproduce on CentOS 7
yum install -y epel-release
rpm -Uvh http://rpms.remirepo.net/enterprise/remi-release-7.rpm
yum install -y httpd php71-php-fpm
cat << EOF > /var/www/html/index.php
<?php
echo 'Value: ' . \$_SERVER['SCRIPT_NAME'] . '<br>';
echo 'Expected Value: ' . '/index.php'
?>
EOF
scl enable php71 php-fpm
echo "ProxyPassMatch ^/(.*\.php(/.*)?)$ fcgi://127.0.0.1:9000/var/www/html/$1" >> /etc/httpd/conf.d/welcome.conf
apachectl -D FOREGROUND
Expected result:
----------------
When requesting "/index.php/1 2 3"
$_SERVER["SCRIPT_NAME"]: "/index.php"
Actual result:
--------------
$_SERVER["SCRIPT_NAME"]: "/index.php/1 2 3"
PatchesPull RequestsHistoryAllCommentsChangesGit/SVN commits
|
|||||||||||||||||||||||||||
Copyright © 2001-2025 The PHP GroupAll rights reserved. |
Last updated: Fri Oct 24 14:00:01 2025 UTC |
Adding some partial problem info: I expect the problem to be in the following lines in fpm/fpm_main.c: 1234 } else if (apache_was_here && env_script_name) { 1235 /* Using mod_proxy_fcgi and ProxyPass, apache cannot set PATH_INFO 1236 * As we can extract PATH_INFO from PATH_TRANSLATED 1237 * it is probably also in SCRIPT_NAME and need to be removed 1238 */ 1239 int snlen = strlen(env_script_name); 1240 if (snlen>slen && !strcmp(env_script_name+snlen-slen, path_info)) { 1241 FCGI_PUTENV(request, "ORIG_SCRIPT_NAME", orig_script_name); 1242 env_script_name[snlen-slen] = 0; 1243 SG(request_info).request_uri = FCGI_PUTENV(request, "SCRIPT_NAME", env_script_name); 1244 } 1245 } 1246 env_path_info = FCGI_PUTENV(request, "PATH_INFO", path_info); Here SCRIPT_NAME gets compared to PATH_INFO in the strcmp() call. Now when using mod_proxy_fcgi Apache sends SCRIPT_NAME non-percent-encoded as required by the CGI spec. But PATH_INFO is extracted from SCRIPT_FILENAME which is percent-encoded. That means all is fine as long as the PATH_INFO part does not contain anything that gets encoded. As soon as chars which need encoding are contained, the strcmp() fails and SCRIPT_NAME will not get adjusted. Furthermore, even if SCRIPT_NAME would be encoded, it would still be important, that the percent-encoding of SCRIPT_FILENAME and SCRIPT_NAME use the same character case for the hex digits, eg. not mixing %5B and %5b. As a workaround I adjusted SCRIPT_NAME in mod_proxy_fcgi to be consistent with SCRIPT_FILENAME even though that's not CGI-spec compliant using the following directive: ProxyFCGISetEnvIf "reqenv('SCRIPT_FILENAME') =~ m|.*${APP_DIR}(/.*)|" SCRIPT_NAME "$1" Here APP_DIR is a Unix env var or Define'd var containing the path to the PHP application (could be your DocumentRoot). One can also use the verbatim path there instead of a variable. the correct fix would probably be to use a percent-decoded path_info in the strcmp() inside fpm_main.c.