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
を使用してスクリプトを検索しているようですが、スクリプトはparamsの最後の値を取得します。 DOCUMENT_ROOT
ディレクティブの順序を変更すると、Webサーバーは403
を返します。問題は...どうしてですか?
php
は期待どおりに機能しますが、2番目のSCRIPT_FILENAME
は最初のものをオーバーライドします。
Fastcgiライブラリは、指定されたパラメータをenviron
ポインタに渡すだけです。 fcgiwrap
によって使用されるgetenv()
は、最初に来た環境変数を使用します(最適化?)。 PHP FPMはこの環境を配列データ型と同じように扱い、後者のキーは最初のキーを上書きする可能性があります。
順序に依存せず、キーが1つしかないことを確認してください。正しい動作が文書化されているかどうかにかかわらず、私はFastCGI仕様を見ていません。
why 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) {
_
テストに使用される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;
}
}
}
_
サーバーを起動するコマンド(現在のディレクトリに_nginx.conf
_があると仮定):
_$ nginx -p . -c nginx.conf
$ env -i ./fcgiwrap -p /dev/null -s unix:/tmp/sock
_
ここで、_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?
_
さておき、これは開発バージョンです。現在の安定版(1.1.0)には、上記の_-p
_パラメーターが含まれていません。結果については、実際には問題ではありません。ドロップして、_SCRIPT_NAME
_が指定されていないなどのエラーを受け取った可能性もあります。