Encodage de transfert fragmenté - Chunked transfer encoding

L'encodage de transfert en bloc est un mécanisme de transfert de données en continu disponible dans la version 1.1 du protocole HTTP ( Hypertext Transfer Protocol ). Dans le codage de transfert par morceaux, le flux de données est divisé en une série de "morceaux" qui ne se chevauchent pas. Les morceaux sont envoyés et reçus indépendamment les uns des autres. Aucune connaissance du flux de données en dehors du bloc en cours de traitement n'est nécessaire à la fois pour l'expéditeur et le destinataire à un moment donné.

Chaque morceau est précédé de sa taille en octets. La transmission se termine lorsqu'un morceau de longueur nulle est reçu. Le mot-clé chunked dans l'en - tête Transfer-Encoding est utilisé pour indiquer le transfert chunked.

Une première forme de codage de transfert fragmenté a été proposée en 1994. Le codage de transfert fragmenté n'est pas pris en charge dans HTTP/2 , qui fournit ses propres mécanismes pour le streaming de données.

Raisonnement

L'introduction de l'encodage par blocs a apporté divers avantages :

  • L'encodage de transfert en bloc permet à un serveur de maintenir une connexion HTTP persistante pour le contenu généré dynamiquement. Dans ce cas, l'en-tête HTTP Content-Length ne peut pas être utilisé pour délimiter le contenu et la prochaine requête/réponse HTTP, car la taille du contenu n'est pas encore connue. L'encodage par blocs présente l'avantage de ne pas avoir besoin de générer le contenu complet avant d'écrire l'en-tête, car il permet la diffusion en continu du contenu sous forme de blocs et signale explicitement la fin du contenu, rendant la connexion disponible pour la prochaine requête/réponse HTTP.
  • L'encodage fragmenté permet à l'expéditeur d'envoyer des champs d'en-tête supplémentaires après le corps du message. Ceci est important dans les cas où les valeurs d'un champ ne peuvent pas être connues tant que le contenu n'a pas été produit, comme lorsque le contenu du message doit être signé numériquement. Sans codage en bloc, l'expéditeur devrait mettre le contenu en mémoire tampon jusqu'à ce qu'il soit terminé afin de calculer une valeur de champ et de l'envoyer avant le contenu.

Applicabilité

Pour la version 1.1 du protocole HTTP, le mécanisme de transfert fragmenté est considéré comme toujours et de toute façon acceptable, même s'il n'est pas répertorié dans le champ d'en-tête de demande TE (encodage de transfert), et lorsqu'il est utilisé avec d'autres mécanismes de transfert, doit toujours être appliqué en dernier à les données transférées et jamais plus d'une fois. Cette méthode de codage de transfert permet également d'envoyer des champs d'en-tête d'entité supplémentaires après le dernier bloc si le client a spécifié le paramètre "trailers" comme argument du champ TE. Le serveur d'origine de la réponse peut également décider d'envoyer des remorques d'entité supplémentaires même si le client n'a pas spécifié l'option « remorques » dans le champ de demande TE, mais seulement si les métadonnées sont facultatives (c'est-à-dire que le client peut utiliser l'entité reçue sans elles ). Chaque fois que les remorques sont utilisées, le serveur doit lister leurs noms dans le champ d'en-tête Trailer ; trois types de champs d'en-tête sont spécifiquement interdits d'apparaître en tant que champ de fin : Transfer-Encoding , Content-Length et Trailer .

Format

Si un champ Transfer-Encoding avec une valeur de " chunked " est spécifié dans un message HTTP (soit une requête envoyée par un client, soit la réponse du serveur), le corps du message consiste en un nombre non spécifié de morceaux, un chunk, trailer, et une séquence CRLF finale (c'est- à- dire un retour chariot suivi d'un saut de ligne ).

Chaque bloc commence par le nombre d' octets des données qu'il contient, exprimé sous forme de nombre hexadécimal en ASCII, suivi de paramètres facultatifs ( extension de bloc ) et d'une séquence CRLF de fin, suivi des données de bloc. Le morceau est terminé par CRLF.

Si des extensions de bloc sont fournies, la taille du bloc est terminée par un point-virgule et suivie des paramètres, chacun étant également délimité par des points-virgules. Chaque paramètre est codé sous la forme d'un nom d'extension suivi d'un signe égal et d'une valeur facultatifs. Ces paramètres peuvent être utilisés pour un résumé de message ou une signature numérique en cours , ou pour indiquer une estimation de la progression du transfert, par exemple.

Le morceau de terminaison est un morceau régulier, à l'exception du fait que sa longueur est de zéro. Il est suivi de la fin, qui consiste en une séquence (éventuellement vide) de champs d'en-tête d'entité. Normalement, ces champs d'en-tête seraient envoyés dans l'en-tête du message ; cependant, il peut être plus efficace de les déterminer après avoir traité l'intégralité de l'entité de message. Dans ce cas, il est utile d'envoyer ces en-têtes dans la remorque.

Les champs d'en-tête qui régulent l'utilisation des remorques sont TE (utilisés dans les demandes) et Trailers (utilisés dans les réponses).

Utilisation avec compression

Les serveurs HTTP utilisent souvent la compression pour optimiser la transmission, par exemple avec Content-Encoding : gzip ou Content-Encoding : deflate . Si à la fois la compression et l'encodage en bloc sont activés, le flux de contenu est d'abord compressé, puis fragmenté ; ainsi, l'encodage du morceau lui-même n'est pas compressé et les données de chaque morceau ne sont pas compressées individuellement. Le point de terminaison distant décode ensuite le flux en concaténant les morceaux et en décompressant le résultat.

Exemple

Données codées

Dans l'exemple suivant, trois morceaux de longueur 4, 6 et 14 (hexadécimal "E") sont affichés. La taille du bloc est transférée sous forme de nombre hexadécimal suivi de \r\n comme séparateur de ligne, suivi d'un bloc de données de la taille donnée.

4\r\n        (bytes to send)
Wiki\r\n     (data)
6\r\n        (bytes to send)
pedia \r\n   (data)
E\r\n        (bytes to send)
in \r\n
\r\n
chunks.\r\n  (data)
0\r\n        (final byte - 0)
\r\n         (end message)

Remarque : la taille du bloc indique la taille des données du bloc et exclut le CRLF de fin ("\r\n"). Dans cet exemple particulier, le CRLF suivant "in" est compté comme deux octets vers la taille de bloc de 0xE (14). Le CRLF dans sa propre ligne est également compté comme deux octets vers la taille du morceau. Le caractère point à la fin des « morceaux » est le 14e caractère, c'est donc le dernier caractère de données de ce morceau. Le CRLF suivant la période est le CRLF de fin, il n'est donc pas compté dans la taille de bloc de 0xE (14).

Données décodées

Wikipedia in

chunks.

Voir également

Les références