Problème : Les en-têtes HTTP avec des tirets bas supprimés par Nginx
Nginx, un serveur web et proxy inverse, supprime par défaut les en-têtes HTTP contenant des tirets bas. Cela peut causer des problèmes lors de l'utilisation d'en-têtes personnalisés ou de services tiers qui utilisent des en-têtes avec des tirets bas, entraînant une perte de données ou des problèmes dans les applications web.
Gestion par défaut des en-têtes avec tirets bas par Nginx
La suppression silencieuse : Comportement par défaut de Nginx
Nginx supprime par défaut les en-têtes contenant des tirets bas. Cela se produit sans avertissement ni message d'erreur. Lorsque Nginx reçoit une requête avec des en-têtes contenant des tirets bas, il supprime ces en-têtes avant d'envoyer la requête au serveur backend ou à l'application. Cette suppression peut causer des problèmes dans les applications web qui utilisent ces en-têtes personnalisés pour des fonctionnalités ou le transfert de données.
La nature cachée de ce processus rend difficile pour les développeurs et les administrateurs système de trouver la cause des problèmes liés aux données d'en-tête manquantes. Les utilisateurs peuvent passer du temps à déboguer leurs applications, sans savoir que Nginx supprime leurs en-têtes personnalisés. Ce comportement par défaut peut être problématique lors du travail avec des services tiers ou des API qui utilisent des en-têtes avec des tirets bas, car il peut perturber le flux d'informations entre les systèmes.
Conseil: Vérifier la configuration Nginx
Pour vérifier si Nginx supprime les en-têtes avec des tirets bas, vous pouvez ajouter un en-tête personnalisé avec un tiret bas dans votre requête client, puis utiliser un mécanisme de journalisation backend ou un outil de débogage pour vérifier si l'en-tête atteint votre application. Si l'en-tête est manquant, il est probable qu'il soit supprimé par Nginx.
La cause profonde : Héritage CGI et mappage des en-têtes
Contexte historique : Variables CGI et conversion des en-têtes
Le comportement de Nginx consistant à supprimer les en-têtes avec des tirets bas découle de l'héritage du Common Gateway Interface (CGI). CGI est une ancienne norme permettant aux serveurs web d'exécuter des programmes externes et de renvoyer leur sortie aux clients web. Il a influencé la manière dont les serveurs web gèrent les en-têtes HTTP.
Dans CGI, les en-têtes HTTP sont convertis en variables d'environnement utilisables par les scripts. Lors de cette conversion, les tirets et les tirets bas dans les noms d'en-têtes sont transformés en tirets bas. Par exemple, un en-tête comme "Custom-Header" devient "HTTP_CUSTOM_HEADER" en tant que variable d'environnement CGI. Ce processus peut créer une confusion lorsque les en-têtes contiennent déjà des tirets bas.
Pour éviter ces ambiguïtés, Nginx supprime par défaut les en-têtes avec des tirets bas. Cette décision évite les problèmes où différents en-têtes pourraient être mappés au même nom de variable CGI. Par exemple, "Custom_Header" et "Custom-Header" deviendraient tous deux "HTTP_CUSTOM_HEADER" en CGI, rendant peu clair quel en-tête original la variable représente.
Bien que cette approche résolve le problème d'ambiguïté, elle peut causer un comportement inattendu dans les applications web modernes qui n'utilisent pas CGI et s'appuient sur des en-têtes personnalisés avec des tirets bas. Comprendre ce contexte historique aide à expliquer pourquoi Nginx gère ainsi les en-têtes contenant des tirets bas, même si ce n'est pas toujours le comportement souhaité dans les pratiques actuelles de développement web.
Conseil: Gestion des en-têtes avec tirets bas dans Nginx
Pour autoriser les en-têtes avec des tirets bas dans Nginx, vous pouvez utiliser la directive underscores_in_headers on;
dans votre configuration Nginx. Ajoutez cette ligne à votre bloc server
ou location
pour activer le traitement des en-têtes contenant des tirets bas.
Normes HTTP et conventions de nommage des en-têtes
Clarification de la RFC HTTP
La RFC HTTP (Request for Comments) autorise l'utilisation de tirets bas dans les noms d'en-têtes. Cela est souvent mal compris par les développeurs et les administrateurs système. La spécification HTTP permet de nombreux caractères dans les noms d'en-têtes, y compris les tirets bas.
La confusion vient souvent d'une mauvaise interprétation des règles de caractères ASCII dans la RFC. La spécification HTTP/1.1 (RFC 2616) fait référence à la RFC 822 pour les formats des champs d'en-tête. La RFC 822 stipule que les noms de champs doivent utiliser des caractères ASCII imprimables, ce qui inclut les caractères avec des valeurs décimales entre 33 et 126, à l'exception des deux-points. Le caractère tiret bas (valeur décimale 95) est dans cette plage autorisée.
Certains développeurs pensent que les tirets bas ne sont pas autorisés car certains serveurs web, comme Apache ou Nginx, les traitent comme invalides par défaut. Cependant, il s'agit d'un choix spécifique au serveur, pas d'une exigence de la norme HTTP.
Bien que les tirets bas soient autorisés dans les noms d'en-têtes HTTP selon la RFC, leur utilisation peut causer des problèmes avec certains serveurs ou proxys qui ne sont pas configurés pour les gérer. Pour cette raison, il est souvent préférable d'utiliser des tirets plutôt que des tirets bas dans les noms d'en-têtes personnalisés pour éviter des problèmes potentiels.
Conseil: Meilleures pratiques de nommage des en-têtes
Lors de la création d'en-têtes HTTP personnalisés, utilisez des tirets au lieu de tirets bas pour améliorer la compatibilité entre différents serveurs et systèmes. Par exemple, utilisez "Custom-Header" plutôt que "Custom_Header".
Exemple: Compatibilité des en-têtes HTTP
Considérez un scénario où vous développez une API qui utilise des en-têtes personnalisés pour transmettre des informations supplémentaires. Vous pourriez être tenté d'utiliser un en-tête comme "API_Version" pour indiquer la version de votre API. Cependant, pour maximiser la compatibilité, il est préférable d'utiliser "API-Version" à la place. Cela garantit que votre en-tête sera correctement traité par une plus large gamme de serveurs et d'intermédiaires.
Résolution du problème des en-têtes avec tirets bas dans Nginx
Activation des en-têtes avec tirets bas : La solution de configuration
Pour résoudre le problème de la suppression par Nginx des en-têtes contenant des tirets bas, vous pouvez utiliser la directive 'underscores_in_headers on;' dans votre configuration Nginx. Cette directive indique à Nginx d'accepter et de transmettre les en-têtes contenant des tirets bas.
Pour mettre en œuvre cette solution, ajoutez la ligne suivante à votre configuration Nginx :
underscores_in_headers on;
Vous pouvez placer cette directive à différents endroits dans votre fichier de configuration Nginx, selon l'étendue de son application :
- Bloc server : Si vous voulez activer les en-têtes avec tirets bas pour un serveur spécifique, ajoutez la directive à l'intérieur du bloc server. Par exemple :
server {
listen 80;
server_name example.com;
underscores_in_headers on;
# Autres configurations du serveur...
}
- Bloc http : Pour activer les en-têtes avec tirets bas pour tous les serveurs, placez la directive dans le bloc http de votre configuration Nginx :
http {
underscores_in_headers on;
# Autres configurations http...
}
- Bloc location : Si vous avez seulement besoin d'autoriser les en-têtes avec tirets bas pour des emplacements spécifiques, ajoutez la directive au bloc location concerné :
location /api {
underscores_in_headers on;
# Autres configurations de location...
}
Après avoir ajouté la directive, redémarrez Nginx pour appliquer les changements. Cela permettra à Nginx de traiter et de transmettre les en-têtes contenant des tirets bas, résolvant ainsi le problème des en-têtes personnalisés manquants dans vos applications.
N'oubliez pas de tester votre configuration après avoir effectué ces modifications pour vous assurer que tout fonctionne comme prévu.
Conseil: Vérifier les en-têtes avec tirets bas
Après avoir activé les en-têtes avec tirets bas dans Nginx, vous pouvez vérifier s'ils sont correctement transmis en utilisant un outil comme cURL. Voici un exemple de commande :
curl -I -H "X_Custom_Header: TestValue" http://votre-domaine.com
Cette commande envoie une requête avec un en-tête personnalisé contenant un tiret bas. Vérifiez les en-têtes de réponse pour confirmer que votre en-tête personnalisé est présent et n'a pas été supprimé par Nginx.