Edit report at http://bugs.php.net/bug.php?id=54152&edit=1
ID: 54152
User updated by: mark at catseye dot org
Reported by: mark at catseye dot org
Summary: Make FPM compatible with Apache HTTP Server 2.3
mod_proxy_fcgi
Status: Open
Type: Feature/Change Request
Package: FPM related
Operating System: Linux
PHP Version: 5.3SVN-2011-03-03 (snap)
Block user comment: N
Private report: N
New Comment:
The second URL is incorrect; apologies for the mistake. The correct URL
for the problem that is being addressed on the Apache end is:
https://issues.apache.org/bugzilla/show_bug.cgi?id=50851
Previous Comments:
------------------------------------------------------------------------
[2011-03-03 19:54:29] mark at catseye dot org
Description:
------------
Apache HTTP Server 2.3 is about to enter beta in preparation for a
general availability release of 2.4 soon, see:
http://marc.info/?l=apache-httpd-dev&m=129900037316343&w=2
Apache HTTP Server 2.3 comes with mod_proxy_fcgi as a standard module;
mod_fcgid and mod_fastcgi are not standard modules. Unfortunately,
mod_proxy_fcgi and php-fpm do not work with each other. One problem
is already being addressed on the Apache end:
http://marc.info/?l=apache-httpd-dev&m=129900037316343&w=2
There are two problems that, in my opinion, are best addressed
on the PHP end of things (patch attached). php-fpm will then
work out of the box with mod_proxy_fcgi:
Problem 1:
PHP relies on the SCRIPT_FILENAME environment variable to find the
script
to execute in the filesystem. (It can also use SCRIPT_NAME for this,
but
that will fail if the document root for php-fpm does not match the
document
root of the httpd proxy). In Apache HTTP Server 2.3, all proxy modules
prefix SCRIPT_FILENAME with "proxy:" followed by a protocol name, for
example, when the user requests
https://server-name/test/test.php
Apache HTTP Server sets SCRIPT_FILENAME to
proxy:fcgi://127.0.0.1:9000/www/php-ssl/test.php/extra/stuff
The attached patch causes php-fpm to recognize the "proxy:"
convention in this case, and skip over the subsequent protocol,
hostname and port. In this example, SCRIPT_FILENAME then becomes
/www/php-ssl/test.php/extra/stuff
...which php-fpm is able to deal with correctly.
I believe that PHP is the correct place to change this, rather than in
Apache HTTP Server, since the proxy (httpd) and origin (php-fpm, in
this
case) may be on different servers machine and httpd should not make
assumptions about the origin's document root or URI path namespace
mapping.
Problem 2:
Apache HTTP Server is not able to set a value for PATH_INFO and still
comply with RFC 3875, for the reasons in the last paragraph above.
sapi/fpm/fpm/fpm_main.c:init_request_info() will find the base script
using SCRIPT_FILENAME, but uses this to calculate and offset into the
original PATH_INFO environment variable. Since no such environment
variable exists (if the patch to Apache HTTP Server is applied),
Additional notes:
Except for 21 additional lines in the fpm version, the code in
init_request_info() is duplicated in the following two files
(378 identical lines in the two versions of this one function):
sapi/fpm/fpm/fpm_main.c
sapi/cgi/cgi_main.c
The changes in the attached patch are made to both files. While
they are only really needed in sapi/fpm/fpm/fpm_main.c, making the
changes in both places should do no harm, will permit the cgi sapi
to be used more flexibly, and be more consistent overall by
minimizing special cases.
----
Using php5.3-201103031330 snapshot.
no changes to php.ini
Fedora 14, 64-bit (fully patched)
gcc 4.5.1
./configure --build=x86_64-unknown-linux-gnu
--host=x86_64-unknown-linux-gnu --program-prefix=
--disable-dependency-tracking --prefix=/usr --exec-prefix=/usr
--bindir=/usr/bin --sbindir=/usr/sbin --sysconfdir=/etc
--datadir=/usr/share --includedir=/usr/include --libdir=/usr/lib64
--libexecdir=/usr/libexec --localstatedir=/var --sharedstatedir=/var/lib
--mandir=/usr/share/man --infodir=/usr/share/info
--cache-file=../config.cache --with-libdir=lib64
--with-config-file-path=/etc --with-config-file-scan-dir=/etc/php.d
--disable-debug --with-pic --disable-rpath --without-pear --with-bz2
--with-exec-dir=/usr/bin --with-freetype-dir=/usr --with-png-dir=/usr
--with-xpm-dir=/usr --enable-gd-native-ttf --with-t1lib=/usr
--without-gdbm --with-gettext --with-gmp --with-iconv
--with-jpeg-dir=/usr --with-openssl --with-pcre-regex=/usr --with-zlib
--with-layout=GNU --enable-exif --enable-ftp --enable-magic-quotes
--enable-sockets --with-kerberos --enable-ucd-snmp-hack --enable-shmop
--enable-calendar --without-sqlite --with-libxml-dir=/usr --enable-xml
--with-system-tzdata --enable-force-cgi-redirect --enable-pcntl
--with-imap=shared --with-imap-ssl --enable-mbstring=shared
--enable-mbregex --with-gd=shared --enable-bcmath=shared
--enable-dba=shared --with-db4=/usr --with-xmlrpc=shared
--with-ldap=shared --with-ldap-sasl --with-mysql=shared,/usr
--with-mysqli=shared,/usr/lib64/mysql/mysql_config
--with-interbase=shared,/usr/lib64/firebird
--with-pdo-firebird=shared,/usr/lib64/firebird --enable-dom=shared
--with-pgsql=shared --enable-wddx=shared --with-snmp=shared,/usr
--enable-soap=shared --with-xsl=shared,/usr --enable-xmlreader=shared
--enable-xmlwriter=shared --with-curl=shared,/usr --enable-fastcgi
--enable-pdo=shared --with-pdo-odbc=shared,unixODBC,/usr
--with-pdo-mysql=shared,/usr/lib64/mysql/mysql_config
--with-pdo-pgsql=shared,/usr --with-pdo-sqlite=shared,/usr
--with-pdo-dblib=shared,/usr --with-sqlite3=shared,/usr
--enable-json=shared --enable-zip=shared --without-readline
--with-libedit --with-pspell=shared --enable-phar=shared
--with-mcrypt=shared,/usr --with-tidy=shared,/usr
--with-mssql=shared,/usr --enable-sysvmsg=shared --enable-sysvshm=shared
--enable-sysvsem=shared --enable-posix=shared
--with-unixODBC=shared,/usr --enable-fileinfo=shared
--enable-intl=shared --with-icu-dir=/usr --with-enchant=shared,/usr
--with-recode=shared,/usr --enable-fpm
Test script:
---------------
<html>
<head> <title>php-fpm test</title> </head>
<body> <?php phpinfo(); ?> </body>
</html>
Expected result:
----------------
1. Save the script in the file file /www/php-ssl/test.php
2. Build Apache HTTP Server 2.3.10 alpha with the patch in
https://issues.apache.org/bugzilla/show_bug.cgi?id=50851
(Note: without the patch to httpd, httpd sets PATH_INFO incorrectly,
which
makes the result from php-fpm incorrect with or without the patch to
PHP
included in this PHP bug report).
3. Configure httpd to act as a reverse proxy for php-fpm by adding the
following to httpd.conf:
ProxyPass /test/ fcgi://127.0.0.1:9000/www/php-ssl/
4. Run the script by requesting:
https://server-name/test/test.php/extra/stuff
The script executes, producing a phpinfo() page. In the "PHP
Variables"
section of the page, the following are expected after the attached
patch
is applied:
_SERVER["SCRIPT_FILENAME"] /www/php-ssl/test.php
_SERVER["REQUEST_URI"] /test/test.php/extra/stuff
_SERVER["PATH_INFO"] /extra/stuff
_SERVER["PATH_TRANSLATED"] /www/html-ssl/extra/stuff
_SERVER["ORIG_SCRIPT_FILENAME"] /www/php-ssl/test.php/extra/stuff
Actual result:
--------------
php-fpm returns a HTTP 404 (Not Found) response to the Apache HTTP
Server
proxy.
------------------------------------------------------------------------
--
Edit this bug report at http://bugs.php.net/bug.php?id=54152&edit=1