Partager via


Drainage des demandes avec serveur web ASP.NET Core Kestrel

L’ouverture de connexions HTTP prend beaucoup de temps. Elle nécessite beaucoup de ressources pour HTTPS aussi. Par conséquent, Kestrel tente de réutiliser les connexions par protocole HTTP/1.1. Un corps de la demande doit être entièrement consommé pour permettre la réutilisation de la connexion. L’application ne consomme pas toujours le corps de la demande, comme les requêtes HTTP POST où le serveur renvoie une redirection ou une réponse 404. Dans le cas de redirection HTTP POST :

  • Le client a peut-être déjà envoyé une partie des données POST.
  • Le serveur écrit la réponse 301.
  • La connexion ne peut pas être utilisée pour une nouvelle demande tant que les données POST du corps de la demande précédente n’ont pas été entièrement lues.
  • Kestrel tente de vider le corps de la demande. Le drainage du corps de la demande signifie lire et ignorer les données sans les traiter.

Le processus de drainage fait un compromis entre l’autorisation de réutiliser la connexion et le temps nécessaire pour vider les données restantes :

  • Le drainage a un délai d’attente de cinq secondes, qui n’est pas configurable.
  • Si toutes les données spécifiées par l’en-tête Content-Length ou Transfer-Encoding n’ont pas été lues avant le délai d’expiration, la connexion est fermée.

Parfois, vous pouvez mettre fin à la demande immédiatement, avant ou après l’écriture de la réponse. Par exemple, les clients peuvent avoir des limites de données restrictives. La limitation des données chargées peut être une priorité. Dans ce cas, pour mettre fin à une demande, appelez HttpContext.Abort à partir d’un contrôleur, Razor d’une page ou d’un intergiciel.

Il existe des mises en garde pour appeler Abort :

  • La création de nouvelles connexions peut être lente et coûteuse.
  • Il n’est pas garanti que le client ait lu la réponse avant la fermeture de la connexion.
  • L’appel Abort doit être rare et réservé aux cas d’erreur grave, et non aux erreurs courantes.
    • Appelez Abort uniquement lorsqu’un problème spécifique doit être résolu. Par exemple, appelez Abort si des clients malveillants essaient de publier des données ou lorsqu’il existe un bogue dans le code client qui provoque des requêtes volumineuses ou plusieurs.
    • N’appelez pas Abort pour les erreurs courantes, telles que HTTP 404 (introuvable).

L’appel de HttpResponse.CompleteAsync avant d’appeler Abort garantit que le serveur a terminé l’écriture de la réponse. Toutefois, le comportement du client n’est pas prévisible et il se peut qu’il ne lise pas la réponse avant l’abandon de la connexion.

Ce processus est différent pour HTTP/2, car le protocole prend en charge l’abandon des flux de requêtes individuels sans fermer la connexion. Le délai d’expiration du drainage de cinq secondes ne s’applique pas. S’il existe des données de corps de la demande non lues après la terminaison d’une réponse, le serveur envoie une trame HTTP/2 RST. Les trames de données de corps de la demande supplémentaires sont ignorées.

Si possible, les clients devraient utiliser l’en-tête de demande Expect: 100-continue et attendre que le serveur réponde avant de commencer à envoyer le corps de la demande. Cela permet au client d’examiner la réponse et d’abandonner avant d’envoyer des données inutiles.