nginx + fcgiwrap: como é que a ordem do fastcgi_param é importante?

2

Estou executando Debian 6.0.3 ( squeeze ), nginx-0.7.67 , fcgiwrap-1.0-1+squeeze1 . Aqui está o script de teste:

#!/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 "$<, $>, $(, $)";

E aqui está a configuração 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;
    }
}

Veja o que obtenho no navegador se for para link :

$VAR1 = { 'SCRIPT_NAME' => '/cgi-bin/1.pl', 'DOCUMENT_ROOT' => '/home/yuri/7/', 'WHATEVER' => '2' };

Assim, parece que fcgiwrap usa o primeiro DOCUMENT_ROOT para procurar pelo script, mas o script obtém os últimos valores de params. Se você alterar a ordem das diretivas DOCUMENT_ROOT , o servidor da web retornará 403 . A questão é ... como vem?

php , embora funcione como esperado: o segundo SCRIPT_FILENAME substitui o primeiro.

    
por x-yuri 30.05.2013 / 20:18

1 resposta

1

A biblioteca fastcgi apenas passa os parâmetros que foram dados no ponteiro environ . getenv() como usado por fcgiwrap usa a variável de ambiente que veio primeiro (otimização?). É provável que o PHP FPM trate este ambiente exatamente como o tipo de dados da matriz, e qualquer segunda chave substitui a primeira.

Você não deve confiar no pedido e certificar-se de que haja apenas uma chave. Eu não olhei para a especificação FastCGI, se o comportamento correto está documentado ou não.

Quanto a por que você recebe o 403, eu acho que não há nenhum arquivo /home/yuri/7/1.pl . (lembre-se, o primeiro parâmetro é correspondido pelo fcgiwrap). Como não é executável, o fcgiwrap retorna um 403.

Teste

O patch abaixo imprime o ambiente conforme fornecido por 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) {

configuração nginx usada para o teste:

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;
        }
    }
}

Comandos para iniciar os servidores (assumindo nginx.conf no diretório atual):

$ nginx -p . -c nginx.conf
$ env -i ./fcgiwrap -p /dev/null -s unix:/tmp/sock

Agora, execute curl http://localhost:5555/ e o stderr será impresso:

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?

Além disso, esta é uma versão de desenvolvimento. A atual estável (1.1.0) não contém o parâmetro -p acima. Para os resultados, isso realmente não importa, você poderia muito bem tê-lo descartado e recebido um erro que nenhumSCRIPT_NAME é dado ou algo assim.

    
por 31.05.2013 / 00:25