본문 바로가기
C.W.K.
Stream
Lesson 04 of 07 · published

HTTP 버전의 진화 — 0.9에서 3까지

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

Level 0HTTP 입문자
0 XP0/46 lessons0/12 achievements
0/120 XP to next level120 XP to go0% complete
"오늘날 HTTP/1.1, HTTP/2, HTTP/3가 함께 쓰여. 메시지가 뜻하는 바는 이어지고, 네트워크에 싣는 방식이 달라졌어."

가계도

HTTP는 응용 계층의 계약을 최대한 유지하면서 진화해 왔어. 이 퀘스트에서 배우는 메서드, 상태 코드, 헤더, URI의 의미는 버전이 달라도 이어져. 크게 달라지는 부분은 전송 표현, 즉 그 정보를 네트워크 위에 어떤 형식으로 싣느냐야.

  • HTTP/0.9 (1991) — 한 줄짜리 GET 요청과 본문 응답만 있던 아주 단순한 형식이야. 지금은 역사적인 버전으로 남아 있어.
  • HTTP/1.0 (1996) — 상태 줄과 헤더, 다양한 메서드가 자리 잡았어. 지속 연결이 기본이 아니어서 보통 요청마다 새 TCP 연결을 열었지.
  • HTTP/1.1 (1997, 2022년 RFC 9112로 정비) — 지속 연결을 기본으로 삼고, 청크 전송 인코딩과 필수 Host 헤더, 파이프라이닝을 정의했어. 시작 줄과 헤더를 텍스트로 표현하므로 netcat에서 직접 작성해 볼 수 있어.
  • HTTP/2 (2015, RFC 9113) — 이진 프레이밍, 하나의 TCP 연결에서 여러 스트림을 처리하는 다중화, HPACK 헤더 압축, 스트림 우선순위 기능을 도입했어. 의미론은 유지하면서 전송 효율을 높였지.
  • HTTP/3 (2022, RFC 9114) — TCP 대신 UDP 기반 QUIC 위에서 동작해. TLS 1.3을 통합하고 스트림별 손실 복구와 연결 이동을 지원하면서도 HTTP 의미론은 그대로 이어 가.

각 버전이 해결한 문제

HTTP/1.1의 대표 변화는 지속 연결이야. TCP 연결을 열어 둔 채 다음 요청에 재사용해 연결 설정 비용을 줄였어. 필수 Host 헤더는 하나의 IP 주소에서 여러 도메인을 구분하는 가상 호스팅을 안정적으로 만들었고.

HTTP/2의 대표 변화는 다중화야. 여러 요청과 응답을 프레임으로 나눠 하나의 TCP 연결에서 번갈아 전송해. 이전에는 브라우저가 같은 출처의 자산을 동시에 가져오려고 여러 TCP 연결을 열었지만, HTTP/2에서는 하나의 연결에 여러 스트림을 실을 수 있어. HPACK 헤더 압축은 반복해서 전송되던 User-Agent, Cookie, Accept-* 같은 필드의 중복도 줄여 줘.

HTTP/3의 대표 변화는 스트림 사이의 전송 계층 head-of-line blocking을 줄인 거야. HTTP/2는 모든 스트림이 하나의 TCP 바이트 스트림을 공유하므로 패킷 하나가 유실되면 복구될 때까지 다른 스트림의 데이터 전달도 막힐 수 있어. QUIC은 손실 복구를 스트림별로 다뤄 영향 범위를 줄이고, 더 빠른 연결 설정과 네트워크 변경 시 연결 이동도 지원해.

의미론은 이어지고, 전송 방식은 진화해. HTTP/1.1의 메서드와 헤더, 상태 코드가 뜻하는 바를 알면 HTTP/2와 HTTP/3에서도 같은 계약을 읽을 수 있어. 이후 내용은 특정 전송 버전보다 메시지의 의미에 초점을 맞춰.

버전을 의식해야 할 때

애플리케이션 코드에서는 버전을 직접 다룰 일이 많지 않아. HTTP 클라이언트(httpx, fetch, axios, curl)와 서버가 지원 범위 안에서 버전을 협상하고, 대체로 같은 API를 제공하기 때문이야.

그래도 버전 차이가 중요한 상황이 있어:

  • 모바일 네트워크 — 패킷 손실이 잦은 환경에서는 HTTP/3의 스트림별 손실 복구가 유리할 수 있어.
  • 작은 자산이 많을 때 — HTTP/2와 HTTP/3의 다중화는 HTTP/1.1에서 여러 연결을 관리하던 부담을 줄여 줘.
  • 오래 유지되는 스트리밍 — HTTP/2에서는 SSE 스트림과 일반 요청을 별도 스트림으로 나눠 하나의 연결에서 함께 처리할 수 있어.
  • 방화벽이나 기업 네트워크 — UDP가 차단되면 HTTP/3 연결이 실패할 수 있으므로 HTTP/2나 HTTP/1.1로 대체할 경로가 필요해.
  • 디버깅 — HTTP/2의 전송 형식은 이진 프레임이라 원시 바이트를 눈으로 읽기 어려워. curl --http1.1로 HTTP/1.1 교환을 보거나, HTTP/2는 Wireshark와 브라우저 DevTools 같은 도구로 해석해서 확인해.

cwkPippa가 사용하는 버전

cwkPippa의 FastAPI/Uvicorn 백엔드는 기본적으로 HTTP/1.1을 사용해. LAN과 Tailscale 안에서 React 프런트엔드와 통신하는 구조라 이 선택으로도 충분해. 공개 cwk-site는 Vercel의 가장자리 네트워크가 브라우저와 지원 가능한 HTTP 버전을 협상하므로, 애플리케이션 코드가 HTTP/2 프레임을 직접 만들 필요는 없어. 프로토콜 협상은 플랫폼에 맡기고 메시지의 의미를 정확히 설계하는 쪽에 집중한 셈이야.

Code

curl로 HTTP 버전을 지정해 응답 줄 확인하기·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 명시적으로 사용하기·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과 HTTP/2에서 여러 작은 요청 비교하기·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를 지원하는 공개 사이트를 골라 curl -v --http1.1 https://<site>/curl -v --http2 https://<site>/를 각각 실행해. (1) TLS의 ALPN 협상 결과, (2) 응답에 표시된 HTTP 버전, (3) curl이 보여 주는 요청·응답 헤더 형식을 비교해. 보너스로 curl이 HTTP/3를 지원한다면 --http3-only도 시도해 서버와 현재 네트워크가 HTTP/3 연결을 허용하는지 확인해.
Hint
curl 상세 출력에서 *는 연결과 TLS 협상 정보, >는 보낸 메시지, <는 받은 메시지를 뜻해. HTTP/2의 전송선은 이진 프레임이지만 curl은 사람이 읽을 수 있도록 해석해서 보여 줘. --http3-only가 실패하면 서버 미지원, curl 빌드의 기능 부족, UDP 차단을 각각 구분해 봐.

Progress

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

댓글 0

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

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