Résumé

  • Publié sur la voie normative de l’IETF en août 2026, RFC 10036 définit le champ HTTP booléen Incremental. La valeur ?1 demande aux intermédiaires qui la prennent en charge de transmettre le contenu d’un message au fil de son arrivée ; elle ne prouve pas que toute la chaîne sait le faire.
  • Un intermédiaire compatible devrait envoyer la section d’en-tête puis faire progresser les octets au lieu d’attendre le message entier. Il peut toutefois mettre en tampon les en-têtes, les trailers et de petits volumes de contenu. S’il comprend la demande mais la refuse entièrement, il doit produire une erreur plutôt que la remplacer silencieusement par un stockage complet.

Prenons un service d’alertes qui émet une observation toutes les deux secondes. L’origine envoie la section d’en-tête, puis la première observation. Le proxy frontal les laisse passer. Le dispositif d’inspection suivant attend la fin de la réponse pour analyser le corps. Or cette fin n’est prévue que plusieurs heures plus tard. L’origine voit des écritures réussies, le proxy garde une connexion active et le client attend : trois états localement cohérents, aucun signal livré.

Le problème n’est pas que le champ a menti. Le problème est de lui avoir attribué une autorité qu’il n’a jamais reçue.

RFC 10036 part de la latitude existante dans la sémantique HTTP. Un destinataire peut traiter un message par portions ; un intermédiaire peut aussi retarder sa transmission ou le mettre entièrement en tampon. Ce choix sert parfois la sécurité, les transformations, la disponibilité ou l’efficacité. Il devient incompatible avec une application dont le résultat dépend de progrès visibles avant la fin du message.

Les Server-Sent Events illustrent le cas le plus simple : la réponse reste ouverte pour porter une suite d’événements. Attendre son achèvement revient à ne rien transmettre. Le projet sur les Chunked Oblivious HTTP Messages, cité par RFC 10036 comme travail en cours, expose un verrou plus symétrique : si le serveur doit répondre pendant que le client continue d’envoyer sa requête, le stockage complet d’un seul sens peut immobiliser les deux.

Le nouveau champ ne supprime donc pas les décisions locales. Il leur donne un vocabulaire et interdit à un refus conscient de se cacher derrière une réponse ordinaire.

?1, ?0, absence et valeur invalide ne disent pas la même chose

Le champ est un Item conforme à Structured Field Values for HTTP. Seules les valeurs booléennes sont valides.

Incremental: ?1 exprime la demande de transfert progressif. Incremental: ?0 conserve le comportement par défaut, dans lequel l’intermédiaire peut attendre le message entier ; cette indication explicite peut même renforcer sa confiance dans ce choix. L’absence du champ ne formule aucune demande au titre de RFC 10036. Une valeur d’un autre type est ignorée.

Ces états ont des conséquences différentes. ?1 n’est pas un verrou appliqué de bout en bout. ?0 n’ordonne pas de tout stocker. Le silence ne vaut pas refus. Une syntaxe ignorée ne prouve ni l’acceptation ni l’opposition du chemin. Avant toute conclusion, il faut savoir ce que chaque destinataire a effectivement analysé et compris.

Le registre IANA des champs HTTP inscrit désormais Incremental comme nom permanent, de type structuré Item, avec RFC 10036 pour référence. IANA protège ici une grammaire commune. Le registre ne déploie aucun proxy et ne mesure aucun délai.

La direction suit le message, pas la conversation

Une application peut exiger que le corps de la requête avance vers le serveur et que la réponse commence avant la fin de cette requête. Dans ce cas, chaque message doit porter son propre Incremental: ?1. La valeur de la requête ne se propage pas par implication à la réponse. Une réponse bien signalée ne libère pas rétroactivement des octets que le chemin aller a déjà retenus.

Cette règle paraît élémentaire, mais les outils la gomment souvent sous un seul attribut « streaming ». Le chemin logique de la requête et celui de la réponse peuvent traverser des adaptateurs différents, des politiques de sécurité différentes et des files de capacité différentes. Une nouvelle tentative peut changer de point de présence ou de connexion amont. Une preuve sérieuse conserve le sens, le numéro de tentative, l’identité du message et le parcours observé.

Lorsqu’il reçoit ?1, un intermédiaire qui prend en charge le mécanisme ne devrait pas attendre le corps entier. Il devrait transmettre la section d’en-tête, puis les octets de contenu à mesure qu’ils arrivent. Mais la portée du champ est le contenu : l’intermédiaire peut attendre la section d’en-tête complète et retenir la section de trailers complète. « Incrémental » n’est donc pas synonyme de « chaque octet est immédiatement un paquet ».

La même demande s’adresse aux bibliothèques et API HTTP. La plupart savent exposer un lecteur ou un écrivain progressif ; celles qui introduisent un tampon devraient le réduire ou le désactiver en présence du champ. Une API de streaming ne dit cependant rien sur le WAF précédent, et un proxy sans tampon ne garantit pas que le framework applicatif consomme rapidement les données reçues.

Le refus connu a une forme publique

La discipline la plus importante du texte intervient lorsque l’intermédiaire connaît le champ. S’il décide de ne pas transférer le corps progressivement, il doit générer une erreur. Il ne peut pas accepter la demande, accumuler secrètement la totalité, puis livrer tardivement comme si rien ne s’était passé.

Cette exigence sépare trois situations. Un équipement ancien peut ignorer le champ et conserver son comportement. Un équipement compatible peut suivre la demande. Un équipement informé peut la refuser. Le standard ne transforme pas l’ignorance en conformité ; il empêche surtout le refus conscient de devenir une réussite trompeuse.

Le conflit permanent apparaît avec l’inspection intégrale. Un intermédiaire qui ne peut juger la sûreté d’un contenu qu’après avoir reçu tout le corps ne peut simultanément le publier vers l’aval. RFC 10036 recommande alors une réponse 501 Not Implemented assortie de l’erreur incremental_refused dans Proxy-Status.

Le registre IANA de Proxy-Status associe incremental_refused à 501 et précise que la réponse ne peut être produite que par un intermédiaire. Elle documente donc une incompatibilité du chemin, pas nécessairement un rejet du traitement métier par l’origine.

La saturation est une autre décision. Les flux longs consomment des connexions, des slots, de la mémoire et du temps d’ordonnancement. Un intermédiaire peut réserver une capacité plus faible aux requêtes incrémentales pour préserver le trafic ordinaire. Lorsque cette limite est atteinte, RFC 10036 recommande 429 Too Many Requests, dont la sémantique vient de RFC 6585, avec connection_limit_reached. Mélanger ce cas temporaire avec l’incompatibilité de sécurité détruirait l’information utile au repli.

Un petit tampon n’est pas une trahison

L’envoi immédiat de chaque fragment minuscule peut gaspiller du calcul, des réveils et des paquets. Il peut aussi offrir à un attaquant une manière peu coûteuse d’imposer beaucoup de travail. RFC 10036 autorise donc un tampon borné par une quantité d’octets ou une durée.

La limite essentielle est l’infini : les données doivent finir par partir lorsque l’un des seuils est atteint. Le compromis reste réel. Augmenter le lot peut améliorer l’efficacité tout en dégradant le délai utile. Deux implémentations peuvent toutes deux être raisonnablement incrémentales et produire des expériences très différentes.

Le premier octet ne suffit donc pas à certifier le service. Un intermédiaire peut libérer une première goutte, puis garder les suivantes pendant plusieurs secondes. Le client peut recevoir des fragments réguliers qui ne constituent encore aucun événement complet. Un message peut finalement réussir tout en ayant manqué chaque échéance interactive.

Il faut dater la fin des en-têtes, le premier octet de contenu, les progressions suivantes, le plus long silence entre octets, le premier objet que l’application peut réellement utiliser, les trailers et la fin. Ces horloges doivent être observées à plusieurs frontières. L’heure d’écriture de l’origine n’est pas l’heure d’émission de la passerelle, encore moins celle de consommation par le lecteur.

Proxy-Status raconte le chemin sans le certifier

RFC 9209 permet aux intermédiaires de décrire leur traitement. Les membres sont ordonnés depuis le proxy proche de l’origine jusqu’à celui proche de l’agent utilisateur. Des paramètres peuvent signaler une erreur, un prochain saut ou un statut reçu ; un problème tardif sur une réponse déjà en cours peut parfois être ajouté dans un trailer.

Ce témoignage est volontairement limité. Un intermédiaire décide s’il publie le champ et peut masquer des détails afin de ne pas révéler sa topologie. Les paramètres sont largement facultatifs. Surtout, RFC 9209 indique que le contenu n’est pas vérifié : un équipement peut déclarer une action qui n’a pas eu lieu.

La présence de incremental_refused constitue donc un indice précis d’une décision explicite. Son absence ne prouve rien. Un ancien proxy ne connaît pas l’erreur, une politique peut supprimer le champ et un trailer peut disparaître. La preuve naît du rapprochement entre champ reçu, résultat du parseur, règle appliquée, seuils du tampon, octets entrants, octets sortants et observation du client.

Le bon protocole reste une décision d’architecture

Avec ?1 dans les deux sens, RFC 10036 peut aider à former un canal d’octets bidirectionnel et à faire suivre une réponse avant l’achèvement de la requête. Le document ajoute immédiatement une réserve : pour un véritable protocole bidirectionnel, Extended CONNECT sous HTTP/2 et sous HTTP/3 correspondent généralement mieux à l’architecture HTTP.

Cette distinction protège contre le glissement du cas d’usage. Une représentation consommée progressivement, un fil d’événements et un protocole duplex n’ont pas les mêmes règles de durée de vie, de contrôle de flux ou de reprise. Maintenir artificiellement deux grands corps HTTP peut faciliter un premier déploiement, puis créer une dépendance difficile à retirer dans les SDK, les exceptions de middleboxes et les contrats clients.

La connaissance préalable ou une sonde par ressource peut établir qu’un parcours précis fonctionne aujourd’hui. Elle ne crée pas une capacité globale et permanente. Routage, règles d’inspection, versions et charge évoluent. Une sonde est un point de comparaison daté.

La recherche d’errata pour RFC 10036 ne renvoyait aucun résultat au 30 août 2026. Cette constatation décrit le registre à cette date ; elle ne préjuge pas d’un futur signalement.

Relier l’intention à l’octet utile

Le journal minimal doit retenir la ressource, le sens, l’identifiant de requête et de trace, la tentative, la version HTTP, les connexions et la route ; la valeur exacte du champ à chaque entrée et sortie ; le résultat d’analyse ; la version des politiques de support et de sécurité ; l’admission de capacité ; les seuils de temps et d’octets ; les instants de réception et d’émission ; le plus long intervalle ; le premier événement utile ; les trailers, l’achèvement, l’annulation, le reset, le statut et Proxy-Status.

Les essais doivent inclure des octets isolés, un flux lent, des rafales, la contre-pression, un corps qui ne finit jamais, une règle exigeant l’inspection complète, la limite de concurrence, l’annulation, la nouvelle tentative et le changement de route. Un banc rapide qui traverse un seul proxy ne prouve pas la propriété en production.

La primauté du code en exécution de Heng Lu place l’autorité dans cette séquence exécutée. Son modèle de spécification initiale minimale, décision future localisée et adoption volontaire éclaire la retenue du standard : un bit commun suffit à coordonner l’intention, tandis que sécurité, capacité et architecture restent locales. Sa distinction entre capacité technique et contrôle pratique explique enfin pourquoi l’expéditeur peut formuler une demande valide sans posséder les tampons indépendants qui suivront.

Le champ rend la question transportable. Seuls les systèmes en fonctionnement rendent la réponse vraie.