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 ___ variável em sua regra de reescrita', mas também explique as diferenças teóricas entre elas.
Você deve quase sempre usar
$host
, pois é o único garantido para ter algo sensato, independentemente de como o user-agent se comporta, 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 de solicitação ou nome do host do campo de cabeçalho da solicitação 'Host' ou o nome do servidor correspondente a uma solicitação"$http_host
contém o conteúdo do campo de cabeçalho HTTP "Host", se estiver presente na solicitação$server_name
contém oserver_name
do host virtual que processou a solicitação, conforme definido na configuração do nginx. Se aserver
contiver váriosserver_name
s, apenas o primeiro estará presente nesta variável.Como é legal que os agentes do usuário enviem o nome do host na linha de solicitação em vez de no cabeçalho Host:, embora raramente seja feito, exceto ao conectar-se a proxies, você deve levar isso em consideração.
Você também deve levar em consideração o caso em que o agente do usuário não envia um nome de host, por exemplo, antigas solicitações HTTP/1.0 e software moderno mal escrito. Você pode fazer isso desviando-os para um host virtual abrangente que não serve para nada, se você estiver atendendo a vários sites ou se tiver apenas um único site em seu servidor, poderá processar tudo por meio de um único host virtual . Neste último caso, você também deve contabilizar isso.
Somente a
$host
variável responde por todas as coisas possíveis que um agente do usuário pode fazer ao formar uma solicitação HTTP.Gostaria de acrescentar outro ponto importante não mencionado na resposta aceita.
$host
NÃO tem número de porta , enquanto$http_host
inclui o número da porta.editar : nem sempre.
Eu configurei um cabeçalho "add_header Y-blog-http_host "$http_host" sempre;"
Então
curl -I -L domain.com:80
(ou 443) e o cabeçalho não mostra nenhum número de porta. Verificado com nginx-extra 1.10.3. É porque são portas http(s) comuns ou configuração nginx? Este comentário apenas para dizer que as coisas nem sempre se comportam da maneira que você pensa.Eu também lutei com isso por um tempo. Ficou claro quando entendi que $http_XXXXX refere-se 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 barra inferior. Isso me explicou de onde diabos $http_upgrade estava vindo em muitos exemplos de configuração do NGINX.
Leia em https://stackoverflow.com/questions/15414810/whats-the-difference-of-host-and-http-host-in-nginx
TL;DR: Se você não usa expressões regulares,
server_name
pode ignorar esta resposta ?.Como esse aspecto não foi mencionado em outras respostas, mas é algo que achei um tanto irritante: eu uso
$host
na criação dos nomes dos meus arquivos de log, assim:Infelizmente, se você usar uma expressão regular em sua
server_name
estrofe como:Na verdade, você
$host
acabará contendo a expressão regular assim (sim, incluindo a barra invertida e tudo):Eu, pelo menos, achei isso muito chato e acabei mudando minha expressão regular para:
para capturar o nome completo para reutilização no nome do arquivo de log. A respectiva estrofe foi então alterada para: