Qual é a Diferença entre as Variáveis Nginx $host e $http_host?

Publicado 27 de agosto de 2024

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:

  1. O nome do host da linha de requisição
  2. O nome do host do campo de cabeçalho "Host" da requisição
  3. 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.