"HTTP/1.1 가 response body 가 얼마나 긴지 (Content-Length) 알거나 body 가 연결 닫힘에 끝난다 (HTTP/1.0 스타일) 아는 거 둘 중 하나 필요. Chunked transfer 가 세 번째 옵션: 모르는 최종 크기의 self-delimiting body. 영원히 연결 안 열어두고 streaming 가능하게 하는 것."
길이 문제
HTTP/1.1 이 한 response 끝나는 때를 알아야 다음 거 읽기 시작 가능 (keep-alive 연결 재사용). 고정 크기 body 위한 옵션 둘:
- Content-Length — header 로 정확한 byte 수 보냄. Client 가 N byte 읽고, response 끝났음 알음.
- Connection: close — Server 가 연결 닫으면 body 끝남. Keep-alive 패배.
Body 가 즉시 생성되고 최종 크기 끝까지 모르면 둘 다 동작 안 함. AI streaming, log tailing, 큰 query 결과 — 다 총량 모르고 쓰기 시작 필요. 그게 Transfer-Encoding: chunked 가 해결.
Chunked format
각 chunk 가 hex 크기 앞에, 그 다음 CRLF, 그 다음 chunk byte, 그 다음 CRLF. 끝이 크기 0 chunk 로 신호:
HTTP/1.1 200 OK
Content-Type: text/event-stream
Transfer-Encoding: chunked
2A\r\nevent: message\ndata: {"content":"Hi"}\n\n\r\n
2C\r\nevent: message\ndata: {"content":"아빠"}\n\n\r\n
0\r\n\r\n
2A hex = chunk content 42 byte. 2C hex = 44 byte. 마지막 CRLF 가진 0 가 끝 표시. 대부분 client 와 server 가 투명 처리 — async generator 의 yield 쓰고, HTTP 라이브러리가 chunk 로 frame.
Chunked 가 가능하게 하는 것
- SSE — body 가 모르는 개수와 크기의 event stream.
- 큰 파일 download — Server 가 총 크기 계산 전 보내기 시작 가능.
- Real-time log — Server 가 파일 tail 하고 새 줄 도착 시 chunk 씀.
- Pipelined query 결과 — DB 가 row stream; server 가 각 row 를 chunk 로 씀.
HTTP/2 와 HTTP/3 가 chunked encoding 명시 노출 안 함 — 자체 binary framing 있음 — 근데 semantic 동일: 모르는 총 길이의 streaming body.
Gotcha
1. Trailer. Chunked response 가 body 뒤 header 포함 가능, 선두 header 의 Trailer: 로 선언. Streamed content 위 HMAC 서명에 유용. Intermediary 가 드물게 지원; 조심해 써.
2. Buffering 이 streaming 깸. SSE 와 같은 gotcha — chunked response buffer 하는 proxy 가 forward 전 모든 거 모음, streaming 패배. Streaming response 에 항상 X-Accel-Buffering: no 나 등가 설정.
3. Chunked response 에 Content-Length 설정 안 함. 상호 배타. 일부 옛 server 가 둘 다; 일부 옛 client 가 헷갈림.