AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / server / 问题 / 512028
Accepted
x-yuri
x-yuri
Asked: 2013-05-31 10:18:18 +0800 CST2013-05-31 10:18:18 +0800 CST 2013-05-31 10:18:18 +0800 CST

nginx + fcgiwrap:为什么 fastcgi_param 的顺序很重要?

  • 772

我正在运行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覆盖第一个。

nginx
  • 1 1 个回答
  • 8725 Views

1 个回答

  • Voted
  1. Best Answer
    Lekensteyn
    2013-05-31T14:25:40+08:002013-05-31T14:25:40+08:00

    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) {
    

    测试使用的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给出或其他东西的错误。

    • 6

相关问题

  • Gzip 与反向代理缓存

  • nginx 作为代理的行为

  • Nginx 学习资源 [关闭]

  • 提供 70,000 个静态文件 (jpg) 的最佳方式?

  • 在 Apache、LightTPD 和 Nginx Web 服务器上提供 PHP 5.x 应用程序的现状?

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    新安装后 postgres 的默认超级用户用户名/密码是什么?

    • 5 个回答
  • Marko Smith

    SFTP 使用什么端口?

    • 6 个回答
  • Marko Smith

    命令行列出 Windows Active Directory 组中的用户?

    • 9 个回答
  • Marko Smith

    什么是 Pem 文件,它与其他 OpenSSL 生成的密钥文件格式有何不同?

    • 3 个回答
  • Marko Smith

    如何确定bash变量是否为空?

    • 15 个回答
  • Martin Hope
    Tom Feiner 如何按大小对 du -h 输出进行排序 2009-02-26 05:42:42 +0800 CST
  • Martin Hope
    Noah Goodrich 什么是 Pem 文件,它与其他 OpenSSL 生成的密钥文件格式有何不同? 2009-05-19 18:24:42 +0800 CST
  • Martin Hope
    Brent 如何确定bash变量是否为空? 2009-05-13 09:54:48 +0800 CST
  • Martin Hope
    cletus 您如何找到在 Windows 中打开文件的进程? 2009-05-01 16:47:16 +0800 CST

热门标签

linux nginx windows networking ubuntu domain-name-system amazon-web-services active-directory apache-2.4 ssh

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve