我正在运行Debian 6.0.3
( squeeze
), nginx-0.7.67
, fcgiwrap-1.0-1+squeeze1
。这是测试脚本:
#!/usr/bin/perl
use 5.010;
use warnings;
use strict;
use Data::Dumper;
print "Content-Type: text/html\n\n";
say Dumper {map {$_ => $ENV{$_}} 'SCRIPT_NAME', 'DOCUMENT_ROOT', 'WHATEVER'};
say "$<, $>, $(, $)";
这是nginx
配置:
server {
server_name domain.com;
root /home/yuri/6;
access_log /var/log/nginx/domain.com-access.log;
error_log /var/log/nginx/domain.com-error.log;
location /cgi-bin/ {
fastcgi_pass unix:/var/run/fcgiwrap.socket;
fastcgi_param DOCUMENT_ROOT $document_root;
fastcgi_param DOCUMENT_ROOT /home/yuri/7/;
fastcgi_param SCRIPT_NAME $fastcgi_script_name;
fastcgi_param WHATEVER 1;
fastcgi_param WHATEVER 2;
}
location /1.php {
fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_param PHP_ADMIN_VALUE cgi.fix_pathinfo=1;
fastcgi_param REQUEST_METHOD $request_method;
fastcgi_param SCRIPT_FILENAME whatever;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
}
如果转到 url http://domain.com/cgi-bin/1.pl ,这是我在浏览器中得到的:
$VAR1 = { 'SCRIPT_NAME' => '/cgi-bin/1.pl', 'DOCUMENT_ROOT' => '/home/yuri/7/', 'WHATEVER' => '2' };
看起来,它fcgiwrap
使用第一个DOCUMENT_ROOT
来查找脚本,但脚本获取参数的最后一个值。如果您更改DOCUMENT_ROOT
指令的顺序,Web 服务器将返回403
. 问题是……怎么会呢?
php
虽然按预期工作:第二个SCRIPT_FILENAME
覆盖第一个。
fastcgi 库只是将给定的任何参数传递给
environ
指针。getenv()
所使用的fcgiwrap
任何环境变量首先出现(优化?)。PHP FPM 很可能像对待数组数据类型一样对待这个环境,后面的任何键都会覆盖第一个。您不应该依赖顺序并确保只有一把钥匙。我没有看过 FastCGI 规范,是否记录了正确的行为。
至于为什么会出现403,估计是没有
/home/yuri/7/1.pl
文件吧。(记住,第一个参数由 fcgiwrap 匹配)。由于它不可执行,fcgiwrap 返回 403。测试
下面的补丁打印了由给出的环境
FCGI_Accept()
:测试使用的nginx配置:
启动服务器的命令(假设
nginx.conf
在当前目录中):现在,运行
curl http://localhost:5555/
,stderr 将打印:另外,这是一个开发版本。当前稳定版 (1.1.0) 不包含上述
-p
参数。对于结果来说,这并不重要,你也可以放弃它并收到一个没有SCRIPT_NAME
给出或其他东西的错误。