我正在运行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 "$<, $>, $(, $)";
Run Code Online (Sandbox Code Playgroud)
这是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;
}
}
Run Code Online (Sandbox Code Playgroud)
如果要访问 url http://domain.com/cgi-bin/1.pl,这是我在浏览器中得到的:
$VAR1 = { 'SCRIPT_NAME' => '/cgi-bin/1.pl', 'DOCUMENT_ROOT' => '/home/yuri/7/', 'WHATEVER' => '2' };
Run Code Online (Sandbox Code Playgroud)
所以看起来,它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()
:
diff --git a/fcgiwrap.c b/fcgiwrap.c
index e86ff9d..0dff2e6 100644
--- a/fcgiwrap.c
+++ b/fcgiwrap.c
@@ -470,6 +470,11 @@ static void inherit_environment(void)
char * const * p;
char *q;
+ for (p = environ; *p; p++)
+ fprintf(stderr, "ENV: %s\n", *p);
+
+ fprintf(stderr, "ENV[FOO] = %s\n", getenv("FOO"));
+
for (p = inherited_environ; *p; p++) {
q = strchr(*p, '=');
if (!q) {
Run Code Online (Sandbox Code Playgroud)
用于测试的nginx配置:
events {
worker_connections 768;
}
pid pid;
error_log error_log;
http {
server {
access_log off;
listen 5555;
location / {
fastcgi_param FOO BAR;
fastcgi_param FOO BARRED;
fastcgi_pass unix:/tmp/sock;
}
}
}
Run Code Online (Sandbox Code Playgroud)
启动服务器的命令(假设nginx.conf
在当前目录中):
$ nginx -p . -c nginx.conf
$ env -i ./fcgiwrap -p /dev/null -s unix:/tmp/sock
Run Code Online (Sandbox Code Playgroud)
现在,运行curl http://localhost:5555/
,stderr 将打印:
ENV: FCGI_ROLE=RESPONDER
ENV: FOO=BAR
ENV: FOO=BARRED
ENV: HTTP_USER_AGENT=curl/7.30.0
ENV: HTTP_HOST=localhost:5555
ENV: HTTP_ACCEPT=*/*
ENV[FOO] = BAR
Cannot get script name, are DOCUMENT_ROOT and SCRIPT_NAME (or SCRIPT_FILENAME) set and is the script executable?
Run Code Online (Sandbox Code Playgroud)
另外,这是一个开发版本。当前稳定版(1.1.0)不包含-p
上述参数。对于结果来说,这并不重要,您也可以放弃它并收到一个没有SCRIPT_NAME
给出的错误或其他错误。
归档时间: |
|
查看次数: |
8258 次 |
最近记录: |