$ sent_http_ variáveis desaparecem no Nginx em algumas circunstâncias

2

Eu enfrento um problema estranho com o Nginx. Esta é uma configuração mínima que reproduz o erro:

server {
    server_name     mydomain.com;
    listen          111.111.111.111:80;
    root            /some/path;

    set     $some_var   $sent_http_content_type;
    add_header  "X-Debug" $sent_http_content_type;
}

Nesse caso, X-Debug header nunca é mostrado na resposta. Mas, se eu comentar esta linha:

set     $some_var   $sent_http_content_type;

tudo funciona. Parece muito estranho para mim porque essa linha não reatribui o $sent_http_content_type var, mas apenas lê.

Parece que pertence apenas às variáveis $sent_http_ .

Eu também tentei "${sent_http_content_type}" em vez de $sent_http_content_type com o mesmo resultado.

A diretiva

more_set_headers não corrige isso.

Por que o Nginx se comporta assim? Isso é um bug?

Edit:
O exemplo que forneci é apenas o caso mais simples em que $sent_http_ vars desappear. Na verdade, quero fazer algo assim:

if ($sent_http_access_control_allow_origin ~ "^(https?)://([^/]+)") {
    set $new_cors http://$1.$2.proxy.mydomain.com;
}
more_set_headers "Access-Control-Allow-Origin: $new_cors";

Eu escrevo um servidor proxy e preciso substituir o Access-Control-Allow-Origin response header porque, caso contrário, os sites com proxy não funcionam como esperado.

No exemplo acima, if condition (em server section) nunca produz true , mesmo que haja tal cabeçalho e se ajuste à minha expressão regular.

Isso pode ser corrigido? Aprecie sua ajuda!

    
por Oleg 29.02.2016 / 20:33

1 resposta

1

O módulo rewrite do Nginx (no qual as variáveis e a diretiva set pertencem) é bastante não-intuitivo e frágil. Mas, na verdade,

set     $some_var   $sent_http_content_type;

não tem sentido, pois a diretiva set é executada no início da solicitação e não há variáveis $sent_http_* disponíveis no momento.

O que você poderia fazer (se realmente quiser usar $sent_http_* variables de alguma forma) é usar a diretiva map .

map $sent_http_content_type $some_var {
    default $sent_http_content_type;
}

...
server {
    ...
    add_header "X-Debug"  $sent_http_content_type;
    add_header "X-Debug2" $some_var;
}

EDIT: Seu problema poderia ser resolvido com mais map s, mas seria muito mais fácil se você pudesse usar o módulo Lua.

Veja como isso pode ser feito com map s: (bastante ilegível e insustentável)

map $sent_http_access_control_allow_origin $__proto {
    default "NONE";
    "~^(?<_>https?):" "$_";
}

map $sent_http_access_control_allow_origin $__host {
    default "";
    "~^https?://(?<_>[^/]+)" "$_";
}

map "http://$__proto.$__host.proxy.mydomain.com" $new_cors {
    default "";
    "~^http://NONE" "";
    "~^(?<_>.+)$" "$_";
}
    
por 01.03.2016 / 08:39