php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #51983 [fpm sapi] pm.status_path not working when cgi.fix_pathinfo=1
Submitted: 2010-06-03 04:42 UTC Modified: 2023-04-06 15:10 UTC
Votes:25
Avg. Score:4.3 ± 1.1
Reproduced:14 of 14 (100.0%)
Same Version:7 (50.0%)
Same OS:10 (71.4%)
From: konstantin at symbi dot org Assigned: bukka (profile)
Status: Wont fix Package: FPM related
PHP Version: 5.3SVN-2010-06-03 (snap) OS: Any
Private report: No CVE-ID: None
View Add Comment Developer Edit
Welcome! If you don't have a Git account, you can't do anything here.
You can add a comment by following this link or if you reported this bug, you can edit this bug over here.
(description)
Block user comment
Status: Assign to:
Package:
Bug Type:
Summary:
From: konstantin at symbi dot org
New email:
PHP Version: OS:

 

 [2010-06-03 04:42 UTC] konstantin at symbi dot org
Description:
------------
FPM status does not work when cgi.fix_pathinfo = 1, with the default nginx 
configuration for php (default fastcgi_params + SCRIPT_FILENAME added).

The problems is that in fpm_main.c, here:

if (!strcasecmp(SG(request_info).request_method, "GET") && 
fpm_status_handle_status(SG(request_info).request_uri, ...

SG(request_info).request_uri is sometimes NULL depending on the trickiest things 
which happen when cgi.fix_pathinfo = 1.

I have examined the code of init_request_info() which runs when cgi.fix_pathinfo 
= 1, and I found out that this part of code is legacy part from the CGI SAPI, it 
is was designed to fix problems with a lots of broken CGI implementations. It 
was reasonable for CGI to get the things working independent on speed, but the 
'bruteforce' approach used is not too good for FPM SAPI which is commonly used 
on high-bandwidth sites.

More, PHP introduces non-standard "SCRIPT_FILENAME" fastcgi env; it is not hard 
to add it to configuration of flexible servers like nginx (by using 
"fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name" in its 
configuration), but it can cause problems with such servers as lighttpd where 
all the fastcgi parameters are hardcoded (I've seen people on forums complaining 
thay get 'no input file' with nginx+fpm and they found no way to fix it).

So, I have found the fix_pathinfo part is written in a hard to understand and 
difficult to fix way, and that is is really not required for FPM SAPI, and that 
it slows it down. System administrators who configure FSM webservers and use FPM 
sapi are usually experianced and for them it would be preferable to have strict 
and simple logic rather then some magic which can potentially slow things down a 
lot. So i have rewritten init_request_info(), the the suggested patch is 
attached.

It logic of detection script_filename is much simpler:
if SCRIPT_FILENAME is defined, use it,
else if both DOCUMENT_ROOT and SCRIPT_NAME are defined, concat them and use 
(should fix all the problems with lighty etc);
else if PATH_TRALSLATED is defined, use it as script_filename;
else we do not know the script_filename.

And, of course, it fixes the problem with pm.status_path I started with.

Test script:
---------------
N/A

Expected result:
----------------
N/A

Actual result:
--------------
N/A

Patches

init_request_info.patch (last revision 2010-06-03 02:43 UTC by konstantin at symbi dot org)

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2010-06-04 02:26 UTC] felipe@php.net
-Status: Open +Status: Assigned -Package: CGI related +Package: FPM related -Assigned To: +Assigned To: fat
 [2010-06-04 06:32 UTC] sergo_s at bk dot ru
I met problem "No input file specified" in the configuration of lighttpd 1.4.26 + php-5.3.2 + fastcgi/php-fpm when requesting addresses like index.php/myMethod/ (kohanaframework based site). I found that $_SERVER[PATH_INFO] is NULL.
(More about my problem in this post: http://phpclub.ru/talk/showthread.php?s=&postid=902382 (russian))

This patch solved the problem. Thanks.
 [2010-06-04 08:25 UTC] fat@php.net
Have you tried your patch with other webservers than nginx and lighttpd ?
 [2010-06-04 08:52 UTC] konstantin at symbi dot org
99% of fpm installations are with nginx or lighty, using fpm sapi with non-FSM 
webservers is at least very strange. But I have just checked it with 
Apache+mod_fastcgi in a simplest configuration:

DocumentRoot "/var/www"
FastCgiExternalServer /var/www -socket /tmp/php-fpm.sock
<Directory /var/www>
    Options FollowSymLinks +ExecCGI
    AllowOverride   All
    Order           Allow,Deny
    Allow           from all
</Directory>

and it works OK.

The patch contains comments in the top of the new init_request_info() 
implementation. It describes why fastcgi parameters are mapped to the script 
filename in this way, and it was chosen after examining CGI specs, typical fpm 
configurations, and common sense.

BTW, those webservers like old IIS versions with buggy cgi implementations which 
required that awkward way of guessing what they meant, for which the original 
implementation of init_request_info() was designed, do not support remote 
FastCGI at all.
 [2010-06-04 08:59 UTC] fat@php.net
I'm asking about Apache, to be certain not to ban some webservers from using 
FPM.

According to http://www.fastcgi.com/drupal/node/3, we have to make sure that FPM 
is compliant with all of the following webservers:

Apache
Microsoft IIS
Microsoft IIS (second generation)
SunOne
Lighttpd
Premium thttpd http
MyServer
Pi3Web
WebSTAR (Mac OS)
Nginx
Cherokee
 [2010-06-04 09:04 UTC] konstantin at symbi dot org
FPM sapi implements remote fastcgi only (also known as "external FastCGI").
So it is limited to web servers which support it.

I have tested Nginx, Lighttpd, and Apache mod_fastcgi.

For other webservers listed, are there ones which of them support remote 
fastcgi? At least I am sure that IIS does not (even with its latest fastcgi 
implementations, I've asked this question on IIS FastCGI forums). As far as I 
know, thttpd does not, too.
 [2010-06-04 09:07 UTC] konstantin at symbi dot org
And of course I never say we should do anything with the CGI/FCGI sapi. I am sure 
its implementation must not be chanhed 'cause it was tested with many webservers 
during years. I am speaking only about FPM sapi which is much more specific.
 [2010-06-09 15:59 UTC] tony2001@php.net
Jerome, I agree that we should drop this fix_pathinfo stuff - it makes no sense to adopt all the freaky things from CGI API. 
The patch requires some extensive testing, though, that's clear. But I don't think we should keep in mind of all the web-servers you mentioned.
Apache, nginx & lightty are my biggest concern, others can be safely dropped (or assumed working). 
You can forget about IIS anyway, FPM doesn't support Windows.
 [2010-06-09 16:15 UTC] fat@php.net
I mentioned all the web servers to make sure we agree on doing this.

I totaly agree on making this change. This pathinfo thing sucks for real.
 [2010-08-04 17:07 UTC] konstantin at symbi dot org
btw, current fix_pathinfo implementation has security problems:

http://habrahabr.ru/blogs/sysadm/100961/
http://www.80sec.com/nginx-securit.html

If a site has uploads (say, images), one can upload an image containing 
executable php code and append /something.php to the image url (say, 
/uploads/1.jpg/test.php). When fix_pathinfo=1, init_request_info would use 
/uploads/1.jpg as a script filename.

The suggested patch fixes this, too.
 [2011-02-01 13:34 UTC] slim at inbox dot lv
after applying the patch php compiled with debug complain on every request:

Feb 01 14:26:38.214800 [WARNING] [pool www] child 16257 said into stderr: "[Tue Feb  1 14:26:38 2011]  Script:  '-'"
Feb 01 14:26:38.214846 [WARNING] [pool www] child 16257 said into stderr: "/var/tmp/portage/dev-lang/php-5.3.5-r100/work/sapis-build/fpm/sapi/fpm/fpm/fpm_main.c(1116) :  Freeing 0x08B95CBC (23 bytes), script=-"
Feb 01 14:26:38.214857 [WARNING] [pool www] child 16257 said into stderr: "=== Total 1 memory leaks detected ==="
Feb 01 14:26:40.535416 [WARNING] [pool www] child 16258 said into stderr: "[Tue Feb  1 14:26:40 2011]  Script:  '-'"
Feb 01 14:26:40.535466 [WARNING] [pool www] child 16258 said into stderr: "/var/tmp/portage/dev-lang/php-5.3.5-r100/work/sapis-build/fpm/sapi/fpm/fpm/fpm_main.c(1116) :  Freeing 0x08B95EA4 (23 bytes), script=-"
Feb 01 14:26:40.535477 [WARNING] [pool www] child 16258 said into stderr: "=== Total 1 memory leaks detected ==="

a line at fpm_main.c(1116) causing this is 
SG(request_info).request_uri = request_uri ? estrndup(request_uri, strcspn(request_uri, "?")) : NULL;
 [2011-07-03 14:33 UTC] felipe@php.net
What is the status of this?
 [2011-07-03 17:24 UTC] fat@php.net
I'm dequeuing FPM bugs. I've started with the simple ones. This one is on my todo 
list. I don't have an ETA right now.

++ Jerome
 [2011-07-03 17:28 UTC] felipe@php.net
Ah okay, I was wondering if it already has been closed. Thanks.
 [2011-07-16 19:34 UTC] fat@php.net
Warning: the following comment is very long. Take time to read it and don't 
hesitate to ask me for details questions.
Notes: I've not been able to put it all in one comment (it's detected as spam). 
So I've split it into several comments.

I just review de patch and there is a problem.

It does not work with mod_fastcgi except when mod_fastcgi is configured as 
commented before:

DocumentRoot "/var/www"
FastCgiExternalServer /var/www -socket /tmp/php-fpm.sock
<Directory /var/www>
    Options FollowSymLinks +ExecCGI
    AllowOverride   All
    Order           Allow,Deny
    Allow           from all
</Directory>

Setting this make all requests to be forward to php-fpm and that is definitely 
NOT what common configurations aim to do.

More common mod_fastcgi configuration would be something like:

ScriptAlias /fcgi-bin/ /usr/local/apache2/fcgi-bin/
FastCGIExternalServer /usr/local/apache2/fcgi-bin/php-cgi -host 127.0.0.1:9000
AddHandler php-fastcgi .php
Action php-fastcgi /fcgi-bin/php-cgi

and in this case, the patch does not work.
 [2011-07-16 19:37 UTC] fat@php.net
but let's analyse all this:

FastCGI defines a communication protocol above CGI 1.1 (which is defined in RFC 
3875).
So fastcgi client/servers should be RFC 3875 compliant


From RFC 3875:
Usefull required request variables are:
- PATH_INFO
- PATH_TRANSLATED
- QUERY_STRING
- SCRIPT_NAME

And the variable which are NOT defined in the RFC:
- DOCUMENT_ROOT
- SCRIPT_FILENAME
- REQUEST_URI

Here is a comparison of common web server behaviour to see what values they send 
to FPM. See http://pastebin.com/tqFjUaiB

Conlusion:
Nginx and Lighttpd are fully RFC 3875 compliant and they add the following 
variables:
- SCRIPT_FILENAME
- DOCUMENT_ROOT
- REQUEST_URI
Note: nginx should set PATH_INFO event if it's null as describe in the RFC. But 
this breaks nothing. So we can forgive him.


mod_fastcgi is acting as nginx and lighttpd only with the following 
configuration:
<VirtualHost *:82>
  DocumentRoot /home/fat/web/docs/php
  FastCgiExternalServer /home/fat/web/docs/php -host 127.0.0.1:9000
</VirtualHost>

but in this case, all request are sent to FPM and this is NOT what common users 
want to do. 

In order to send only php request, users can use the following configuration:
<VirtualHost *:82>
  DocumentRoot /home/fat/web/docs/php
  <Location "/php-fpm">
    Options +ExecCGI
    Order Deny,Allow
    Deny from All
    Allow from ENV=REDIRECT_STATUS
  </Location>

  FastCgiExternalServer /php-fpm-handler -host 127.0.0.1:9000
  AddType application/x-httpd-php .php
  Action application/x-httpd-php /php-fpm
  ScriptAlias /php-fpm /php-fpm-handler
</VirtualHost>

In this case, mod_fastcgi is not RFC 3875 compliant:
- DOCUMENT_ROOT, REQUEST_URI and QUERY_STRING are set correctely
- SCRIPT_FILENAME, SCRIPT_NAME, PATH_INFO, PATH_TRANSLATED have just wrong 
values

mod_proxy_fcgi is also not RFC 3875 compliant:
- DOCUMENT_ROOT, REQUEST_URI and QUERY_STRING are set correctely
- SCRIPT_FILENAME, SCRIPT_NAME, PATH_INFO, PATH_TRANSLATED have just wrong 
values

SCRIPT_NAME is even empty when apache env var proxy-fcgi-pathinfo is set
 [2011-07-16 19:37 UTC] fat@php.net
If FPM would be RFC 3875 compliant, it should:
- set document_root in its own configuration
- execute the script set by concatening its own document_root and SCRIPT_NAME

As all web servers are sending DOCUMENT_ROOT correctely, FPM should:
- execute the script set by concatening DOCUMENT_ROOT and SCRIPT_NAME

In this two cases, nginx and lighttpd would still work, mod_fastcgi should work 
depending on how it's being used and proxy_mod_fcgi whould just not work.


as apache 2.3 is still beta, I hope we could have them change mod_proxy_fcgi 
behaviour 
in order to be RFC 3875 compliant... (I've opened a bug report: 
https://issues.apache.org/bugzilla/show_bug.cgi?id=51517)

but for mod_fastcgi this is more complicated. We can't forget it because it's
used with FPM (just google apache fpm)

How should we addresse that ? That is the question I don't have the answer to :(

But I have a proposal:


1- add a configuration directive on each pool named "document_root.override" 
which is optional and default set to "true"  


2- add a configuration directive on each pool named "document_root" which is 
optional and default set to (null).
But it's mandatory if document_root.override is set. 
This set the document_root for the current pool.
In fact, as the web server and FPM can be on a different server with a different 
filesystem organisation,
I really think that it's not the job of the webserver to set the document_root, 
but it's up to nginx.
Does the webserver defines where a tomcat application servers find the files / 
class it has to execute ? --> NO.
This configuration is made on the tomcat side. 
FPM should not be exclusive, but this should be definitely possible (which is 
not the case right now)


3- add a configuration directive on each pool named 
"not_compliant_fcgi_web_server" which is optional and default set to "false"


So, when a request arrives

if (not_compliant_fcgi_web_server is set to "true") {
  just act as now and nothing changes and all servers works.

} else { // new behaviour, RFC compliant
  // determine the doc_root.
  doc_root = (empty) 
  if (document_root.override is set to "false") {
    doc_root = document_root
  } else {
    if (DOCUMENT_ROOT has been sent by the webserver) {
      doc_root = DOCUMENT_ROOT
    } else {
      doc_root = document_root
    }  
  }
  
  if (doc_root is not empty and SCRIPT_NAME is not empty) {
    execute script set by concatenation of doc_root and SCRIPT_NAME
  } else {
    returns a 500 and log the error to warn the web server administrator
  }
 }   

Notes: the configuration directive names have been choosen as a first thought. 
There is maybe changes to make.

what guys do you think ?

++ Jerome
 [2011-07-17 14:19 UTC] konstantin at symbi dot org
Hello,

Here are a few quick thoughts.

1) The fix_pathinfo stuff has been implemented a long ago, and it's main purpose 
was to workaround the bugs of web servers used 10 years ago. It was 
developed with the CGI exec()s in mind so the performance impact caused by 
multiple stat()s was not so important. I see no reason to keep it 
nowadays.

2) The patch I have proposed hase a bug mentioned in a comment above, that must 
be fixed. I personally just use fix_patninfo=0 now ;)

3) The CGI protocol itself has been developed (as far as I understand) with a 
thought that there's some monolithic application which takes PATH_INFO, 
parses it, does something and prints the results. With PHP applications, there's 
usually another case - we need to map the request variables to a physical 
path to the php script, the same way as web server SAPIs do. It does not conform 
to any RFCs but that's how people DO use PHP, and that's a behavior everyone 
expects in 99.9999% cases.

4) The non-standard SCRIPT_FILENAME fastcgi variable is widely used in many 
configurations, and there are standard config samples for nginx etc which rely 
on 
the fact that it has been working for years.

5) Your proposal seems mostly OK but I'd prefer if the SCRIPT_FILENAME remains 
supported.

My proposal would be close to yours:

I. Add the 'fcgi.accept_script_filename' per-pool ini setting, default true;

II. Add the document_root.override per-pool ini setting, default empty.

III. Remove all the fix_pathinfo stuff, and change the corresponding parts of 
the init_request_info function according to the pseudocode:

function get_script_filename(ini, Env) {
    var script_filename;
    if (ini["fcgi.accept_script_filename"] == true && Env["SCRIPT_FILENAME"] is 
not empty) {
        script_filename = Env["SCRIPT_FILENAME"];
    } else {
         doc_root = undefined;
         assert(Env["SCRIPT_NAME"] is not empty); // *
         if (ini["document_root.override"] is not empty) {
             doc_root = ini["document_root.override"];
         } else {
             assert(Env["DOCUMENT_ROOT"] is not empty);
             doc_root = Env["DOCUMENT_ROOT"];
         }
         script_filename = concat(doc_root, Env["SCRIPT_NAME"]);
    }
    return script_filename;
}

*) assert() means 'respond with status 500 if assertion fails'.

The RFC3875 compliance can be achieved by defining document_root.override and 
setting fcgi.accept_script_filename = false.
 [2011-07-17 15:29 UTC] fat@php.net
hi,

thx for the feedback. For SCRIPT_FILENAME, I know it became a pseudo standard. 

But as the concatenation of DOCUMENT_ROOT and SCRIPT_NAME results in  
SCRIPT_FILENAME, I don't really see why you want to keep it with yet another fpm 
configuration line ? Maybe I missed something :)

++ Jerome
 [2011-07-17 15:35 UTC] konstantin at symbi dot org
I remember I've seen a configuration which passed SCIPT_FILENAME but no 
DOCUMENT_ROOT. (In nginx, you can define any fastcgi variables in the 
configuraton file, there's nothing hardcoded). I have no idea how many such 
configurations exist, may be that one was the single of its kind in the world. 
But it would be definitely wrong to break anything in the 5.3.x branch.

Well, that extra ini setting is probably really unneeded. May be just leave 
support for SCRIPT_FILENAME (handle it always it if is not empty) in 5.3.x, and 
drop it in 5.4?
 [2011-07-20 09:08 UTC] slim at inbox dot lv
probably it is worth to have additional setting to set webserver in use and select appropriate handling method.
Something like "web_server = compliant | apache | iis | anything"
this will simplify appending of hacks for custom implementations of fastcgi protocol
 [2011-07-20 09:16 UTC] konstantin at symbi dot org
IIS? FPM does not support Windows, and IIS does not support remote FastCGI. Either 
ISAPI or local FCGI (via the cgi-fcgi SAPI) are used togerher with IIS, there's 
nothing about fpm.

For all other known webservers, both Jerome's and my proposals should work fine 
AFAIK.
 [2011-10-30 21:03 UTC] mabi at gentoo dot org
What's the status of this? Any chance we can have that fixed for 5.4?
 [2013-05-13 21:48 UTC] fat@php.net
After having analyzing comments, apache behaviour, here is what I propose for this case.

1- add a fpm configuration directive for each pool named "fastcgi_client". Possible values are "rfc3875", "apache_mod_fastcgi", 
"apache_mod_proxy_fcgi" or "backward_compatibility". Defaults to "rfc3875".

2- add a fpm configuration directive for each pool named "document_root". It can be set to a directory. Defaults to (null).

3- add a fpm configuration directive for each pool named "always_run_script". It can be set to a php file. Defaults to (null)

When a request is received:
/*
 *  Use a custom script to do some routage and other stuf
 *  In this case FPM does nothing but to passthrough fastcgi variables
 */
if (fpm.ini[always_run_script] is set) {
  return execute_php(fpm.ini[always_run_script])
}

/*
 *  override DOCUMENT_ROOT if document_root is set in the FPM config
 *  otherwise check the DOCUMENT_ROOT sent is a valid directory 
 */ 
if (fpm_ini[document_root] is set) {
  DOCUMENT_ROOT = fpm.ini[document_root]
  // no need to check if DIR exits as it's been done at conf check
} else {
  if (DOCUMENT_ROOT is not set) {
    return error500 "document root not set"
  }
  if (!is_dir(DOCUMENT_ROOT)) {
    return error500 "Documentroot not found or not a directory"
  }
}


if (fpm.ini[fastcgi_client] == "backward_compatibility") {
  /*
   * Use the same code as before (with microsoft clean up)
   * Will maybe be removed in a later release.
   */
   
  see fpm_main.c in function init_request_info()       

}else if (fpm.ini[fastcgi_client] == "apache_mod_fastcgi" or "apache_mod_proxy_fcgi") {
 /*
  *     *** mod_fastcgi ***
  *    
  *  SCRIPT_NAME is invalid  (/php5-fcgi)
  *  PATH_INFO is set to /test.php/more
  *  SCRIPT_FILENAME is invalid (/tmp/php5-fcgi)
  *  DOCUMENT_ROOT is set correctly
  *  PATH_TRANSLATED = DOCUMENT_ROOT + PATH_INFO
  *  REQUEST_URI is set correctly
  *  QUERY_STRING is set correctly
  *  
  *  ==> use DOCUMENT_ROOT + PATH_INFO                           
  */

  /*
  *     *** mod_proxy_fcgi ***
  *    
  *  everything is buggy in mod_proxy_fcgi
  *  PATH_TRANSLATED is set only if proxy-fcgi-pathinfo is set
  *  PATH_TRANSLATED is set to "proxy:fcgi://host:port" + PATH_INFO
  *  sometimes PATH_TRANSLATED is set to "proxy:fcgi://host:port" + PATH_INFO*2
  *   --> we can rely on PATH_TRANSLATED no matter what
  *          
  *  PATH_INFO is set only if proxy-fcgi-pathinfo is set
  *  PATH_INFO is set to /test.php/more
  *  SCRIPT_NAME is empty if proxy-fcgi-pathinfo is set
  *  SCRIPT_NAME has the same value as PATH_INFO when proxy-fcgi-pathinfo is set
  *   --> we can rely on one of those value. They are the same depending on
  *       proxy-fcgi-pathinfo        
  *
  *  SCRIPT_FILENAME value is consistent and set to 
  *  "proxy:fcgi://host:port" + PATH_INFO
  *           
  *  DOCUMENT_ROOT is set correctly
  *  QUERY_STRING is set correctly  
  *      
  *  ==> we will use PATH_INFO or SCRIPT_NAME and DOCUMENT_ROOT  
  */

  if (fpm.ini[fastcgi_client] == "apache_mod_fastcgi") {
    unset SCRIPT_NAME /* will use PATH_INFO instead */ 
  }

  /* automatic detection for mod_proxy_fcgi */
  if (SCRIPT_NAME null or empty) {
    SCRIPT_NAME = PATH_INFO
    unset PATH_INFO
  }
  
  if (SCRIPT_NAME is empty) {
    return error500("SCRIPT_NAME or PATH_INFO not set")
  }

  /* override PATH_TRANSLATED */  
  PATH_TRANSLATED = DOCUMENT_ROOT + SCRIPT_NAME   
  
  if (php.ini[fix_pathinfo] == 1) {
    /*
     *  Try to determine SCRIPT_FILENAME and PATH_INFO from PATH_TRANSLATED      
     */      
     For each '/' in PATH_TRANSLATED begining from the end of the string {
       SCRIPT_FILENAME = path before the '/'
       PATH_INFO = path after the '/' (with the '/' included)
       if SCRIPT_FILENAME is a valid file {
         PATH_TRANSLATED = DOCUMENT_ROOT + PATH_INFO
         return execute_php(SCRIPT_FILENAME)
       }
       return error404 "file not found"        
     }
  } else {
    /*
     *  Suppose PATH_TRANSLATED is DOCUMENT_ROOT + SCRIPT_NAME
     *  ignore PATH_TRANSLATED and PATH_INFO     
     */
     SCRIPT_FILENAME = PATH_TRANSLATED
     unset PATH_TRANSLATED
     return execute_php(SCRIPT_FILENAME)            
  }    

} else { /* rfc3875 */
  /*
   *  simple as descript in RFC 3875
   *  let PATH_INFO and PATH_TRANSLATED to their value
   *  change nothing as we are supposed to be rfc compliant :-)      
   */   
  
  if (SCRIPT_NAME not set) {
    return error500 "SCRIPT_NAME not set"
  }

  SCRIPT_FILENAME = DOCUMENT_ROOT + SCRIPT_NAME 
  return execute_php(SCRIPT_FILENAME)
}


- "rfc3875" makes things very easy and quick for nginx, lighthttpd and other compliant fastcgi clients. php.ini fix_pathinfo is not 
used in this case.

- "apache_mod_fastcgi" and "apache_mod_proxy_fcgi" makes the code cleaner for apache. Correct values are deducted. php.ini 
fix_pathinfo is still used. If path_info URL are not used, fix_pathinfo can be disabled to avoid doing useless and costy calls to 
stats(). It would be maybe possible to use only one value "apache" and detect which one is used. But I prefer not to to be able to 
differentiate them later if need (as proxy_mod_fcgi could hopefully be updated to fix some of its bugs)

- "backward_compatibility" for those who have older version of apache or else which is not compatible with the previous mode. 
Hopefully it won't be needed and will be removed in a later release.

what guys do you think ???

++ jerome
 [2013-05-13 21:48 UTC] fat@php.net
-Status: Assigned +Status: Analyzed
 [2013-05-13 22:57 UTC] konstantin at symbi dot org
Do the issues with apache_mod_fastcgi still exist? I remember I've tested it 
with my patch and it worked well, maybe you've missed some of its settings?

Personally I don't like introducing such "magic" settings which are unclear on 
what they do. It reminds me of that crappy "broken-scriptfilename" and "fix-
root-scriptname" lighttpd fastcgi settings. I indeed prefer the nginx way where 
every fastcgi variable is configured explicitly.

In general it's OK, but I world prefer more obvious settings with names telling 
about real fastcgi parameters. It's the matter of taste of course.

Anyway, there are two things to take into account: known clients, and backward 
compatibility for any possible configuration. We need to remember that this is 
_remote_ fastcgi, and php-fpm may run on a different machine. For instance, I 
have seen a real life nginx configuration which looked like:

set $remote_php_root /path/to/remote/php/root;
SCRIPT_FILENAME $remote_root_php/$fastcgi_script_name;

and DOCUMENT_ROOT was defined to the front web server root. It is senseless, but 
it worked: SCRIPT_FILENAME was correct, and the php code did not use 
$_SERVER['DOCUMENT_ROOT'] at all.

Also, these changes really should not go to php 5.4 (or go with "compat" mode by 
default). There already have been a BC-breaking change with 
security.limit_extensions in minor update, I believe no one wants one more.
 [2013-05-14 07:44 UTC] fat@php.net
> Do the issues with apache_mod_fastcgi still exist? I remember I've tested it 
> with my patch and it worked well, maybe you've missed some of its settings?

Using a global mod_fastcgi configuration (where everything is sent to FPM) 
returns full compliant fastcgi envars which are compatible 
with the "rfc3875" mode.
Using a specific mod_fastcgi configuration (AddHandler, AddAction and Alias) 
returns buggy fastcgi envars which are compatible with the 
"apache_mod_fastcgi" mode.

> Personally I don't like introducing such "magic" settings which are unclear on 
> what they do. It reminds me of that crappy "broken-scriptfilename" and "fix-
> root-scriptname" lighttpd fastcgi settings. I indeed prefer the nginx way 
where 
> every fastcgi variable is configured explicitly.

I hear you. I don't really mind since the "magic" settings are documented and 
explain what they do. A simple explication "use 
apache_mod_fastcgi is your are using mod_fastcgi using ScriptAlias, 
apache_mod_proxy_fcgi if your using mod_proxy_fcgi, compliant 
otherwise. If you encouters problems, you can back to backward_compatibility". 
And then a more specific explication

"apache_mod_fastcgi: The SCRIPT_FILENAME is deduced using DOCUMENT_ROOT + 
PATH_INFO. If fix_pathinfo is set, then a reverse search is 
made on the string to find out the SCRIPT_FILENAME part and the PATH_INFO part 
by testing (using stat()3) the SCRIPT_FILENAME to ensure 
it exists on disk."

"apache_mod_proxy_fcgi: the SCRIPT_FILENAME is deduced using DOCUMENT_ROOT + 
(PATH_INFO || SCRIPT_NAME). Auto detection is used wether 
to choose PATH_INFO or SCRIPT_NAME (it depends on the proxy-fcgi-pathinfo 
settings). If fix_pathinfo is set, the same treatment is done 
than it's done for apache_mod_fastcgi"

"rfc3875: SCRIPT_FILENAME is deduced using DOCUMENT_ROOT + SCRIPT_NAME. No other 
actions are taken as the PATH_INFO stuff is done by 
the web server"

"backward_compatibility: old code untouched. Will maybe be removed in later 
major release"


> In general it's OK, but I world prefer more obvious settings with names 
telling 
> about real fastcgi parameters. It's the matter of taste of course.

What do you have in mind ?

Another possibility would be to set the transormation rules inside of fpm 
configuration with something like:

envvar[SCRIPT_FILENAME] = "%{DOCUMENT_ROOT}%{SCRIPT_NAME}"
envvar[SCRIPT_NAME] = "%{PATH_INFO}

and keep the usage of fix_pathinfo. If set, SCRIPT_FILENAME is searched for real 
file and PATH_INFO. Otherwise nothing is done.
In the comments, for each kind of configuration (mod_fastcgi, mod_proxy_fcgi, 
nginx, lighttpd) the right settings are documented.

In the case, nothing is changed, try to make autodetection based on 
SERVER_SOFTWARE maybe.

But, even if it's more detailed it's maybe too complex.



> Anyway, there are two things to take into account: known clients, and backward 
> compatibility for any possible configuration. We need to remember that this is 
> _remote_ fastcgi, and php-fpm may run on a different machine. For instance, I 
> have seen a real life nginx configuration which looked like:
> 
> set $remote_php_root /path/to/remote/php/root;
> SCRIPT_FILENAME $remote_root_php/$fastcgi_script_name;
> 
> and DOCUMENT_ROOT was defined to the front web server root. It is senseless, 
but 
> it worked: SCRIPT_FILENAME was correct, and the php code did not use 
> $_SERVER['DOCUMENT_ROOT'] at all.

In all the cases we can't match all the possible solutions, especially ones for 
nginx as everything can be setup as desired.
Such a configuration is marginal, I think, and a little change won't kill anyone 
(I think).

> Also, these changes really should not go to php 5.4 (or go with "compat" mode 
by 
> default). There already have been a BC-breaking change with 
>security.limit_extensions in minor update, I believe no one wants one more.

Agree. The code will be put in 5.3, 5.4 and 5.5 but the default settings will be 
set to "rfc3875" only for 5.5 (if it's not been 
released yet).
 [2017-10-24 05:22 UTC] kalle@php.net
-Status: Analyzed +Status: Assigned
 [2017-10-24 07:43 UTC] kalle@php.net
-Status: Assigned +Status: Open -Assigned To: fat +Assigned To:
 [2023-04-06 15:10 UTC] bukka@php.net
-Status: Open +Status: Wont fix -Assigned To: +Assigned To: bukka
 [2023-04-06 15:10 UTC] bukka@php.net
So finally read through all of this and looked into it. This is obviously very old and things have changed since this was discussed. First of all we cannot just remove cgi.fix_pathinfo as there is like lots of code depending on that behaviour so this would be a big BC break. I don't think we need special handling that was proposed as it is possible to set cgi.fix_pathinfo = 0 and possibly cgi.discard_path = 1 to make it work with nginx, httpd and possibly other servers. Nginx is trivial and I just committed a test for Apache showing how this can be done with mod_proxy_fcgi (only supported module nowadays) and handler: https://github.com/php/php-src/commit/15802dfc62c2c5ee371032dd34110abdad6f367e . The PHP_SELF is a bit mixed up and we have got a special issue for that: https://github.com/php/php-src/issues/11025 . Marking this as won't fix.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Tue Mar 19 06:01:30 2024 UTC