web-dev-qa-db-fra.com

Quelle est la différence entre les variables Nginx $ Host, $ http_Host et $ server_name?

Quelle est la différence entre les trois variables Nginx $Host, $http_Host, et $server_name?

J'ai une règle de réécriture où je ne sais pas laquelle utiliser:

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/;
        }

Je cherche une réponse qui ne dit pas seulement "utilisez la variable ___ dans votre règle de réécriture" mais explique également les différences théoriques entre elles.

46
Jeff Widman

Vous devriez presque toujours utiliser $Host, car c'est la seule garantie d'avoir quelque chose de sensé quel que soit le comportement de l'agent utilisateur, à moins que vous n'ayez spécifiquement besoin de la sémantique de l'une des autres variables.

La différence est expliquée dans la documentation nginx :

  • $Host contient "dans cet ordre de priorité: le nom d'hôte de la ligne de demande, ou le nom d'hôte du champ d'en-tête de demande" Hôte ", ou le nom du serveur correspondant à une demande"
  • $http_Host contient le contenu du champ d'en-tête HTTP "Host", s'il était présent dans la demande
  • $server_name contient le server_name de l'hôte virtuel qui a traité la demande, tel qu'il a été défini dans la configuration nginx. Si un server contient plusieurs server_names, seule la première sera présente dans cette variable.

Puisqu'il est légal pour les agents utilisateurs d'envoyer le nom d'hôte dans la ligne de demande plutôt que dans un en-tête Host:, bien que cela soit rarement fait sauf lors de la connexion à des proxys, vous devez en tenir compte.

Vous devez également tenir compte du cas où l'agent utilisateur n'envoie pas du tout de nom d'hôte, par exemple anciennes requêtes HTTP/1.0 et logiciels modernes mal écrits. Vous pouvez le faire en les détournant vers un hôte virtuel fourre-tout qui ne sert rien, si vous desservez plusieurs sites Web, ou si vous n'avez qu'un seul site Web sur votre serveur, vous pouvez tout traiter via un seul hôte virtuel. . Dans ce dernier cas, vous devez également en tenir compte.

Seulement le $Host variable représente toutes les choses possibles qu'un agent utilisateur peut faire lors de la formation d'une requête HTTP.

56
Michael Hampton

J'ai également eu du mal avec cela pendant un certain temps. Il est devenu clair quand j'ai compris que $ http_XXXXX faisait référence à toutes les variables d'en-tête déclarées.

Ainsi, $ http_user_agent, $ http_referer sont "USER AGENT", "REFERER" référencés en minuscules et soulignés. Cela m'a expliqué d'où venait l'enfer $ http_upgrade dans de nombreux exemples de configuration NGINX.

Lisez-le sur https://stackoverflow.com/questions/15414810/whats-the-difference-of-Host-and-http-Host-in-nginx

1
luison

Je voudrais ajouter un autre point important non mentionné dans la réponse acceptée.

$Host n'a pas [~ # ~] pas [~ # ~] de numéro de port, tandis que $http_Host inclut le numéro de port.

edit : pas toujours.

J'ai mis en place un en-tête "add_header Y-blog-http_Host" $ http_Host "toujours;"

Alors curl -I -L domain.com:80 (ou 443) et l'en-tête n'affiche pas du tout de numéro de port. Vérifié avec nginx-extra 1.10.3. Est-ce parce qu'il s'agit de ports http (s) courants ou d'une configuration nginx? Ce commentaire juste pour dire que les choses ne se comportent pas toujours comme vous le pensez.

1
Mohammed Noureldin