HTTP 기본
모든 것이 HTTP
HTTP는 HyperText Transfer Protocol의 약자로,
원래는 하이퍼텍스트 문서인 HTML을 전송하기 위해 개발되었습니다.
하지만 현재는 이미지, 음성, 영상, 파일, JSON, XML 등
거의 모든 형태의 데이터를 전송할 수 있는 프로토콜로 발전했습니다.
심지어 서버 간의 통신에서도 HTTP를 많이 사용하며, TCP 프로토콜을 직접 사용하는 경우는 드뭅니다.
예를 들어, 모바일 게임에서도 HTTP를 이용하여 서버와 통신하는 경우가 많습니다.
이렇게 HTTP는 시간이 흐르면서 모든 것을 전송할 수 있는 만능 프로토콜로 자리매김했습니다.
따라서 우리는 현재 “HTTP의 시대”에 살고 있다고 할 수 있습니다.
HTTP의 역사와 버전
- HTTP/0.9: 초기 버전으로 단순한 GET 메서드와 HTML 전송만 지원.
- HTTP/1.0: 헤더 개념 도입, 다양한 메서드와 MIME 타입 지원.
- HTTP/1.1: 현재 가장 중요한 버전으로, 지속 연결(Persistent Connection), 파이프라이닝 등 성능 개선.
- HTTP/2: 성능 향상을 위한 이진 프로토콜, 멀티플렉싱 지원.
- HTTP/3: UDP 기반의 QUIC 프로토콜을 사용하여 연결 설정 지연 감소.
기반 프로토콜
- HTTP/1.1과 HTTP/2: TCP 기반으로 동작.
- HTTP/3: UDP 기반의 QUIC 프로토콜 사용.
예시
웹 브라우저에서 개발자 도구(F12)를 열고 네트워크 탭에서 프로토콜을 확인하면, 해당 사이트가 어떤 HTTP 버전을 사용하는지 알 수 있습니다.
- Google: HTTP/2(h2)와 HTTP/3(h3)를 사용.
- 네이버: HTTP/1.1과 HTTP/2를 사용.
확인 문제
- 질문: 현재 HTTP는 어떤 데이터들을 전송할 수 있나요?
- 답변: HTTP는 HTML뿐만 아니라 이미지, 음성, 영상, 파일, JSON, XML 등
거의 모든 형태의 데이터를 전송할 수 있습니다.
클라이언트-서버 구조
HTTP는 클라이언트-서버 구조를 따르는 프로토콜입니다.
클라이언트는 서버에 요청을 보내고, 서버는 그 요청에 대한 응답을 반환합니다.
이때 클라이언트는 응답을 받을 때까지 대기합니다.
특징
- 역할 분리: 클라이언트와 서버를 분리하여 각각의 역할에 집중.
- 클라이언트: 사용자 인터페이스(UI) 및 경험(UX)에 집중.
- 서버: 데이터 관리 및 비즈니스 로직 처리에 집중.
- 독립적 진화: 클라이언트와 서버가 서로 영향을 받지 않고 독립적으로 발전 가능.
- 다양한 플랫폼 지원: 클라이언트는 PC, 모바일, TV 등 다양한 플랫폼에서 동작.
예시
- 클라이언트: 웹 브라우저, 모바일 앱, 데스크톱 애플리케이션 등.
- 서버: 웹 서버(Apache, Nginx), 애플리케이션 서버, 데이터베이스 서버 등.
확인 문제
- 질문: 클라이언트-서버 구조의 장점은 무엇인가요?
- 답변: 클라이언트와 서버를 분리하여 각각 독립적으로 발전할 수 있고,
역할에 집중할 수 있으며, 다양한 플랫폼을 지원할 수 있습니다.
Stateful vs Stateless (무상태 프로토콜)
HTTP는 무상태(Stateless) 프로토콜을 지향합니다.
이는 서버가 클라이언트의 상태를 보존하지 않는다는 의미입니다.
각 요청은 독립적으로 처리되며, 이전 요청의 정보나 상태를 알지 못합니다.
Stateful (상태 유지) 예시
- 고객이 마트에서 점원에게 “노트북 얼마예요?”라고 묻습니다.
- 점원은 “100만 원입니다.”라고 답합니다.
- 고객은 “2개 구매할게요.”라고 말합니다.
- 점원은 이전 대화를 기억하고 “200만 원입니다.”라고 계산합니다.
- 고객은 “신용카드로 결제하겠습니다.”라고 말합니다.
- 점원은 거래를 완료합니다.
- 이 과정에서 점원은 고객의 이전 대화 내용과 상태를 기억하고 있습니다.
Stateless (무상태) 예시
- 고객이 점원에게 “노트북 2개를 신용카드로 구매하겠습니다.”라고 말합니다.
- 점원은 이전 대화 없이도 필요한 정보를 모두 받아 거래를 완료합니다.
- 점원은 고객의 이전 상태나 대화를 기억할 필요가 없습니다.
장점
- 확장성: 서버가 상태를 유지하지 않으므로, 서버를 쉽게 증설하여 대량의 요청을 처리할 수 있습니다.
- 유연성: 서버 간 로드 밸런싱 및 장애 대응이 용이합니다.
단점
- 데이터 중복 전송: 각 요청마다 필요한 모든 정보를 포함해야 하므로, 데이터 전송량이 증가할 수 있습니다.
- 상태 유지 필요시 복잡성 증가: 로그인 세션 등 상태 유지를 위해 추가적인 메커니즘(예: 세션, 토큰)이 필요합니다.
확인 문제
- 질문: HTTP가 무상태 프로토콜을 지향하는 이유는 무엇인가요?
- 답변: 서버가 상태를 유지하지 않음으로써 확장성을 높이고, 서버 자원을 효율적으로 사용하여 대량의 요청을 효과적으로 처리할 수 있기 때문입니다.
비연결성
HTTP는 기본적으로 비연결성(Connectionless)을 특징으로 합니다.
이는 클라이언트와 서버가 요청 및 응답 후 연결을 끊는 방식을 의미합니다.
특징
- 요청마다 새로운 연결: 각 요청 시마다 새로운 연결을 맺고, 응답 후 연결을 종료합니다.
- 서버 자원 절약: 불필요한 연결을 유지하지 않아 서버 자원을 효율적으로 사용합니다.
장점
- 동시 처리 능력 향상: 많은 클라이언트의 요청을 효율적으로 처리할 수 있습니다.
- 자원 관리 용이: 연결을 지속적으로 유지하지 않아 서버 자원 소모가 적습니다.
단점
- 연결 설정 오버헤드: 요청마다 연결 설정(3-way handshake)이 필요하므로 지연이 발생할 수 있습니다.
- 성능 저하 가능성: 웹 페이지 로딩 시 여러 리소스를 각각 요청하면 성능이 저하될 수 있습니다.
지속 연결 (Persistent Connection)
- HTTP/1.1부터는 기본적으로 지속 연결을 사용하여 위의 단점을 보완합니다.
- 한 번의 연결로 여러 개의 요청과 응답을 주고받을 수 있습니다.
- 연결 설정에 따른 오버헤드를 줄이고 성능을 향상시킵니다.
예시
- 웹 페이지를 로딩할 때 HTML, CSS, JavaScript, 이미지 등 여러 리소스를 다운로드해야 합니다.
- 지속 연결을 사용하면 한 번의 연결로 모든 리소스를 주고받을 수 있습니다.
확인 문제
- 질문: HTTP/1.1에서 도입된 연결 방식으로, 한 번의 연결로 여러 요청과 응답을 주고받을 수 있게 한 것은 무엇인가요?
- 답변: 지속 연결(Persistent Connection)입니다.
HTTP 메시지
HTTP 통신은 요청 메시지와 응답 메시지를 통해 이루어집니다.
각 메시지는 일정한 구조를 가지고 있으며, 이 구조를 이해하는 것이 HTTP의 핵심입니다.
HTTP 메시지의 구조
- 시작줄(Start Line)
- 요청 메시지: 요청라인(Request Line)
- 응답 메시지: 상태라인(Status Line)
- 헤더(Header) 필드
- 요청 또는 응답에 대한 부가 정보를 포함.
- 공백 줄
- 헤더와 본문을 구분하는 빈 줄(CRLF).
- 본문(Body)
- 실제 전송할 데이터를 포함.
요청 메시지의 구조 예시
1
2
3
4
5
GET /search?q=HTTP HTTP/1.1
Host: www.example.com
User-Agent: Mozilla/5.0
Accept-Language: ko-KR
- GET: 메서드 (클라이언트가 서버에 요청하는 행위).
- /search?q=HTTP: 요청 대상(URI).
- HTTP/1.1: 사용 중인 HTTP 버전.
- Host, User-Agent, Accept-Language: 헤더 필드들.
- 공백 줄 이후에 메시지 바디가 올 수 있지만, GET 요청에서는 일반적으로 없음.
응답 메시지의 구조 예시
1
2
3
4
5
6
7
8
HTTP/1.1 200 OK
Content-Type: text/html; charset=UTF-8
Content-Length: 3423
<html>
<!-- HTML 내용 -->
</html>
- HTTP/1.1: 사용 중인 HTTP 버전.
- 200: 상태 코드 (요청 성공).
- OK: 상태 코드의 사유 구문(설명).
- Content-Type, Content-Length: 헤더 필드들.
- 공백 줄 이후에 메시지 바디로 HTML 문서가 전달됨.
시작줄(Start Line) 상세
요청라인(Request Line)
- 메서드(Method): 클라이언트가 서버에서 수행하고자 하는 동작.
- 예: GET, POST, PUT, DELETE, HEAD, OPTIONS 등.
- 요청 대상(Request Target): 요청하고자 하는 리소스의 경로.
- HTTP 버전: 사용 중인 HTTP의 버전 명시.
상태라인(Status Line)
- HTTP 버전: 사용 중인 HTTP의 버전.
- 상태 코드(Status Code): 요청에 대한 처리 결과를 숫자로 표시.
- 1xx: 정보 응답
- 2xx: 성공 (예: 200 OK)
- 3xx: 리다이렉션 (예: 301 Moved Permanently)
- 4xx: 클라이언트 오류 (예: 404 Not Found)
- 5xx: 서버 오류 (예: 500 Internal Server Error)
- 사유 구문(Reason Phrase): 상태 코드의 의미를 사람이 이해하기 쉽게 설명.
헤더(Header) 필드
- 구성: <필드 이름="">:<필드 값=""> 형식으로 구성.필드>필드>
- 역할: 메시지 바디에 대한 정보, 클라이언트 및 서버에 대한 정보, 요청 및 응답에 대한 부가 정보를 제공.
- 예시:
- Host: 요청하는 호스트 정보.
- Content-Type: 메시지 바디의 데이터 타입과 문자 인코딩 정보.
- Content-Length: 메시지 바디의 크기(바이트 단위).
- User-Agent: 클라이언트 애플리케이션 정보.
본문(Body)
- 역할: 실제 전송하고자 하는 데이터를 포함.
- 내용: HTML 문서, 이미지, JSON 데이터, 파일 등.
- 주의사항: 메시지 바디가 없을 수도 있음(예: GET 요청의 경우).
확인 문제
- 질문: HTTP 메시지는 어떤 구성 요소로 이루어져 있나요?
- 답변: 시작줄(Start Line), 헤더(Header) 필드, 공백 줄, 본문(Body)으로 이루어져 있습니다.
※ 참고: HTTP는 단순하지만 확장 가능한 프로토콜로, 현대 웹의 핵심을 이루고 있습니다.
각 구성 요소를 정확히 이해함으로써 웹 통신의 원리를 파악하고, 효율적인 웹 애플리케이션 개발이 가능합니다.