Problème : Comprendre les variables Nginx $host et $http_host
Lors de l'utilisation de Nginx, vous pouvez rencontrer deux variables qui semblent similaires : $host
et $http_host
. Ces variables ont des utilisations différentes et peuvent se comporter différemment selon la situation. Il est important de comprendre leurs différences pour configurer correctement les serveurs et gérer les requêtes dans Nginx.
Que sont $host et $http_host dans Nginx ?
La variable $host dans Nginx
La variable $host dans Nginx représente le nom du serveur pour la requête en cours de traitement. Nginx définit la valeur de $host selon cet ordre :
- Le nom d'hôte de la ligne de requête
- Le nom d'hôte du champ d'en-tête "Host" de la requête
- Le nom de serveur correspondant à la requête
Si aucune de ces sources ne fournit un nom d'hôte valide, Nginx utilise une chaîne vide comme valeur pour $host.
La variable $http_host dans Nginx
La variable $http_host correspond au champ d'en-tête "Host" dans la requête HTTP. Cet en-tête est envoyé par le client (généralement un navigateur web) et contient le nom de domaine du serveur.
Contrairement à $host, $http_host ne passe pas par le traitement de Nginx. Elle reflète la valeur exacte de l'en-tête "Host" telle que reçue dans la requête HTTP. Si l'en-tête "Host" est absent de la requête, $http_host sera une chaîne vide.
Différences clés entre $host et $http_host
Ordre de priorité
Nginx définit la valeur de $host dans un ordre spécifique. Il vérifie d'abord le nom d'hôte dans la ligne de requête. S'il n'est pas disponible, il examine le champ d'en-tête "Host". Si les deux sont absents, il utilise le nom de serveur correspondant à la requête. Cet ordre aide Nginx à gérer différents types de requêtes.
$http_host est utilisé lorsque l'en-tête "Host" est présent dans la requête HTTP. Si l'en-tête est manquant, $http_host reste vide. Contrairement à $host, $http_host n'a pas d'option de secours et reflète directement la requête du client.
Comportement avec les noms de serveur et les noms d'hôte
La variable $host fonctionne avec la directive server_name dans Nginx. Lorsqu'une requête arrive, Nginx la compare aux valeurs server_name dans sa configuration. S'il trouve une correspondance, cette valeur devient une partie de la variable $host. Cela permet d'avoir différentes configurations de blocs serveur basées sur les noms de domaine.
$http_host est lié aux champs d'en-tête de la requête. Il reflète l'en-tête "Host" envoyé par le client. Cela rend $http_host utile pour enregistrer le nom d'hôte exact que le client a utilisé pour accéder au serveur, qui peut être différent du nom de serveur que Nginx utilise en interne.
Utilisation de $host et $http_host dans la configuration Nginx
$host dans les blocs serveur Nginx
La variable $host est utile dans les blocs serveur Nginx avec les directives server_name. Voici un exemple :
server {
listen 80;
server_name example.com www.example.com;
location / {
root /var/www/$host;
}
}
Cette configuration utilise $host pour des chemins de racine de document flexibles. Pour les requêtes vers "example.com", Nginx sert les fichiers depuis "/var/www/example.com". Pour "www.example.com", il utilise "/var/www/www.example.com".
Cette approche :
- Gère plusieurs domaines dans un seul bloc serveur
- Simplifie la configuration pour les sites ayant des structures similaires
- Facilite l'ajout de nouveaux domaines
$http_host pour la journalisation et les redirections
$http_host est utile pour la journalisation et les redirections. Voici comment l'utiliser dans les logs d'accès :
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;
Cette configuration ajoute $http_host à vos logs d'accès, montrant le nom d'hôte que les clients utilisent pour accéder à votre serveur.
Pour les redirections, $http_host aide à maintenir le nom d'hôte original :
server {
listen 80;
server_name example.com www.example.com;
if ($http_host = "www.example.com") {
return 301 $scheme://example.com$request_uri;
}
}
Cette configuration redirige "www.example.com" vers "example.com", en conservant le protocole original ($scheme) et le chemin ($request_uri). L'utilisation de $http_host maintient le nom d'hôte exact de la requête du client, ce qui est important pour des redirections précises.