3. Capsules
Un mécanisme pour étendre HTTP consiste à introduire de nouveaux jetons de mise à niveau HTTP (HTTP upgrade tokens) ; voir la section 16.7 de [HTTP]. Dans HTTP/1.x, ces jetons sont utilisés via le mécanisme Upgrade ; voir la section 7.8 de [HTTP]. Dans HTTP/2 et HTTP/3, ces jetons sont utilisés via le mécanisme Extended CONNECT ; voir [EXT-CONNECT2] et [EXT-CONNECT3].
Cette spécification introduit le protocole Capsule. Le protocole Capsule est une séquence de tuples type-longueur-valeur que les définitions de nouveaux jetons de mise à niveau HTTP peuvent choisir d'utiliser. Il permet aux points de terminaison de communiquer de manière fiable des informations liées aux requêtes de bout en bout sur les flux de requêtes HTTP, même en présence d'intermédiaires HTTP. Le protocole Capsule peut être utilisé pour échanger des datagrammes HTTP, ce qui est nécessaire lorsque HTTP s'exécute sur un transport qui ne prend pas en charge la trame QUIC DATAGRAM. Le protocole Capsule peut également être utilisé pour communiquer des messages de contrôle fiables et bidirectionnels associés à un protocole basé sur des datagrammes, même lorsque les datagrammes HTTP/3 sont utilisés.
3.1. Flux de données HTTP (HTTP Data Streams)
Cette spécification définit le « flux de données » (data stream) d'une requête HTTP comme le flux bidirectionnel d'octets qui suit la section d'en-tête du message de requête et le message de réponse final qui est soit réussi (c'est-à-dire 2xx) soit mis à niveau (c'est-à-dire 101).
Dans HTTP/1.x, le flux de données se compose de tous les octets de la connexion qui suivent la ligne vide qui conclut soit la section d'en-tête de la requête, soit la section d'en-tête de la réponse finale. Par conséquent, seule la dernière requête HTTP sur une connexion HTTP/1.x peut démarrer le protocole Capsule.
Dans HTTP/2 et HTTP/3, le flux de données d'une requête HTTP donnée se compose de tous les octets envoyés dans les trames DATA avec l'ID de flux correspondant.
Le concept de flux de données est particulièrement pertinent pour des méthodes telles que CONNECT, où il n'y a pas de contenu de message HTTP après les en-têtes.
Les flux de données peuvent être priorisés en utilisant tous les moyens adaptés à la priorisation de flux ou de requêtes. Par exemple, voir la section 11 de [PRIORITY].
Les flux de données sont soumis aux mécanismes de contrôle de flux des couches sous-jacentes ; les exemples incluent le contrôle de flux de flux HTTP/2, le contrôle de flux de connexion HTTP/2 et le contrôle de flux TCP.
3.2. Le protocole Capsule (The Capsule Protocol)
Les définitions de nouveaux jetons de mise à niveau HTTP peuvent indiquer que le flux de données de la requête associée utilise le protocole Capsule. Si elles le font, le contenu du flux de données de la requête associée utilise le format suivant :
Capsule Protocol {
Capsule (..) ...,
}
Figure 2 : Format de flux du protocole Capsule
Capsule {
Capsule Type (i),
Capsule Length (i),
Capsule Value (..),
}
Figure 3 : Format de capsule
Capsule Type : Un entier de longueur variable indiquant le type de la capsule. Un registre IANA est utilisé pour gérer l'attribution des types de capsules ; voir la section 5.4.
Capsule Length : La longueur, en octets, du champ Capsule Value qui suit ce champ, encodée comme un entier de longueur variable. Notez que ce champ peut avoir une valeur de zéro.
Capsule Value : La charge utile de cette capsule. Sa sémantique est déterminée par la valeur du champ Capsule Type.
Un intermédiaire peut identifier l'utilisation du protocole Capsule soit par la présence du champ d'en-tête Capsule-Protocol (section 3.4), soit en comprenant le jeton de mise à niveau HTTP choisi.
Étant donné que de nouveaux protocoles ou extensions peuvent définir de nouveaux types de capsules, les intermédiaires qui souhaitent permettre l'extensibilité future devraient (SHOULD) transférer les capsules sans modification, sauf si la définition du type de capsule utilisé spécifie un traitement intermédiaire supplémentaire. Un tel type de capsule est la capsule DATAGRAM ; voir la section 3.5. En particulier, les intermédiaires devraient (SHOULD) transférer les capsules avec un type de capsule inconnu sans modification.
Les points de terminaison qui reçoivent une capsule avec un type de capsule inconnu doivent (MUST) abandonner silencieusement cette capsule et la sauter pour analyser la capsule suivante.
En vertu de la définition du flux de données :
-
Le protocole Capsule n'est pas utilisé à moins que la réponse n'inclue un code d'état 2xx (Succès) ou 101 (Changement de protocoles).
-
Lorsque le protocole Capsule est utilisé, la requête HTTP et la réponse associées ne transportent pas de contenu HTTP. Une extension future peut (MAY) définir un nouveau type de capsule pour transporter du contenu HTTP.
Le protocole Capsule s'applique uniquement aux définitions de nouveaux jetons de mise à niveau HTTP ; ainsi, dans HTTP/2 et HTTP/3, il ne peut être utilisé qu'avec la méthode CONNECT. Par conséquent, une fois que les deux points de terminaison acceptent d'utiliser le protocole Capsule, les exigences d'utilisation de trame du flux changent comme spécifié dans la section 8.5 de [HTTP/2] et la section 4.4 de [HTTP/3].
Le protocole Capsule ne doit pas (MUST NOT) être utilisé avec des messages qui contiennent les champs d'en-tête Content-Length, Content-Type ou Transfer-Encoding. De plus, les codes d'état HTTP 204 (No Content), 205 (Reset Content) et 206 (Partial Content) ne doivent pas (MUST NOT) être envoyés sur les réponses qui utilisent le protocole Capsule. Un récepteur qui observe une violation de ces exigences doit (MUST) traiter le message HTTP comme mal formé.
Lors du traitement des capsules, un récepteur peut être tenté d'accumuler toute la longueur du champ Capsule Value dans le flux de données avant de le traiter. Cette approche devrait (SHOULD) être évitée car elle peut consommer le contrôle de flux dans les couches sous-jacentes, ce qui peut conduire à des blocages si les données de la capsule épuisent la fenêtre de contrôle de flux.
3.3. Gestion des erreurs (Error Handling)
Lorsqu'un récepteur rencontre une erreur lors du traitement du protocole Capsule, le récepteur doit (MUST) le traiter comme s'il avait reçu un message HTTP mal formé ou incomplet. Pour HTTP/3, la gestion des messages mal formés est décrite dans la section 4.1.2 de [HTTP/3]. Pour HTTP/2, la gestion des messages mal formés est décrite dans la section 8.1.1 de [HTTP/2]. Pour HTTP/1.x, la gestion des messages incomplets est décrite dans la section 8 de [HTTP/1.1].
La charge utile de chaque capsule doit (MUST) contenir exactement les champs identifiés dans sa description. Une charge utile de capsule qui contient des octets supplémentaires après les champs identifiés ou une charge utile de capsule qui se termine avant la fin des champs identifiés doit (MUST) être traitée comme s'il s'agissait d'un message mal formé ou incomplet. En particulier, les encodages de longueur redondants doivent (MUST) être vérifiés pour être auto-cohérents.
Si le côté réception d'un flux transportant des capsules est terminé proprement (par exemple, dans HTTP/3, cela est défini comme la réception d'une trame QUIC STREAM avec le bit FIN défini) et que la dernière capsule sur le flux a été tronquée, cela doit (MUST) être traité comme s'il s'agissait d'un message mal formé ou incomplet.
3.4. Le champ d'en-tête Capsule-Protocol (The Capsule-Protocol Header Field)
Le champ d'en-tête « Capsule-Protocol » est un champ structuré d'élément ; voir la section 3.3 de [STRUCTURED-FIELDS]. Sa valeur doit (MUST) être un booléen ; tout autre type de valeur doit (MUST) être traité comme si le champ n'était pas présent par les destinataires (par exemple, si ce champ est inclus plusieurs fois, son type deviendra une liste et le champ sera ignoré). Ce document ne définit aucun paramètre pour la valeur du champ d'en-tête Capsule-Protocol, mais les documents futurs pourraient définir des paramètres. Les récepteurs doivent (MUST) ignorer les paramètres inconnus.
Les points de terminaison indiquent que le protocole Capsule est utilisé sur un flux de données en envoyant un champ d'en-tête Capsule-Protocol avec une valeur vraie. Un champ d'en-tête Capsule-Protocol avec une valeur fausse a la même sémantique que lorsque l'en-tête n'est pas présent.
Les intermédiaires peuvent (MAY) utiliser ce champ d'en-tête pour permettre le traitement des datagrammes HTTP pour des jetons de mise à niveau HTTP inconnus. Notez que cela n'est possible que pour HTTP Upgrade ou Extended CONNECT.
Le champ d'en-tête Capsule-Protocol ne doit pas (MUST NOT) être utilisé sur les réponses HTTP avec un code d'état à la fois différent de 101 (Changement de protocoles) et en dehors de la plage 2xx (Succès).
Lors de l'utilisation du protocole Capsule, les points de terminaison HTTP devraient (SHOULD) envoyer le champ d'en-tête Capsule-Protocol pour simplifier le traitement intermédiaire. Les définitions de nouveaux jetons de mise à niveau HTTP qui utilisent le protocole Capsule peuvent (MAY) modifier cette recommandation.
3.5. La capsule DATAGRAM (The DATAGRAM Capsule)
Ce document définit le type de capsule DATAGRAM (0x00). Cette capsule permet d'envoyer des datagrammes HTTP sur un flux en utilisant le protocole Capsule. Ceci est particulièrement utile lorsque HTTP s'exécute sur un transport qui ne prend pas en charge la trame QUIC DATAGRAM.
Datagram Capsule {
Type (i) = 0x00,
Length (i),
HTTP Datagram Payload (..),
}
Figure 4 : Format de capsule DATAGRAM
HTTP Datagram Payload : La charge utile du datagramme, dont la sémantique est définie par l'extension qui utilise les datagrammes HTTP. Notez que ce champ peut être vide.
Les datagrammes HTTP envoyés à l'aide de la capsule DATAGRAM ont la même sémantique que ceux envoyés dans des trames QUIC DATAGRAM. En particulier, les restrictions sur le moment où il est autorisé d'envoyer un datagramme HTTP et comment les traiter (de la section 2.1) s'appliquent également aux datagrammes HTTP envoyés et reçus à l'aide de la capsule DATAGRAM.
Un intermédiaire peut ré-encoder les datagrammes HTTP lorsqu'il les transmet. En d'autres termes, un intermédiaire peut (MAY) envoyer une capsule DATAGRAM pour transférer un datagramme HTTP qui a été reçu dans une trame QUIC DATAGRAM et vice versa. Les intermédiaires ne doivent pas (MUST NOT) effectuer ce ré-encodage à moins qu'ils n'aient identifié l'utilisation du protocole Capsule sur le flux de requête correspondant ; voir la section 3.2.
Notez que bien que les capsules DATAGRAM, qui sont envoyées sur un flux, soient livrées de manière fiable dans l'ordre, les intermédiaires peuvent ré-encoder les capsules DATAGRAM en trames QUIC DATAGRAM lors du transfert de messages, ce qui pourrait entraîner une perte ou un réordonnancement.
Si un intermédiaire reçoit un datagramme HTTP dans une trame QUIC DATAGRAM et le transmet sur une connexion qui prend en charge les trames QUIC DATAGRAM, l'intermédiaire ne devrait pas (SHOULD NOT) convertir ce datagramme HTTP en capsule DATAGRAM. Si le datagramme HTTP est trop grand pour tenir dans une trame DATAGRAM (par exemple, parce que le MTU de chemin (PMTU) de cette connexion QUIC est trop bas ou si la taille maximale de charge utile UDP annoncée sur cette connexion est trop basse), l'intermédiaire devrait (SHOULD) abandonner le datagramme HTTP au lieu de le convertir en capsule DATAGRAM. Cela préserve la caractéristique de non-fiabilité de bout en bout sur laquelle des méthodes telles que la découverte PMTU de couche de paquetisation de datagrammes (DPLPMTUD) dépendent [DPLPMTUD]. Un intermédiaire qui convertit les trames QUIC DATAGRAM en capsules DATAGRAM permet aux datagrammes HTTP d'être arbitrairement grands sans subir de perte. Cela peut fausser les vraies propriétés du chemin, en défaisant les méthodes telles que DPLPMTUD.
Bien que les capsules DATAGRAM puissent théoriquement transporter une charge utile de longueur 2^62-1, la plupart des extensions HTTP qui utilisent des datagrammes HTTP auront leurs propres limites sur les tailles de charge utile de datagramme pratiques. Les implémentations devraient (SHOULD) prendre ces limites en compte lors de l'analyse des capsules DATAGRAM. Si une capsule DATAGRAM entrante a une longueur connue pour être si grande qu'elle n'est pas utilisable, l'implémentation devrait (SHOULD) jeter la capsule sans mettre en mémoire tampon son contenu en mémoire.
Étant donné que les trames QUIC DATAGRAM doivent tenir dans un paquet QUIC, les implémentations qui ré-encodent les capsules DATAGRAM en trames QUIC DATAGRAM pourraient être tentées d'accumuler toute la capsule dans le flux avant de la ré-encoder. Cela devrait (SHOULD) être évité, car cela peut causer des problèmes de contrôle de flux ; voir la section 3.2.
Notez qu'il est possible pour une extension HTTP d'utiliser des datagrammes HTTP sans utiliser le protocole Capsule. Par exemple, si une extension HTTP qui utilise des datagrammes HTTP n'est définie que sur des transports qui prennent en charge les trames QUIC DATAGRAM, elle pourrait ne pas avoir besoin d'un encodage de flux. De plus, les extensions HTTP peuvent utiliser des datagrammes HTTP avec leur propre protocole de flux de données. Cependant, les nouvelles extensions HTTP qui souhaitent utiliser des datagrammes HTTP devraient (SHOULD) utiliser le protocole Capsule, car ne pas le faire rendra plus difficile pour l'extension HTTP de prendre en charge les versions de HTTP autres que HTTP/3 et empêchera l'interopérabilité avec les intermédiaires qui ne prennent en charge que le protocole Capsule.