안녕, 리뷰어. 나는 뫙대🛠️
CS에 대한 개념이 0에 수렴해 공부를 시작합니다. 네트워크 공부는 '혼자 공부하는 네트워크'를 기반으로 합니다. 이번 글에서는 응용 계층의 HTTP에 대해 다룹니다.
- 저자
- 강민철
- 출판
- 한빛미디어
- 출판일
- 2024.04.12
HTTP(Hyper Text Transfer Protocol)
정보를 주고받는 데 사용되는 프로토콜
요청-응답 기반 프로토콜
클라이언트-서버 주고 기반의 요청-응답 프로토콜 → 요청과 응답 메시지 형태가 다름

미디어 독립적 프로토콜
자원의 특성과 무관하게 자원을 주고받을 수단
- 종류: 미디어 타입 i.e. MIME(Multipurpose Internet Mail Extensions) 타입 참조. media types
type/subtype;parameter=value: 데이터 유형/세부유형;부가설명
스테이트리스 프로토콜 🔗 확장성・견고성
상태를 유지하지 않는 포르토콜
- 이전 상태 정보를 저장하지 않기 때문에 모든 HTTP 요청을 독립적 요청으로 간주 → 쉽게 서버 추가
- 특정 클라이언트가 특정 서버에 종속되지 않음 → 문제가 생겨도 쉽게 다른 서버로 대체 가능
지속 연결 프로토콜 i.e. 킵 얼라이브(keep-alive)
하나의 TCP 연결을 유지하며 여러 요청-응답을 주고받을 수 있는 기술. HTTP/1.1부터 기본으로 적용
→ 연결을 재사용해 오버헤드 감소+전송 지연 최소화로 성능 향상
HTTP의 발전
| 버전 | 주요 특징 | 연결 방식 |
전송 방식 |
메서드 | 개선점 | 기타 기능 |
| HTTP/0.9 | 초창기 HTTP 버전. 요청 메시지 한 줄 구성 | 비지속 | 텍스트 | GET | - | 헤더 지원 X |
| HTTP/1.0 | 헤더 도입. 메서드 추가 | 비지속 | 텍스트 | GET, POST, HEAD | 헤더 지원 | 지속 연결 지원 X |
| HTTP/1.1 | 오늘날까지 널리 사용되는 버전 | 지속 | 텍스트 | 다양한 메서드 | 지속 연결 공식적 지원 | 파이프라이닝, 사용 가능 헤더 |
| HTTP/2.0 | 1.1의 효율과 성능 보완. 헤더 압축. 병렬 처리 가능 | 지속 | 바이너리 | 다양한 메서드 | HOL 블로킹 문제 완화 → 멀티플레싱 도입 | 서버 푸시 |
| HTTP/3.0 | 현재 빠르게 성장하는 프로토콜. UDP 기반 QUIC 프로토콜 사용 | 지속 | 바이너리 | 다양한 메서드 | 속도 개선 | - |
HTTP 메시지
시작 라인+필드 라인(0개 이상)+메시지 본문(선택)
시작 라인start line
공백으로 구분
요청 라인request line
HTTP 요청 메시지 method request-target HTTP-version
- 메서드method: 요청 대상에 대해 수행할 작업의 종류 e.g. GET 🔗 API 문서
| HTTP 메서드 | 설명 | 요청 URI | 멱등성* | 안전성 |
| GET | 자원을 습득하기 위한 메서드 | 컬렉션 URI, 특정 리소스 URI | O | O |
| HEAD | GET과 유사. 헤더만 응답받는 메서드 | 특정 리소스 URI | O | O |
| POST | 서버로 하여금 특정 작업을 처리하도록 하는 메서드 | 컬렉션 URI | X | X |
| PUT | 자원을 대체하기 위한 메서드. 덮어쓰기 | 특정 리소스 URI | O | X |
| PATCH | 자원에 대한 부분적 수정을 위한 메서드 | 특정 리소스 URI | X | X |
| DELETE | 자원을 삭제하기 위한 메서드 | 특정 리소스 URI | O | X |
| CONNECT | 자원에 대한 양방향 연결을 시작하는 메서드 | 프록스 URI 등 특수한 경우 | X | X |
| OPTIONS | 사용 가능한 메서드 등 통신 옵션을 확인하는 메서드 | 컬렉션 URI, 특정 리소스 URI | O | O |
| TRACE | 자원에 대한 루프백 테스트를 수행하는 메서드 | 특정 리소스 URI | O | O |
* 첫 번째 수행을 한 뒤 여러 차례 적용해도 결과를 변경시키지 않는 작업 또는 기능의 속성 참조. 토스개발블로그
- 요청 대상request target: 서버의 자원. 보통 URI의 경로 e.g. /feed
- HTTP 버전HTTP version
HTTP/<version>e.g. HTTP/1.1
상태 라인status line
HTTP 응답 메시지 HTTP-version status-code reason-phrase
- HTTP 버전
- 상태 코드status code: 요청에 대한 세 자리 정수의 결과 참조. HTTP status codes e.g. 200
- 이유 구문reason phrase: 상태 코드에 대한 문자열 형태의 설명. 선택적 e.g. OK
| 상태 코드 | 유형 | 이유 구문 | 설명 |
| 200 | 성공 | OK | 요청이 성공했음 |
| 201 | 성공 | Created | 요청이 성공했으며, 새로운 자원이 생성됐음 🔗Location 헤더 |
| 202 | 성공 | Accpeted | 요청을 잘 받았으나, 아직 요청한 작업을 끝내지 않았음 |
| 204 | 성공 | No Content | 요청이 성공했지만, 메시지 본문으로 표시할 데이터가 없음 |
| 301 | 리다이렉션 | Moved Permanently | 재요청 메서드 변경될 수 있음 |
| 308 | 리다이렉션 | Permanent Redirect | 재요청 메서드 변경되지 않음 |
| 302 | 일시적 리다이렉션 | Found | 재요청 메서드 변경될 수 있음 |
| 303 | 일시적 리다이렉션 | See Other | 재요청 메서드 GET으로 변경 |
| 307 | 일시적 리다이렉션 | Temporary Redirect | 재요청 메서드 변경되지 않음 |
| 304 | 특수 리다이렉션 | Not Modified | 자원이 변경되지 않았음 🔗캐시 |
| 400 | 클라이언트 에러 | Bad Request | 클라이언트 요청이 잘못됐음 |
| 401 | 클라이언트 에러 | Unauthorized | 요청한 자원에 대한 유효한 인증이 없음 |
| 403 | 클라이언트 에러 | Forbidden | 요청이 서버에 의해 거부됨 e.g. 접근 권한 X |
| 404 | 클라이언트 에러 | Not Found | 요청받은 자원을 찾을 수 없음 |
| 405 | 클라이언트 에러 | Method Not Allowed | 요청한 메서드를 지원하지 않음 |
| 500 | 서버 에러 | Internal Server Error | 요청을 처리할 수 없음 |
| 502 | 서버 에러 | Bad Gateway | 중간 서버의 통신 오류 |
| 503 | 서버 에러 | Service Unavailable | 현재는 요청을 처리할 수 없으나 추후 가능할 수도 있음 |
필드 라인
0개 이상의 HTTP 헤더 명시
헤더
header-name: header-value
- 요청
- Host: 요청을 보낼 호스트. 주로 도메인 네임으로 명시 e.g.
Host: www.tistory.com - User-Agent: HTTP 요청을 시작하는 클라이언트 측 프로그램. 클라이언트의 접속 환경 유추
→ 웹 브라우저의 Mozilla 호환 여부 운영체제 및 아키텍처 정보 렌더링 엔진 관련 정보 브라우저와 버전 정보
e.g.User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/136.0.0.0 Safari/537.36 - Referer: 클라이언트의 유입 경로 파악. 클라이언트가 요청을 보낼 때 머무르고 있던 URL 명시
e.g.Referer: https://logins.daum.net/ - Authorization: 클라이언트의 인증 정보. 인증 타입type과 인증을 위한 정보credentuals 명시
e.g.Authorization: Basic:<Base64(username:password)>
- Host: 요청을 보낼 호스트. 주로 도메인 네임으로 명시 e.g.
- 응답
- Server: 요청을 처리하는 서버 측의 소프트웨어 관련 정보 e.g.
Server: Apche/2.4.1 (Unix) - Allow: 클라이언트에게 허용된 HTTP 메서드 목록 🔗 상태코드 405 e.g.
Allow: POST, OPTIONS - Retry-After: 자원을 사용할 수 있는 날짜 또는 시간 🔗 상태코드 503 e.g.
Retry-After: 120 - Location: 자원의 위치. 주로 리다이렉션 발생 또는 새로운 자원 생성 시 사용 e.g.
Location: /posting/1 - WWW-Authenticate: 자원에 접근하기 위한 인증 방식 설명 🔗 상태코드 401 e.g.
WWW-Authenticate: Basic realm="Access to engineering site", charset="UTF-8"
- Server: 요청을 처리하는 서버 측의 소프트웨어 관련 정보 e.g.
- 모두
- Date: 메시지가 생성된 날짜와 시각 e.g.
Date: Mon, 19 May 2025 14:56:40 GMT - Connection: 요청과 응답 간의 연결 방식 설정 🔗 지속 연결 e.g.
Connection: keep-alive - Content-Length: 본문의 바이트 단위 크기 e.g.
Content-Length: 100 - Content-Type, Content-Language, Content-Encoding: 본문의 표현 방식 설명 i.e. 표현 헤더
e.g.Content-Type: text/html; charset=utf-8 Content-Language: ko-KR Content-Encoding: gzip
- Date: 메시지가 생성된 날짜와 시각 e.g.
캐시
정보의 사본을 임시로 저장(caching)하는 기술. 불필요한 대역폭 낭비와 응답 지연 방지 참조. RFC 9111
- 개인 전용 캐시private cache: 웹 브라우저에 저장
- 공용 캐시public cache: 클라이언트와 서버 사이에 위치한 중간 서버에 저장
캐시 신선도cahce freshness: 캐시된 사본 데이터와 최신 원본 데이터의 유사도 → 신선도 유지를 위해 캐시된 데이터에 유효 기간 설정. 유효 기간이 만료됐을 때 재검사
- 날짜 기반: 특정 시점. If-Modified-Since → 특정 시점 이후 원본 데이터의 변경을 물어봄
- 엔티티 태크(Etag, Entity Tag) 기반: 자원의 버전을 식별하기 위한 정보. If-Non-Match → 정보와 일치하는 자원을 물어봄
- 요청받은 자원이 변경됐음 🔗 상태코드 200
- 요청받은 자원이 변경돼지 않았음 🔗 상태코드 304
- 요청받은 자원이 삭제됐음 🔗 상태코드 404
쿠키
서버에서 생성돼 클라이언트 측에 저장되는 데이터. 서버가 클라이언트의 상태를 알 수 있음 → 스테이트리스 특성 보완
단, 보안 취약 → 보완하기 위한 수단: Secure 🔗 HTTPS, HttpOnly(자바스크립트의 쿠키 접근 금지)
<이름, 값> 쌍의 기본 형태. 적용 범위와 만료 기간 등 다양한 속성 추가

콘텐츠 협상 🔗 GET, Accept 헤더
가장 적합한 자원의 형태, 즉 표현을 제공하는 메커니즘. 클라이언트의 요구사항을 바탕으로 같은 URI에서 가장 적절한 표현을 선택해 응답
q(Quality Value) 값으로 우선순위 반영 → 범위 0~1(생략). 클수록 우선순위가 높음
GET /feed HTTP/1.1
Host: www.tistory.com
Accept-Language: ko-KR,ko;q=0.9,en-US;q=0.8,en;q=0.7
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
공식 문서는 정말 좋은 것이다. 이번 장을 공부하면서 RFC 문서의 도움을 톡톡히 얻었다. 특히 DNS와 URI를 공부할 때 유용하게 읽었다. 처음 목차를 훑었을 때는 HTTP가 오래 걸릴 줄 알았는데, 웬 걸. 오히려 익숙한 DNS가 오래 걸렸다. 눈에 익은 만큼 하나하나 찾아보는 데 시간을 많이 썼다. 고마워요, RFC 문서. 응용 계층을 공부하는 동안 개발자도구로 쉽게 확인할 수 있어서 특히 재밌었다. 프론트엔드 공부하며 나왔던 부분이 겹쳐서 "아, 이게 그거구나." 했다. 특히 쿠키가 그랬다. 팝업 등을 구현할 때 쿠키를 사용했었지만, 정확히 왜 써야하는지 잘 몰랐었다. 스테이트리스 특성 때문이었구나. 그동안 얼마나 기본 지식 없었는지 확인해보는 시간이 됐다. 이것도 모르면서 어떻게... 이제라도 알아서 다행이라고 생각하기로 했다. 추가. 확실히 단어 의미를 알면 이해가 더 잘 된다.
🤔 HTTP/3.0부터 UDP를 사용하는 이유는 동일한 스테이트리스 프로토콜이기 때문일까. TCP 기반과 UDP 기반 HTTP의 차이점을 좀 더 찾아봐야겠다.
참고
'CS > 네트워크' 카테고리의 다른 글
| [혼자 공부하는 네트워크] 07 네트워크 심화 (1) | 2025.05.26 |
|---|---|
| [혼자 공부하는 네트워크] 06 실습으로 복습하는 네트워크 - 와이어샤크 (0) | 2025.05.26 |
| [혼자 공부하는 네트워크] 05 응용 계층 - DNS (0) | 2025.05.19 |
| [혼자 공부하는 네트워크] 04 전송 계층 - UDP (0) | 2025.05.13 |
| [혼자 공부하는 네트워크] 04 전송 계층 - TCP (1) | 2025.05.13 |

