Qual é a diferença entre as variáveis ​​Nginx $ host, $ http_host e $ server_name?

42

Qual é a diferença entre as três variáveis Nginx $host, $http_host, e $server_name?

Eu tenho uma regra de reescrita em que não tenho certeza de qual devo usar:

location = /vb/showthread.php {
    # /vb/showthread.php?50271-What-s-happening&p=846039
    if ($arg_p) {
        return 301 $scheme://$host/forum/index.php?posts/$arg_p/;
        }

Estou procurando uma resposta que não diga apenas 'use a variável ___ na sua regra de reescrita', mas também explique as diferenças teóricas entre elas.

Jeff Widman
fonte
Percebi depois que nem precisava especificar $schemee $host... return 301 /forum/index.php?posts/$arg_p/;funciona bem.
22615 Jeff Jeffman
A maioria dos navegadores funcionaria com URL relativo no redirecionamento, mas o padrão ( w3.org/Protocols/rfc2616/rfc2616-sec14.html ) requer um URL absoluto no Locationcabeçalho.
Cthulhu

Respostas:

54

Você quase sempre deve usar $host, pois é o único que garante algo sensato, independentemente de como o agente do usuário se comporte, a menos que você precise especificamente da semântica de uma das outras variáveis.

A diferença é explicada na documentação do nginx :

  • $host contém "nesta ordem de precedência: nome do host da linha da solicitação, ou nome do host do campo de cabeçalho da solicitação 'Host' ou o nome do servidor que corresponde a uma solicitação"
  • $http_host contém o conteúdo do campo de cabeçalho "Host" HTTP, se estiver presente na solicitação
  • $server_namecontém o server_namehost virtual que processou a solicitação, conforme definido na configuração nginx. Se a servercontiver vários server_names, apenas o primeiro estará presente nessa variável.

Como é legal para os agentes do usuário enviarem o nome do host na linha de solicitação, e não no cabeçalho Host:, embora isso raramente seja feito, exceto quando você se conectar a proxies, é necessário prestar contas.

Você também deve considerar o caso em que o agente do usuário não envia um nome de host, por exemplo, solicitações HTTP / 1.0 antigas e software moderno e mal escrito. Você pode fazer isso desviando-os para um host virtual abrangente que não serve para nada, se você estiver servindo vários sites ou se tiver apenas um site no servidor, poderá processar tudo por meio de um único host virtual . Neste último caso, você também deve explicar isso.

Somente a $hostvariável é responsável por todas as coisas possíveis que um agente do usuário pode fazer ao formar uma solicitação HTTP.

Michael Hampton
fonte
2
Por outro lado, $server_nameé seguro quando o Host:campo do UA pode conter conteúdo arbitrário.
Cthulhu
1
O $ http_host é renomeado para $ hostname? Não consigo encontrar essa variável no documento Nginx. $ hostname é o mais semelhante, eu acho.
darkbaby123
3
@ darkbaby123 Não, não foi renomeado para nada. Veja a documentação .
Michael Hampton
1
Ah, agora eu entendo o que a variável http_ <name> significa. Obrigado!
darkbaby123
0

Gostaria de acrescentar outro ponto importante não mencionado na resposta aceita.

$hostque não tem número de porta, enquanto $http_hostnão incluem o número da porta.

editar : nem sempre.

Configurei um cabeçalho "add_header Y-blog-http_host" $ http_host "always;"

Então curl -I -L domain.com:80(ou 443) e o cabeçalho não mostra um número de porta. Verificado com nginx-extra 1.10.3. É porque é comum as portas http (s) ou a configuração nginx? Este comentário apenas para dizer que as coisas nem sempre se comportam da maneira que você pensa.

Mohammed Noureldin
fonte
0

Eu também lutei com isso por um tempo. Ficou claro quando entendi que $ http_XXXXX se refere a todas as variáveis ​​de cabeçalho declaradas.

Portanto, $ http_user_agent, $ http_referer são "USER AGENT", "REFERER" referenciados em letras minúsculas e sublinhadas. Isso me explicou de onde diabos $ http_upgrade estava vindo em muitos exemplos de configuração do NGINX.

Leia-o em https://stackoverflow.com/questions/15414810/whats-the-difference-of-host-and-http-host-in-nginx

luison
fonte