"모든 HTTP 메시지 — request 든 response 든, 1990년이든 2026년이든, plain 이든 암호화든 — 네 부분 같은 shape 이야. Shape 한 번 외우고 나면 나머지는 채우기일 뿐."
한 가지 shape, 영원히
HTTP 메시지는 정확히 네 부분이야, 이 순서로:
- Start line — 이게 어떤 종류의 메시지인지 말하는 한 줄.
- Header — 0개 이상의 key: value 쌍.
- Blank line — 글자 그대로의 CRLF, "header 끝, body 시작" 신호.
- Body — optional payload. 비어 있거나, JSON 이거나, form data, 이미지, event stream, 뭐든.
이게 다야. 모든 HTTP/1.1 메시지가 이 네 부분이야. HTTP/2 랑 HTTP/3 는 같은 내용을 binary block 으로 frame 해서 빠르게 만든 거지, code 가 보는 parsed shape 은 동일해. Shape 을 배워; 나머지는 그 위의 variation 일 뿐.
Start line — Request 와 Response 가 다른 유일한 곳
첫 줄이 request 랑 response 가 구조적으로 다른 유일한 자리야.
Request start line 은 토큰 세 개: METHOD SP URI SP HTTP-VERSION. 예: POST /api/chat HTTP/1.1. "HTTP/1.1 로 /api/chat 에 POST 하고 싶어" 라는 뜻.
Response start line 도 토큰 세 개지만 다른: HTTP-VERSION SP STATUS-CODE SP REASON-PHRASE. 예: HTTP/1.1 201 Created. "HTTP/1.1 response, status 201, 의미는 Created". Reason phrase 는 사람 보라는 텍스트야 — client 는 절대 거기 의존해서 분기하면 안 돼; 숫자 코드로 분기해.
Header — 메시지에 대한 metadata
Header 는 메시지가 뭔지, 어떻게 다룰지 describe 해. Key 는 wire 에서 대소문자 무관이야 (Content-Type, content-type, CONTENT-TYPE 다 같은 거). Value 는 ASCII 면 뭐든; 쉼표로 한 header 에 여러 value 묶을 수 있어.
초반엔 두 category 가 가장 중요해:
- Representation metadata (예전엔 "entity header") — body 에 뭐가 있는지.
Content-Type,Content-Length,Content-Encoding. Body 가 있는 곳이면 request 든 response 든 나와. - Control header — request 자체를 어떻게 다룰지. Request 엔
Host,Authorization,Accept,User-Agent. Response 엔Server,Set-Cookie,Cache-Control.
Blank line — 멍청하지만 필수
한 줄의 CRLF (Carriage Return + Line Feed) 가 header 와 body 를 분리해. 빼먹으면 server 가 body 를 또 다른 header 줄로 봐. 요즘 client 대부분이 자동으로 써주지만, TCP socket 위에 손으로 request 만들 거면 blank line 까먹는 게 1위 신참 버그야.
Content-Type response header 를 print 하는 거야. Header 가 body 의 format 에 대한 진실; text/html body 를 response.json() 하려는 게 "API 가 쓰레기 줬어" 의 가장 흔한 원인이야.Body — Optional, header 가 describe
Body 는 optional. GET request 는 보통 없어. DELETE 도 자주 없어. 근데 존재하는 모든 body 는 최소 두 header 중 하나로 describe 돼: Content-Length (고정 크기, byte 수) 혹은 Transfer-Encoding: chunked (스트리밍, 길이 미리 모름). cwkPippa SSE response 가 Transfer-Encoding: chunked 를 써 — 네 부분 anatomy 똑같음, body 만 event 하나씩 long-lived connection 으로 흘러나오는 거.
전체를 시각화
이걸 byte 단위로 읽을 수 있으면 앞으로 만날 모든 HTTP 메시지를 읽을 수 있어.