ASP.NET Core 3, IIS et en-têtes HTTP vides
Les en-têtes HTTP sont des paires clé/valeur envoyées au début d'une requête ou réponse HTTP, comme Content-Type
, Accept
, User-Agent
, etc. D'après la grammaire définie dans la RFC 7230, il est permis pour un en-tête d'avoir une valeur vide. En pratique, cela n'a sans doute pas beaucoup de sens : sémantiquement, un en-tête avec une valeur vide ou l'absence de cet en-tête sont équivalents.
Cependant, certaines implémentations de client ou serveur HTTP requièrent la présence d'un en-tête donné, même si sa valeur est vide. Par exemple, les tests de validation pour WOPI (un protocole basé sur HTTP pour intégrer Office for the Web dans une application web) exigent la présence d'un header X-WOPI-Lock
dans certaines situations, même si sa valeur est vide (bien que les specs disent que l'en-tête peut être omis).
J'avais une implémentation fonctionnelle d'un hôte WOPI, réalisée avec ASP.NET Core 2.1 et hébergée sur Azure App Service. Tous les tests de validation passaient. Mais après avoir migré l'application vers ASP.NET Core 3.1, certains tests liés aux locks se sont mis à échouer parce que l'en-tête X-WOPI-Lock
était absent. Le code qui envoyait cet en-tête n'avait pas changé, et en testant en local, je voyais que l'en-tête était bien présent. Mais quand l'app était déployée dans Azure, l'en-tête était absent !
Après de longues recherches, j'ai fini par trouver la cause du problème : une pull request sur ASP.NET Core qui supprime les en-têtes vides de la réponse, quand l'application est hébergée sur IIS. Je ne voyais pas le problème en local parce que j'utilisais Kestrel, mais Azure App Service utilise IIS pour héberger les applications. A mon avis, cette modification est une erreur : puisqu'un en-tête vide est valide selon la spec HTTP, ASP.NET Core ne devrait pas le supprimer.
Quoi qu'il en soit, il y a un contournement très simple pour éviter que les en-têtes vides soient supprimés de la réponse : au lieu d'affecter une chaîne vide à l'en-tête, il suffit de lui affecter une chaîne ne contenant que des espaces, comme ceci :
Response.Headers["X-WOPI-Lock"] = " ";
Ainsi l'en-tête ne sera pas supprimé de la réponse, mais sa valeur sera trimmée, ce qui donnera bien au final un en-tête vide, comme on le souhaitait ! Cette solution relève un peu du bricolage et n'est peut-être pas très robuste à long terme, mais elle règle le problème.
Commentaires