Este é um servidor Ubuntu rodando PHP 7 no Apache, com um site que impõe TLS (usando a porta padrão). No meu entender, https://example.com
e https://example.com:443
são exatamente equivalentes (e, de fato, no meu navegador o número da porta desaparece da barra de endereços quando eu digito). E, no entanto, HTTP_HOST
geralmente contém apenas o nome do domínio, mas às vezes também contém o número da porta. Isso pode ser para visitantes de bots (não analisei logs), mas mesmo assim não vejo como. Existe alguma diferença real?
(Isso está causando alguns problemas, pois alguns de nossos logs e filas de trabalho e cache do lado do servidor são separados por HTTP_HOST
, portanto, ter o mesmo relatório de site em diferentes hosts é confuso.)
A documentação do PHP afirma que
$_SERVER['HTTP_HOST']
é:De fato, cada variável nesse array associativo cuja chave começa com a string
HTTP_
é uma cópia da variável de solicitação HTTP correspondente enviada pelo agente do usuário.Então, por que às vezes contém o nome do host e às vezes contém o nome do host e o número da porta?
Acontece que ambas as sintaxes são legais e equivalentes. O número da porta é obrigatório se o servidor usar uma porta não padrão, mas é opcional caso contrário.
Em que circunstâncias um agente de usuário enviaria o número da porta mesmo quando fosse o padrão?
A seção 5.4 da RFC 7230 explica que o valor do cabeçalho Host: é uma cópia exata do componente de autoridade do URI.
Qual é o componente de autoridade?
Isso vem da definição de um URI na RFC 3986 seção 3.2 , que explica que são as informações do usuário (nome de usuário e senha), host e porta. Ele explica que a porta DEVE ser omitida se for a porta padrão, mas DEVE não ser igual a DEVE. (Veja RFC 2119. )
Portanto, para juntar tudo isso, espera-se que um agente do usuário envie o número da porta no cabeçalho Host: se ele também aparecer no URI. Assim, se o agente do usuário tiver a URL
https://example.com:443/robots.txt
, ele terá um cabeçalhoHost: example.com:443
. Como o agente do usuário obteve tal URL, não há como saber. Ele pode ter sido enviado pelo seu aplicativo ou pode ter sido construído pelo agente do usuário.A seção 2.7.3 da RFC 7230 explica a normalização de URL que, neste caso, indica que uma URL que não contém número de porta e uma URL que contém o número de porta padrão são equivalentes.
TL;DR: Seu aplicativo deve esperar que um número de porta apareça neste cabeçalho e tratá-lo de alguma forma apropriada ao contexto em que é usado.
Você pode considerar usar
$_SERVER['SERVER_NAME']
, que contém o valor daServerName
diretiva no Apache<VirtualHost>
que processou a solicitação (ou, para nginx, a primeiraserver_name
noserver
bloco).