Problema: Entendendo as Variáveis $host vs $http_host do Nginx
Ao usar o Nginx, você pode encontrar duas variáveis que parecem semelhantes: $host
e $http_host
. Essas variáveis têm usos diferentes e podem se comportar de maneira distinta dependendo da situação. Entender como elas diferem é importante para configurar servidores e lidar com requisições no Nginx corretamente.
O que são $host e $http_host no Nginx?
Variável $host no Nginx
A variável $host no Nginx representa o nome do servidor para a requisição sendo processada. O Nginx define o valor de $host usando esta ordem:
- O nome do host da linha de requisição
- O nome do host do campo de cabeçalho "Host" da requisição
- O nome do servidor que corresponde à requisição
Se nenhuma dessas fontes fornecer um nome de host válido, o Nginx usa uma string vazia como valor para $host.
Variável $http_host no Nginx
A variável $http_host corresponde ao campo de cabeçalho "Host" na requisição HTTP. Este cabeçalho é enviado pelo cliente (geralmente um navegador web) e contém o nome de domínio do servidor.
Diferentemente de $host, $http_host não passa pelo processamento do Nginx. Ela reflete o valor exato do cabeçalho "Host" como recebido na requisição HTTP. Se o cabeçalho "Host" estiver ausente na requisição, $http_host será uma string vazia.
Principais Diferenças Entre $host e $http_host
Ordem de Precedência
O Nginx define o valor de $host em uma ordem específica. Primeiro, verifica o nome do host na linha de requisição. Se não estiver disponível, olha para o campo de cabeçalho "Host". Se ambos estiverem ausentes, usa o nome do servidor que corresponde à requisição. Esta ordem ajuda o Nginx a lidar com diferentes tipos de requisições.
$http_host é usado quando o cabeçalho "Host" está presente na requisição HTTP. Se o cabeçalho estiver ausente, $http_host permanece vazio. Diferentemente de $host, $http_host não tem uma opção de backup e reflete diretamente a requisição do cliente.
Comportamento com Nomes de Servidor e Hostnames
A variável $host funciona com a diretiva server_name no Nginx. Quando uma requisição chega, o Nginx a compara com os valores de server_name em sua configuração. Se encontrar uma correspondência, esse valor se torna parte da variável $host. Isso permite diferentes configurações de blocos de servidor baseadas em nomes de domínio.
$http_host está ligado aos campos de cabeçalho da requisição. Ele espelha o cabeçalho "Host" enviado pelo cliente. Isso torna $http_host útil para registrar o nome de host exato que o cliente usou para acessar o servidor, que pode ser diferente do nome de servidor que o Nginx usa internamente.
Usando $host e $http_host na Configuração do Nginx
$host em Blocos de Servidor do Nginx
A variável $host é útil em blocos de servidor do Nginx com diretivas server_name. Aqui está um exemplo:
server {
listen 80;
server_name example.com www.example.com;
location / {
root /var/www/$host;
}
}
Esta configuração usa $host para caminhos flexíveis de diretório raiz. Para requisições para "example.com", o Nginx serve arquivos de "/var/www/example.com". Para "www.example.com", usa "/var/www/www.example.com".
Esta abordagem:
- Lida com múltiplos domínios em um único bloco de servidor
- Simplifica a configuração para sites com estruturas similares
- Facilita a adição de novos domínios
$http_host para Logs e Redirecionamentos
$http_host é útil para logs e redirecionamentos. Aqui está como usá-lo em logs de acesso:
log_format custom '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent" "$http_host"';
access_log /var/log/nginx/access.log custom;
Esta configuração adiciona $http_host aos seus logs de acesso, mostrando o nome de host que os clientes usam para acessar seu servidor.
Para redirecionamentos, $http_host ajuda a manter o nome de host original:
server {
listen 80;
server_name example.com www.example.com;
if ($http_host = "www.example.com") {
return 301 $scheme://example.com$request_uri;
}
}
Esta configuração redireciona "www.example.com" para "example.com", mantendo o protocolo original ($scheme) e o caminho ($request_uri). Usar $http_host mantém o nome de host exato da requisição do cliente, o que é importante para redirecionamentos precisos.