"HTTP/1.1은 응답 본문이 어디서 끝나는지 분명히 표시해야 같은 연결을 다음 메시지에 다시 쓸 수 있어. 최종 길이를 미리 알 수 없다면 청크 전송 코딩이 각 조각의 길이와 마지막 지점을 본문 안에 기록해. 덕분에 연결을 닫아 끝을 알리지 않고도 생성되는 데이터를 곧바로 보낼 수 있어."
본문 경계가 필요한 이유
HTTP/1.1 연결에서 응답 본문을 읽는 클라이언트는 현재 응답의 끝을 알아야 뒤따르는 메시지를 올바르게 해석할 수 있어. 길이가 정해진 응답에는 주로 다음 두 방식이 보여:
- Content-Length — 헤더에 정확한 바이트 수를 적어. 클라이언트는 그만큼 읽으면 본문이 끝났다고 판단해.
- Connection: close — 연결 종료로 본문의 끝을 표시해. 동작은 하지만 그 연결을 다음 요청에 재사용할 수 없어.
AI 응답, 실시간 로그, 점진적으로 생성되는 쿼리 결과처럼 끝까지 만들어 보기 전에 전송을 시작해야 하는 본문은 Content-Length를 미리 계산할 수 없어. 연결 종료로 경계를 표시할 수도 있지만 연결 재사용을 포기해야 해. HTTP/1.1의 Transfer-Encoding: chunked는 최종 길이를 몰라도 본문 자체에 경계를 기록해 이 문제를 해결해.
청크의 전송 형식
각 청크는 데이터 바이트 수를 16진수로 적은 줄, CRLF, 해당 바이트, 다시 CRLF 순서로 구성돼. 크기가 0인 마지막 청크가 본문의 끝을 표시해:
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와 2C는 16진수 크기 표기가 놓이는 자리를 보여 주는 값이야. 실제 메시지에서는 반드시 뒤따르는 데이터의 실제 바이트 수를 계산해 기록해야 하므로 표시된 숫자를 그대로 복사하면 안 돼. 0 뒤의 마지막 CRLF는 청크 본문이 끝났음을 나타내. 보통은 HTTP 서버와 클라이언트 라이브러리가 이 프레이밍을 처리하므로 애플리케이션이 청크 문법을 직접 만들지 않아.
길이를 모르는 스트림의 쓰임새
- SSE — HTTP/1.1에서 개수와 총길이를 미리 알 수 없는 이벤트를 응답 본문에 이어 보낼 수 있어.
- 대용량 다운로드 — 압축이나 변환 결과를 만들면서 보내는 등 최종 크기를 미리 계산하기 어려운 경우 전송을 먼저 시작할 수 있어.
- 실시간 로그 — 새 로그 줄이 생길 때마다 끝나지 않은 응답에 이어 쓸 수 있어.
- 점진적 쿼리 결과 — 데이터베이스에서 행을 읽는 대로 직렬화해 전체 결과를 메모리에 모으지 않고 전달할 수 있어.
HTTP/2와 HTTP/3는 Transfer-Encoding: chunked를 사용하지 않아. 대신 자체 DATA 프레임과 스트림 종료 표지를 사용해 최종 길이를 모르는 본문을 전달해. 애플리케이션에서 보이는 스트리밍 의미는 비슷하지만 전송선의 프레이밍은 서로 달라.
주의할 점
1. Trailer 필드. 청크 응답은 마지막 청크 뒤에 일부 필드를 보낼 수 있고, 보낼 필드 이름을 선두 헤더의 Trailer:로 알릴 수 있어. 스트림 전체를 읽은 뒤 계산되는 무결성 값 등에 쓸 수 있지만, 모든 중간 장치와 클라이언트 API가 trailer를 보존하거나 노출하는 것은 아니므로 호환성을 먼저 확인해야 해.
2. 버퍼링은 점진적 전달을 가려. 프록시나 압축 계층이 작은 조각을 모아 두면 HTTP/1.1이 chunked로 프레이밍되어 있어도 클라이언트에는 늦게 도착할 수 있어. X-Accel-Buffering: no는 Nginx에서 사용할 수 있는 설정 신호일 뿐이므로 실제 경로의 각 계층을 확인해야 해.
3. Content-Length와 함께 보내면 안 돼.송신자는 Transfer-Encoding이 있는 HTTP/1.1 메시지에 Content-Length를 함께 생성하면 안 돼. 두 헤더가 충돌하면 중간 장치마다 메시지 경계를 다르게 해석해 보안 문제로 이어질 수도 있으므로 프레임워크의 올바른 처리를 따르는 편이 안전해.