C.W.K.
Stream
Lesson 04 of 07 · published

HTTP Versions — 같은 semantics, 다른 wire

~11 min · foundations, http1, http2, http3, quic, multiplexing

Level 0HTTP Newbie
0 XP0/46 lessons0/12 achievements
0/120 XP to next level120 XP to go0% complete
"오늘날 세 개의 HTTP 가 현역으로 쓰여. 다 같은 단어를 써. 그냥 봉투를 다르게 포장할 뿐."

가계도

HTTP 는 application 층 계약을 안 깨고 진화했어. 이 퀘스트에서 배우는 method, status code, header, URI 는 어느 version 에서도 똑같이 동작해. 변하는 건 wire encoding — 메시지의 네 부분이 네트워크 위에 어떻게 놓이느냐.

  • HTTP/0.9 (1991) — 한 줄 GET 만. 역사적 호기심; 오래전 죽음.
  • HTTP/1.0 (1996) — status code, header, GET 이외의 method 도입. Keep-Alive 아직 없어서 request 마다 새 TCP 연결.
  • HTTP/1.1 (1997, 2022년 RFC 9112 로 다듬어짐) — persistent connection 기본, chunked transfer encoding, 필수 Host header, pipelining (잘 안 씀). Wire 위 텍스트 기반 — netcat 에 칠 수 있는 그거.
  • HTTP/2 (2015, RFC 9113) — binary framing, multiplexing (한 TCP 연결 위 여러 동시 stream), header 압축 (HPACK), prioritization. 같은 semantics, 훨씬 빠른 전달.
  • HTTP/3 (2022, RFC 9114) — TCP 대신 QUIC (UDP 기반) 위에서 돌아. 더 빠른 handshake (TLS 묶음), head-of-line blocking 없음, 연결 migration. Semantics 또 같음.

각 version 이 해결한 것

HTTP/1.1 의 킬러 기능은 Keep-Alive: TCP 연결을 열어둬서 다음 request 가 재사용. 필수 Host header 와 합쳐서 virtual hosting (한 IP 에 여러 사이트) 을 가능하게 했고, 웹페이지를 극적으로 빠르게 만들었어.

HTTP/2 의 킬러 기능은 multiplexing: 여러 request 가 frame 으로 한 TCP 연결 위에 interleave. HTTP/2 전엔 브라우저가 asset parallel fetch 위해 origin 당 ~6 TCP 연결 열었어. HTTP/2 에선 한 연결이 다 처리. Header 압축 (HPACK) 이 반복 request overhead 잘랐어 — 같은 origin 으로 가는 모든 request 가 그 모든 User-Agent, Cookie, Accept-* header 를 raw text 로 재전송했었거든; HTTP/2 가 중복 제거해.

HTTP/3 의 킬러 기능은 TCP head-of-line blocking 죽인 것. HTTP/2 에선 multiplex 된 stream 들이 한 TCP 연결 공유라서 패킷 하나 잃으면 모든 stream 이 stall. QUIC (HTTP/3 transport) 는 loss 를 per-stream 처리해서 다른 stream 들은 계속 흘러. 추가로: 더 빠른 handshake 와 연결 migration (폰이 request 중간에 네트워크 바꿔도 됨).

Semantics 는 변하지 않고, wire 만 진화해. HTTP/1.1 의 method, header, status code 를 알면 HTTP/2 와 HTTP/3 도 알아. 이 퀘스트 나머지는 전부 wire-version-independent — message 의 의미에 대한 거지 아래 byte 에 대한 게 아냐.

Version 신경 써야 할 때

대부분의 application code 한텐 답이 절대 없음. 네 HTTP client (httpx, fetch, axios, curl) 랑 server 가 version 을 투명하게 negotiate 해. HTTP/1.1 이든 HTTP/3 이든 같은 코드 써.

신경 써야 하는 때:

  • 모바일 네트워크 — HTTP/3 가 손실 많은 연결에서 이김 (HTTP/2 의 head-of-line blocking 이 거기서 아파).
  • 작은 asset 많을 때 — HTTP/2/3 multiplexing 이 HTTP/1.1 의 origin 당 연결 cap 이김.
  • 장기 스트리밍 — HTTP/2 frame 이 SSE stream 과 일반 request 를 한 연결에 섞을 수 있게 해.
  • 방화벽 / 회사 네트워크 — UDP (그래서 HTTP/3) 가 가끔 차단됨; HTTP/2 fallback 필요.
  • Debugging — HTTP/2 binary wire 는 사람이 못 읽음. curl --http1.1 이 text trace 줘; HTTP/2 는 Wireshark 나 브라우저 DevTools 로 decode 해야.

cwkPippa 의 version 현실

cwkPippa 의 FastAPI/Uvicorn backend 는 기본적으로 HTTP/1.1 써. 괜찮아 — LAN 과 Tailscale 위에서 React frontend 서빙하니까 multiplexing 이득이 작아. 공개 cwk-site (Vercel 위 Next.js) 는 edge 에서 자동으로 HTTP/2 와 HTTP/3 받아; Cloudflare 와 Vercel 이 각 방문자의 브라우저랑 best version 을 negotiate. HTTP/2 코드 한 줄도 안 썼고; 그냥 플랫폼이 고르게 뒀어.

Code

curl 로 특정 HTTP version 강제하고 응답 줄 보기·bash
# curl 이 server 랑 HTTP version negotiate 하는 거 보기
# -v 로 고른 protocol 봄
curl -v --http1.1 https://creativeworksofknowledge.com/ 2>&1 | grep -E '^(>|<) ' | head
curl -v --http2     https://creativeworksofknowledge.com/ 2>&1 | grep 'HTTP/'
curl -v --http3-only https://creativeworksofknowledge.com/ 2>&1 | grep 'HTTP/'

# Response 줄 봐:
# < HTTP/1.1 200 OK
# < HTTP/2 200
# < HTTP/3 200
# Server 가 어느 version 에 동의했는지 알려줘.
Python httpx — HTTP/2 opt-in·python
import httpx

# 기본은 HTTP/1.1 — 어디서나 돌아
resp = httpx.get('https://creativeworksofknowledge.com/')
print(resp.http_version)  # 'HTTP/1.1'

# HTTP/2 opt-in (`pip install httpx[http2]` 필요)
with httpx.Client(http2=True) as client:
    resp = client.get('https://creativeworksofknowledge.com/')
    print(resp.http_version)  # server 가 지원하면 'HTTP/2'

# httpx 는 아직 HTTP/3 안 줘 (2026년 기준); 일단 curl --http3 써
HTTP/1.1 vs HTTP/2 작은 parallel request 다수 비교·bash
# Multiplexing 데모: 같은 origin 에서 asset 6개 fetch
# HTTP/1.1: 브라우저가 최대 6 parallel 연결 염
# HTTP/2:    한 연결, 6 multiplex stream
# HTTP/3:    HTTP/2 와 같지만 QUIC 위

# 직접 시간 재 (대략 데모)
time curl -s --http1.1 -o /dev/null \
  https://creativeworksofknowledge.com/a.png \
  https://creativeworksofknowledge.com/b.png \
  https://creativeworksofknowledge.com/c.png \
  https://creativeworksofknowledge.com/d.png \
  https://creativeworksofknowledge.com/e.png \
  https://creativeworksofknowledge.com/f.png

time curl -s --http2 -o /dev/null \
  https://creativeworksofknowledge.com/a.png \
  https://creativeworksofknowledge.com/b.png \
  https://creativeworksofknowledge.com/c.png \
  https://creativeworksofknowledge.com/d.png \
  https://creativeworksofknowledge.com/e.png \
  https://creativeworksofknowledge.com/f.png

External links

Exercise

HTTP/2 나 HTTP/3 지원하는 공개 사이트 골라 (cloudflare.com, google.com, 요즘 사이트 아무거나). curl -v --http1.1 https://<site>/curl -v --http2 https://<site>/ 돌려. 세 가지 비교: (1) TCP 연결 몇 개 열렸는지 ('Trying' 줄 봐), (2) response 줄에 negotiate 된 protocol, (3) header byte — HTTP/2 의 HPACK 압축으로 request 줄이 HTTP/1.1 raw text 보다 짧아야. 보너스: --http3-only 시도해서 server 가 지원하는지 봐.
Hint
curl verbose 출력 접두사: * = curl 부연설명 (TCP, TLS), > = 보낸 byte, < = 받은 byte. Response 줄의 'HTTP/X' 가 negotiate 된 거 알려줘. CDN 대부분 (Cloudflare, Akamai, Fastly) HTTP/3 함; origin server 대다수는 안 해.

Progress

Progress is local-only — sign in to sync across devices.
이 페이지에서 버그를 발견하셨거나 피드백이 있으세요?문제 신고

댓글 0

🔔 답글 알림 (로그인 필요)
로그인댓글을 남기려면 로그인해 주세요.

아직 댓글이 없어요. 첫 댓글을 남겨보세요.