Chunked Transfer — то је механизам HTTP протокола при којем сервер преноси тело одговора у одвојеним фрагментима (чанковима), без навођења унапред укупне величине података. Сваки чанк садржи своју величину у хексадецималном формату и податке наведене дужине, а завршава се финалним чанком нулте величине. Према MDN Web Docs, 2025, Transfer-Encoding: chunked се укључује аутоматски од стране сервера када величина одговора није унапред позната — на пример, при генерисању садржаја у лету или streaming преносу података.
Главно
Chunked Transfer је HTTP механизам дефинисан у спецификацији HTTP/1.1 (RFC 7230, одељак 4.1) који омогућава серверу да шаље тело одговора у деловима без навођења укупног Content-Length. Уместо да израчуна величину одговора пре слања, сервер одмах почиње пренос, шаљући податке у фрагментима како су спремни. Сваки фрагмент је праћен сопственим заглављем величине, што омогућава клијенту да састави одговор из делова.
Механизам се укључује заглављем Transfer-Encoding: chunked. Када клијент види ово заглавље у одговору, зна да ће се тело преносити у чанковима и мора да чита одговор у петљи: прочита величину чанка, затим податке наведене величине, затим понови. Процес се завршава када се наиђе на чанк нулте величине. Chunked Transfer је обавезан део HTTP/1.1, подржан од свих модерних веб сервера и HTTP клијената.
Главни разлог за коришћење chunked transfer је динамичко генерисање садржаја. Када сервер генерише одговор на основу упита бази података, спољног API-ја или дуготрајног израчунавања, не може унапред знати величину резултата. Уместо да баферује цео одговор у меморији (што је ризично за велике количине), сервер укључује Transfer-Encoding: chunked и шаље податке како су спремни. Ово је посебно важно за сервере са ограниченом меморијом и за одговоре чија величина може бити веома велика — од 100 MB и више.
У HTTP/2 механизам chunked transfer као такав не постоји, јер протокол користи мултиплексирање токова на нивоу оквира. У HTTP/2 подаци било које величине се преносе у DATA оквирима, а величина тела одговора не мора да се унапред декларише — ток се може затворити у било ком тренутку. Модерни сервери аутоматски конвертују chunked одговоре HTTP/1.1 у еквивалентни streaming пренос при проксирању на HTTP/2 upstream. Chunked Transfer остаје актуелан за HTTP/1.1 конекције.
Када сервер одлучи да користи Chunked Transfer, не израчунава Content-Length, већ шаље заглавље Transfer-Encoding: chunked. Затим се тело одговора формира као низ чанкова. Сваки чанк почиње редом који садржи величину чанка у хексадецималном формату (без префикса 0x), након чега следи CRLF ( ). Затим долазе подаци чанка наведене величине, завршени CRLF. Последњи чанк има величину 0, након чега могу уследити trailer заглавља.
Хексадецимална величина омогућава пренос чанкова било које величине — од 1 бајта до теоријски неограниченог обима. У пракси величину чанка бира сервер: типичне вредности су 4 KB, 8 KB или 16 KB. Оптимална величина чанка је умножак величине TCP сегмента (обично 1460 бајтова за Ethernet) како би се минимизирала фрагментација на транспортном нивоу. Nginx подразумевано користи чанкове од 4 KB, Apache — од 8 KB.
Клијент који је примио Transfer-Encoding: chunked дужан је да чита одговор чанк по чанк до завршног нултог чанка. Ако клијент не подржава chunked transfer, сервер не може користити овај режим. У пракси сви модерни HTTP клијенти — прегледачи, OkHttp, URLSession, curl — у потпуности подржавају chunked одговоре. Streaming читање омогућава клијенту да почне обраду података пре него што прими комплетан одговор, што је критично за перформансе.
| Елемент чанка | Формат | Пример |
|---|---|---|
| Величина чанка | HEX + CRLF | 1000 |
| Подаци чанка | [величина бајтова] + CRLF | [4096 бајтова података] |
| Завршни чанк | 0 | 0 |
| Trailer (опционално) | Заглавља + CRLF | Expires: Wed, 21 Oct 2025 |
Chunked Transfer подржава trailer заглавља — додатна HTTP заглавља која се преносе након последњег чанка. Ово је корисно за метаподатке који постају познати тек након завршетка генерисања одговора: на пример, Content-MD5 или X-Compression-Ratio. Trailer заглавља морају бити декларисана у заглављу Trailer: Content-MD5, X-Compression-Ratio. У пракси trailer се ретко користе — већина сервера их не укључује у одговоре.
Chunked одговор има строго дефинисану структуру коју клијент мора правилно да рашчлани. Размотримо комплетан пример HTTP одговора са Transfer-Encoding: chunked. Након заглавља и празног реда почиње тело одговора. Структура тела представља низ: величина_чанка подаци величина_чанка подаци ... до 0 . Свака величина се преноси у хексадецималном бројевном систему ASCII знацима.
Пример одговора сервера са Chunked Transfer:
HTTP/1.1 200 OK
Content-Type: text/plain
Transfer-Encoding: chunked
7
Hello
6
World!
0
У овом примеру сервер преноси стринг „Hello World!” у два чанка. Први чанк величине 7 бајтова садржи „Hello ”, други — 6 бајтова „World!”. Клијент сакупља податке из оба чанка и добија комплетан стринг. Важно: величина чанка укључује само податке, не укључујући CRLF раздвајаче самих чанкова. Завршни празан чанк (0 ) обавештава клијента о крају преноса.
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 у потпуности апстрахује програмера од детаља Chunked Transfer-а. При пријему одговора са Transfer-Encoding: chunked, OkHttp аутоматски сакупља чанкове и пружа програмеру комплетно тело одговора кроз response.body?.string(). За streaming обраду користи се response.body?.source() који враћа BufferedSource и омогућава читање података како пристижу. Програмер не мора ручно да рашчлањује hex величине и CRLF — библиотека то ради аутоматски.
Content-Length и Transfer-Encoding: chunked су два међусобно искључива начина за одређивање величине тела HTTP поруке. Content-Length је заглавље које садржи тачну величину тела у бајтовима. Обавезно је за одговоре чија је величина позната унапред и за захтеве са телом (POST, PUT). Content-Length омогућава клијенту да унапред издвоји бафер одговарајуће величине и провери да ли су сви подаци примљени.
Chunked Transfer се користи када величина тела није унапред позната. Ово се дешава у три главна сценарија: динамичко генерисање садржаја (на пример, упит бази података чији резултат још није примљен), streaming пренос великих фајлова (како не би баферовао цео фајл у меморији) и Server-Sent Events (SSE) за пренос догађаја у реалном времену. Избор између Content-Length и chunked је одговорност сервера. Ако сервер зна величину пре почетка преноса, треба да користи Content-Length као једноставнији и предвидљивији механизам.
Спецификација HTTP/1.1 забрањује истовремену употребу Content-Length и Transfer-Encoding: chunked. Ако сервер шаље оба заглавља, клијент мора да игнорише Content-Length и обрађује одговор као chunked. Приоритет Transfer-Encoding над Content-Length утврђен је у RFC 7230 за случајеве када прокси сервер мења тело одговора и не може да сачува оригинални Content-Length. Неки стари HTTP клијенти неисправно обрађују ову ситуацију, али модерне имплементације прате спецификацију.
Постоје сценарији у којима Content-Length принципијелно не може бити израчунат унапред. Динамички извештаји који се генеришу на захтев корисника са филтрирањем и агрегацијом — сервер не зна обим података до завршетка упита бази података. Streaming видео преношен са камере у реалном времену — величина је бесконачна. SSE и long polling за обавештења — одговор може трајати неодређено дуго. У свим овим случајевима Chunked Transfer је једини исправан механизам.
Chunked Transfer лежи у основи многих streaming технологија на вебу. Најпознатија је Server-Sent Events (SSE), где сервер шаље догађаје клијенту преко једне HTTP конекције са Transfer-Encoding: chunked. SSE користи посебан текст формат (data: порука ), али транспортни ниво је обичан chunked transfer. Прегледач прима догађаје како их сервер шаље, не чекајући завршетак одговора.
Streaming аудио и видео такође се ослања на Chunked Transfer. Медија сервери, као што су Nginx RTMP и Wowza Streaming Engine, шаљу медија податке у чанковима преко HTTP-а. Плејер на страни клијента почиње репродукцију када је примљен први чанк, не чекајући потпуно учитавање фајла. Ово смањује време до почетка репродукције (Time to First Frame) са десетина секунди на 1-2 секунде. YouTube и Netflix користе управо овај приступ за своје HTTP токове.
У развоју мобилних апликација, Chunked Transfer се користи за пренос великих количина података без учитавања целог одговора у меморију. При учитавању слика преко Coil или Glide на Android-у, библиотеке читају streaming податке у чанковима и постепено декодирају слику. Ово омогућава приказ великих слика (10+ MB) без OutOfMemoryError. OkHttp подржава streaming читање кроз response.body?.byteStream() који враћа InputStream и чита податке чанк по чанк.
gRPC користи HTTP/2, где је streaming пренос уграђен на нивоу протокола и не захтева посебан chunked механизам. GraphQL сервери који раде преко HTTP/1.1 могу користити Chunked Transfer за streaming пренос резултата претплата (subscriptions). Apollo Server и Hasura шаљу chunked одговоре за GraphQL претплате, преносећи догађаје како настају. Клијент добија ажурирања у реалном времену без потребе за polling-ом.
Chunked Transfer пружа важне предности за веб апликације. Тренутно слање података — сервер не баферује одговор пре слања, смањујући кашњење (latency) до првог бајта. Streaming обрада — клијент може почети обраду података како пристижу, не чекајући потпуно учитавање. Без ограничења меморије — сервер не чува комплетан одговор у меморији, што је критично за велике количине података. Могућност преноса бесконачних токова — SSE, live видео, мониторинг.
Међутим, Chunked Transfer има ограничења. Додатни трошак за сваки чанк износи 6-12 бајтова за величину + CRLF, што за велики број малих чанкова (на пример, по 100 бајтова) може повећати величину одговора за 10-15%. Немогућност навођења тачне величине — клијент не може унапред издвојити бафер или показати траку напретка. Проблеми са прокси серверима — неки стари прокси не подржавају chunked transfer и не могу кеширати такве одговоре. Недовољна подршка за настављак прекинутог преузимања — за делимично примљене chunked одговоре не може се упутити Range захтев.
Према HTTP Archive, 2025, око 35% свих HTTP одговора користи Transfer-Encoding: chunked. Међу њима преовлађују динамичке странице (60%), API одговори (25%) и медија токови (15%). Статички фајлови скоро увек користе Content-Length, јер је њихова величина унапред позната. Удео chunked одговора постепено опада са ширењем HTTP/2, где је streaming пренос имплементиран на нивоу оквира без потребе за додатним заглављем Transfer-Encoding.
У развоју мобилних апликација користите Chunked Transfer за учитавање великих фајлова (слике, видео) и за API захтеве који враћају велике низове података. OkHttp у потпуности подржава chunked transfer без додатног подешавања. За отпремање на сервер (upload) Chunked Transfer се не примењује — за то се Transfer-Encoding не користи за upload у HTTP/1.1. На iOS-у URLSession подржава и слање и пријем chunked података без посебне конфигурације. Streaming парсирање JSON-а (на пример, преко Jackson Streaming API или Moshi) омогућава обраду великих JSON низова како chunked ток пристиже.
Често постављана питања
Сервер укључује Chunked Transfer аутоматски када величина одговора није позната. Nginx додаје Transfer-Encoding: chunked ако није постављен Content-Length. У Spring Boot-у StreamingResponseBody и SseEmitter аутоматски користе chunked transfer. У Node.js Express одговор постаје chunked ако се позову res.write() и res.end() без Content-Length.
Не, спецификација HTTP/1.1 забрањује истовремену употребу Content-Length и Transfer-Encoding: chunked. Ако сервер шаље оба заглавља, клијент мора да игнорише Content-Length и обрађује одговор као chunked. Ово правило је утврђено у RFC 7230 ради компатибилности са прокси серверима који могу мењати тело одговора.
Оптимална величина чанка зависи од сценарија. За обичне веб странице — 4-8 KB. За streaming пренос видеа — 16-64 KB. За SSE — минимални чанкови од 1-2 KB за смањење кашњења. Величина чанка треба да буде умножак величине TCP сегмента (1460 бајтова за Ethernet) ради минимизације фрагментације на транспортном нивоу.
Модерни прокси сервери (Nginx, HAProxy, Envoy) подржавају Chunked Transfer. Прокси може преносити чанкове даље без баферовања (streaming) или баферовати цео одговор и поново га послати са Content-Length. Стари прокси могу баферовати chunked одговор до завршетка, што повећава кашњење. HTTP/2 решава овај проблем на нивоу протокола.
То је исто. Chunked Transfer је пуни назив механизма из спецификације HTTP/1.1. HTTP chunked encoding је исто, понекад се користи у документацији библиотека. Transfer-Encoding: chunked је заглавље које укључује овај режим. Сва три термина описују исти механизам преноса података у деловима.
Резиме
Развићемо мобилну апликацију под кључ
IT Sectr креира iOS и Android апликације за стартапе и предузећа од 2017. године. Саветоваћемо вас и предложити најбоље решење.
Прочитајте такође