Chunked Transfer est un mécanisme du protocole HTTP par lequel le serveur transmet le corps de la réponse en fragments séparés (chunks) sans spécifier la taille totale des données à l'avance. Chaque chunk contient sa taille au format hexadécimal et des données de la longueur spécifiée, et se termine par un chunk final de taille zéro. Selon MDN Web Docs, 2025, Transfer-Encoding: chunked est activé automatiquement par le serveur lorsque la taille de la réponse est inconnue à l'avance — par exemple, lors de la génération de contenu à la volée ou de la transmission de données en streaming.
Points clés
Chunked Transfer est un mécanisme HTTP défini dans la spécification HTTP/1.1 (RFC 7230, section 4.1) qui permet au serveur d'envoyer le corps de la réponse par parties sans spécifier le Content-Length total. Au lieu de calculer la taille de la réponse avant l'envoi, le serveur commence la transmission immédiatement, en envoyant des fragments de données au fur et à mesure qu'ils sont prêts. Chaque fragment est accompagné de son propre en-tête de taille, permettant au client d'assembler la réponse à partir des morceaux.
Le mécanisme est activé par l'en-tête Transfer-Encoding: chunked. Lorsque le client voit cet en-tête dans la réponse, il sait que le corps sera transmis par chunks et doit lire la réponse en boucle : lire la taille du chunk, puis lire les données de la taille spécifiée, puis répéter. Le processus se termine lorsqu'un chunk de taille zéro est rencontré. Chunked Transfer est une partie obligatoire de HTTP/1.1, supportée par tous les serveurs web modernes et clients HTTP.
La principale raison d'utiliser chunked transfer est la génération dynamique de contenu. Lorsque le serveur génère une réponse basée sur une requête de base de données, une API externe ou un calcul long, il ne peut pas connaître la taille du résultat à l'avance. Au lieu de mettre en mémoire tampon la réponse entière (ce qui est risqué pour les gros volumes), le serveur active Transfer-Encoding: chunked et envoie les données au fur et à mesure qu'elles sont disponibles. Ceci est particulièrement important pour les serveurs à mémoire limitée et pour les réponses dont la taille peut être très grande — à partir de 100 Mo et plus.
En HTTP/2, le mécanisme chunked transfer en tant que tel n'existe pas car le protocole utilise le multiplexage de flux au niveau des trames. En HTTP/2, les données de toute taille sont transmises dans des trames DATA, et la taille du corps de la réponse n'a pas besoin d'être déclarée à l'avance — un flux peut être fermé à tout moment. Les serveurs modernes convertissent automatiquement les réponses chunked HTTP/1.1 en transmission par streaming équivalente lors du proxy vers un upstream HTTP/2. Chunked Transfer reste pertinent pour les connexions HTTP/1.1.
Lorsque le serveur décide d'utiliser Chunked Transfer, il ne calcule pas Content-Length mais envoie l'en-tête Transfer-Encoding: chunked. Le corps de la réponse est alors formé comme une séquence de chunks. Chaque chunk commence par une ligne contenant la taille du chunk au format hexadécimal (sans le préfixe 0x), suivie de CRLF ( ). Viennent ensuite les données du chunk de la taille spécifiée, se terminant par CRLF. Le dernier chunk a une taille de 0, après lequel des en-têtes trailer peuvent suivre.
La taille hexadécimale permet de transmettre des chunks de toute taille, de 1 octet à un volume théoriquement illimité. En pratique, la taille du chunk est choisie par le serveur : les valeurs typiques sont 4 Ko, 8 Ko ou 16 Ko. La taille optimale du chunk doit être un multiple de la taille du segment TCP (généralement 1460 octets pour Ethernet) pour minimiser la fragmentation au niveau transport. Nginx utilise des chunks de 4 Ko par défaut, Apache des chunks de 8 Ko.
Un client qui reçoit Transfer-Encoding: chunked doit lire la réponse chunk par chunk jusqu'au chunk nul de terminaison. Si le client ne supporte pas chunked transfer, le serveur ne peut pas utiliser ce mode. En pratique, tous les clients HTTP modernes — navigateurs, OkHttp, URLSession, curl — supportent complètement les réponses chunked. La lecture en streaming permet au client de commencer à traiter les données avant de recevoir la réponse complète, ce qui est critique pour les performances.
| Élément du chunk | Format | Exemple |
|---|---|---|
| Taille du chunk | HEX + CRLF | 1000 |
| Données du chunk | [taille octets] + CRLF | [4096 octets de données] |
| Chunk de terminaison | 0 | 0 |
| Trailer (optionnel) | En-têtes + CRLF | Expires: Wed, 21 Oct 2025 |
Chunked Transfer supporte les en-têtes trailer — des en-têtes HTTP supplémentaires qui sont transmis après le dernier chunk. Ceci est utile pour les métadonnées qui ne deviennent connues qu'après la fin de la génération de la réponse : par exemple, Content-MD5 ou X-Compression-Ratio. Les en-têtes trailer doivent être déclarés dans l'en-tête Trailer : Trailer: Content-MD5, X-Compression-Ratio. En pratique, les trailers sont rarement utilisés — la plupart des serveurs ne les incluent pas dans les réponses.
Une réponse chunked a une structure strictement définie que le client doit analyser correctement. Considérons un exemple complet d'une réponse HTTP avec Transfer-Encoding: chunked. Après les en-têtes et une ligne vide, le corps de la réponse commence. La structure du corps est une séquence de : taille_du_chunk données taille_du_chunk données ... jusqu'à 0 . Chaque taille est transmise en notation hexadécimale utilisant des caractères ASCII.
Exemple de réponse serveur avec Chunked Transfer :
HTTP/1.1 200 OK
Content-Type: text/plain
Transfer-Encoding: chunked
7
Hello
6
World!
0
Dans cet exemple, le serveur transmet la chaîne « Hello World! » en deux chunks. Le premier chunk fait 7 octets et contient « Hello », le second fait 6 octets et contient « World! ». Le client collecte les données des deux chunks et obtient la chaîne complète. Important : la taille du chunk inclut uniquement les données, pas les séparateurs CRLF des chunks eux-mêmes. Le chunk vide de terminaison (0 ) notifie au client que la transmission est terminée.
import java.net.HttpURLConnection
import java.io.BufferedReader
import java.io.InputStreamReader
fun readChunkedResponse() {
val url = java.net.URL("https://stream.example.com/data")
val connection = url.openConnection() as HttpURLConnection
val reader = BufferedReader(
InputStreamReader(connection.inputStream)
)
var line: String?
while (reader.readLine().also { line = it } != null) {
println("Chunk: $line")
}
reader.close()
}
OkHttp abstrait complètement le développeur des détails de Chunked Transfer. Lors de la réception d'une réponse avec Transfer-Encoding: chunked, OkHttp collecte automatiquement les chunks et fournit au développeur le corps complet de la réponse via response.body?.string(). Pour le traitement en streaming, response.body?.source() est utilisé, qui retourne un BufferedSource et permet de lire les données au fur et à mesure de leur arrivée. Le développeur n'a pas besoin d'analyser manuellement les tailles hex et CRLF — la bibliothèque le fait automatiquement.
Content-Length et Transfer-Encoding: chunked sont deux manières mutuellement exclusives de spécifier la taille du corps d'un message HTTP. Content-Length est un en-tête qui contient la taille exacte du corps en octets. Il est obligatoire pour les réponses dont la taille est connue à l'avance et pour les requêtes avec corps (POST, PUT). Content-Length permet au client d'allouer un tampon de la taille requise à l'avance et de vérifier que toutes les données ont été reçues.
Chunked Transfer est utilisé lorsque la taille du corps n'est pas connue à l'avance. Cela se produit dans trois scénarios principaux : la génération dynamique de contenu (par exemple, une requête base de données dont le résultat n'est pas encore disponible), la transmission en streaming de fichiers volumineux (pour éviter de mettre en mémoire tampon le fichier entier) et les Server-Sent Events (SSE) pour la transmission d'événements en temps réel. Le choix entre Content-Length et chunked est la responsabilité du serveur. Si le serveur connaît la taille avant le début de la transmission, il doit utiliser Content-Length comme mécanisme plus simple et plus prévisible.
La spécification HTTP/1.1 interdit l'utilisation simultanée de Content-Length et Transfer-Encoding: chunked. Si le serveur envoie les deux en-têtes, le client doit ignorer Content-Length et traiter la réponse comme chunked. La priorité de Transfer-Encoding sur Content-Length est établie dans la RFC 7230 pour les cas où un serveur proxy modifie le corps de la réponse et ne peut pas préserver le Content-Length original. Certains clients HTTP anciens gèrent cette situation incorrectement, mais les implémentations modernes suivent la spécification.
Il existe des scénarios où Content-Length ne peut fondamentalement pas être calculé à l'avance. Les rapports dynamiques générés à la demande avec filtrage et agrégation — le serveur ne connaît pas le volume de données avant la fin de la requête base de données. La vidéo en streaming transmise depuis une caméra en temps réel — la taille est infinie. Les SSE et le long polling pour les notifications — la réponse peut durer indéfiniment. Dans tous ces cas, Chunked Transfer est le seul mécanisme correct.
Chunked Transfer est à la base de nombreuses technologies de streaming sur le web. La plus connue est Server-Sent Events (SSE), où le serveur envoie des événements au client via une seule connexion HTTP avec Transfer-Encoding: chunked. SSE utilise un format texte spécial (data: message ), mais la couche de transport est un chunked transfer ordinaire. Le navigateur reçoit les événements au fur et à mesure que le serveur les envoie, sans attendre la fin de la réponse.
Le streaming audio et vidéo repose également sur Chunked Transfer. Les serveurs multimédia tels que Nginx RTMP et Wowza Streaming Engine envoient des données multimédia par chunks via HTTP. Le lecteur côté client commence la lecture dès la réception du premier chunk, sans attendre le chargement complet du fichier. Cela réduit le temps jusqu'à la première image de dizaines de secondes à 1-2 secondes. YouTube et Netflix utilisent exactement cette approche pour leurs flux HTTP.
Dans le développement mobile, Chunked Transfer est utilisé pour transférer de gros volumes de données sans charger la réponse entière en mémoire. Lors du chargement d'images via Coil ou Glide sur Android, les bibliothèques lisent les données en streaming chunk par chunk et décodent progressivement l'image. Cela permet d'afficher de grandes images (10+ Mo) sans OutOfMemoryError. OkHttp supporte la lecture en streaming via response.body?.byteStream(), qui retourne un InputStream lisant les données chunk par chunk.
gRPC utilise HTTP/2, où le streaming est intégré au niveau du protocole et ne nécessite pas de mécanisme chunked séparé. Les serveurs GraphQL fonctionnant sur HTTP/1.1 peuvent utiliser Chunked Transfer pour diffuser en streaming les résultats des abonnements. Apollo Server et Hasura envoient des réponses chunked pour les abonnements GraphQL, transmettant les événements au fur et à mesure de leur occurrence. Le client reçoit des mises à jour en temps réel sans avoir besoin de polling.
Chunked Transfer offre des avantages importants pour les applications web. Envoi immédiat des données — le serveur ne met pas en tampon la réponse avant l'envoi, réduisant la latence jusqu'au premier octet. Traitement en streaming — le client peut commencer à traiter les données à leur arrivée sans attendre le téléchargement complet. Pas de limitations mémoire — le serveur ne stocke pas la réponse complète en mémoire, ce qui est critique pour les gros volumes de données. Capacité à transmettre des flux infinis — SSE, vidéo en direct, surveillance.
Cependant, Chunked Transfer a des limites. Surcharge pour chaque chunk de 6 à 12 octets pour la taille + CRLF, ce qui pour de nombreux petits chunks (par exemple, 100 octets chacun) peut augmenter la taille de la réponse de 10 à 15 %. Incapacité de spécifier la taille exacte — le client ne peut pas allouer un tampon à l'avance ou afficher une barre de progression. Problèmes avec les serveurs proxy — certains proxies anciens ne supportent pas chunked transfer et ne peuvent pas mettre en cache ces réponses. Absence de support pour la reprise des téléchargements — les requêtes Range ne peuvent pas être faites pour des réponses chunked partiellement reçues.
Selon HTTP Archive, 2025, environ 35 % de toutes les réponses HTTP utilisent Transfer-Encoding: chunked. Parmi elles, les pages dynamiques prédominent (60 %), suivies des réponses API (25 %) et des flux multimédia (15 %). Les fichiers statiques utilisent presque toujours Content-Length car leur taille est connue à l'avance. La part des réponses chunked diminue progressivement avec l'adoption de HTTP/2, où le streaming est implémenté au niveau des trames sans nécessité d'un en-tête Transfer-Encoding supplémentaire.
Dans le développement mobile, utilisez Chunked Transfer pour télécharger des fichiers volumineux (images, vidéo) et pour les requêtes API retournant de grands tableaux de données. OkHttp supporte complètement chunked transfer sans configuration supplémentaire. Pour les téléversements vers le serveur, Chunked Transfer n'est pas utilisé — HTTP/1.1 n'a pas de Transfer-Encoding pour les téléversements. Sur iOS, URLSession supporte à la fois l'envoi et la réception de données chunked sans configuration spéciale. L'analyse JSON en streaming (via Jackson Streaming API ou Moshi) permet de traiter de grands tableaux JSON au fur et à mesure de leur arrivée dans un flux chunked.
Questions fréquentes
Le serveur active Chunked Transfer automatiquement lorsque la taille de la réponse est inconnue. Nginx ajoute Transfer-Encoding: chunked si Content-Length n'est pas défini. Dans Spring Boot, StreamingResponseBody et SseEmitter utilisent automatiquement chunked transfer. Dans Node.js Express, la réponse devient chunked si res.write() et res.end() sont appelés sans Content-Length.
Non, la spécification HTTP/1.1 interdit l'utilisation simultanée de Content-Length et Transfer-Encoding: chunked. Si le serveur envoie les deux en-têtes, le client doit ignorer Content-Length et traiter la réponse comme chunked. Cette règle est établie dans la RFC 7230 pour la compatibilité avec les serveurs proxy qui peuvent modifier le corps de la réponse.
La taille optimale du chunk dépend du scénario. Pour les pages web ordinaires — 4-8 Ko. Pour le streaming vidéo — 16-64 Ko. Pour SSE — des chunks minimaux de 1-2 Ko pour réduire la latence. La taille du chunk doit être un multiple de la taille du segment TCP (1460 octets pour Ethernet) pour minimiser la fragmentation au niveau transport.
Les serveurs proxy modernes (Nginx, HAProxy, Envoy) supportent Chunked Transfer. Le proxy peut transmettre les chunks sans mise en tampon (streaming) ou mettre en tampon la réponse entière et la renvoyer avec Content-Length. Les proxies anciens peuvent mettre en tampon la réponse chunked jusqu'à la fin, augmentant la latence. HTTP/2 résout ce problème au niveau du protocole.
C'est la même chose. Chunked Transfer est le nom complet du mécanisme de la spécification HTTP/1.1. HTTP chunked encoding est identique, parfois utilisé dans la documentation des bibliothèques. Transfer-Encoding: chunked est l'en-tête qui active ce mode. Les trois termes décrivent le même mécanisme de transmission de données par parties.
Résumé
Nous développerons une application mobile clé en main
IT Sectr crée des applications iOS et Android pour les startups et les entreprises depuis 2017. Nous vous conseillerons et vous proposerons la meilleure solution.
Lisez aussi