생각했으면 행동한다 GitHub

CS/네트워크

HyperText Transfer Protocol

현진용 2025. 10. 24. 15:11

시작


IT 관련 학부생이었다면 네트워크나 프로그래밍 관련 전공수업에서 HTTP는 무조건 들어봤을 것이다. 이번에는 지식을 견고히 하고 확장하는 차원에서 HTTP를 다뤄보려고 한다.

 

HTTP - HyperText Transfer Protocol


HTTP는 클라이언트와 서버가 데이터를 주고 받는 데에 사용되는 통신 규칙(Protocol)이다. 보통 클라이언트는 웹브라우저가, 서버는 웹 서버가 그 역할을 맡는다. 

그렇다면 클라이언트와 서버가 주고 받는 데이터란 무엇인가? 명칭에서 알 수 있듯, 하이퍼텍스트(HyperText)다. 하이퍼텍스트란, 문서 안의 다른 문서나 리소스로 연결되는 링크를 포함할 수 있도록 하는 구조화된 텍스트를 의미한다.

  • 비선형적 구조 : 일반적인 책이나 문서는 순서에 따라 읽지만 하이퍼텍스트는 링크를 따라 사용자가 원하는 순서대로 읽을 수 있다.
  • 연결성 : 링크를 통해 다른 웹사이트, 블로그, 이미지, 동영상 등 다양한 리소스로 이동할 수 있다.

이러한 하이퍼텍스트 문서를 만드는 게 HTML이라는 마크업 언어다.

Application Layer에서 동작하며, 80번 포트를 주로 사용한다.

 

출처 : geeksforgeeks

 

기본적으로 요청과 응답을 동작 원리로 하고 있다. 다시 말해서 다음과 같은 과정을 거쳐서 클라이언트가 하이퍼텍스트 문서를 가져온다.

  1. 클라이언트(웹 브라우저): 사용자가 웹 브라우저에 www.google.com을 입력하면, 브라우저는 "https://www.google.com 홈페이지를 보여줘!"라는 HTTP 요청 메시지를 만들어 웹 서버로 보낸다.
  2. 서버(웹 서버): 서버는 이 요청을 받고, "알겠어, 여기 홈페이지 데이터(HTML, 이미지 등)야!"라며 HTTP 응답 메시지를 만들어 다시 브라우저에게 돌려준다.

개발자라면 기본으로 숙지하고 있을 내용이다. 물론 여기서 더 깊게 파고들면 DNS 쿼리, 참조모델 별 데이터 캡슐화 과정, 서브넷 마스크, ARP 등등 다룰 게 많지만 오늘은 HTTP가 주인공이니 이를 중점적으로 보자!

 

HTTP 메세지 구조


동작 원리는 알겠다. 이번에는 HTTP를 통해 주고 받는 메세지의 구조를 살펴보자.

요청 메세지 - Request

다음은 클라이언트가 서버에게 보내는 메세지의 구조다. 하나씩 차근차근 짚어보자.

GET / HTTP/1.1                <-- 1. Start Line
Host: www.google.com          <-- 2. Headers
User-Agent: Chrome/100.0
Accept: text/html

(여기는 비어 있음)               <-- 3. Body

 

1. Start line

GET은 Method다. 아래에서 설명하겠지만 서버에게 무엇을 할지 알려준다. 이 GET은 어떤 자원을 달라는 의미다.

/(슬래쉬)는 요청 자원(URI)이라고 한다. 서버에게 어떤 자원을 원하는지 알려준다. 보통 /는 인덱스, 즉 메인 페이지를 의미한다.

HTTP/1.1는 보면 알 수 있듯이 HTTP의 버전이다. 이 또한 아래에서 다룰 예정이다.

2. Headers

헤더는 부가 정보는 담은 부분이다. 키-값 형태로 되어있다.

Host: www.google.com 은 어느 서버에 요청하는 건지 나타낸다. 여기서는 구글 서버에 요청하는 것이다.

User-Agent: ... 는 누가 요청하는지 명시한다. 여기선 브라우저 정보라고 생각하면 된다.

Accept: text/html 는 클라이언트가 어떤 형식의 응답을 받을 수 있는지 명시한다. 여기서는 Text / html을 응답으로 받을 수 있음을 알 수 있다.

3. Body

GET 요청은 비어 있어야 한다. 실제로 개발을 시작한 지 얼마 되지 않았을 때 GET 요청에 Request Body를 채워보낸 적이 있었는데 동작하지 않아서 어리둥절했었다. 나중에 알고보니 설계 원칙과 기존 특성에 위배돼서 실제 테스트에서 동작하지 않는 것이었다. GET 자체가 멱등성을 보장해야 하는데 body가 있다는 것만으로 멱등성을 지킬 수 없으니 그럴 수 있다.

다만 Post나 Put 요청 시에는 본문이 채워지기도 한다.

 

응답 메세지 - Response

HTTP/1.1 200 OK               <-- 1. Status Line
Content-Type: text/html       <-- 2. Headers
Content-Length: 15000

<html>...</html>              <-- 3. Body

1. Status Line

HTTP/1.1는 버전이라는 것을 이젠 알 것이다.

200은 상태코드(status code)다. 요청을 처리한 결과를 해당 상태메세지와 함께 숫자로 알려주는 것이다. 200는 OK와 함께 성공을 의미한다.

2. Headers

Content-Type: text/html 은 서버가 보낸 본문의 형식이 HTML이라는 의미다.

Content-Length: 15000 은 본문의 길이가 15000Bytes라는 의미다. 

3. Body

클라이언트가 요청한 실제 데이터다. 여기선 HTML 문서를 요청했으니 HTML 코드가 여기에 담긴다. 이미지를 요청했으면 이미지 데이터가, API를 요청했으면 JSON데이터가 담긴다.

 

HTTP 요소


HTTP 메서드

메서드는 클라이언트가 서버에게 무엇을 하길 원하는 알리는 것이라고 했다. 동사의 의미다. 메소드의 종류가 뭐가 있는지 보겠다!

  • GET (조회: Read)
    • 서버에게 특정 데이터를 달라고 요청한다.
    • 가장 흔하게 사용되며, 웹페이지를 보거나 이미지를 로드할 때 사용된다.
    • 여러 번 요청해도 결과가 같다 (멱등성)
    • 예: www.example.com/users/123 (123번 사용자 정보 조회)
  • POST (생성: Create)
    • 서버에게 새로운 데이터를 만들라고 요청한다.
    • 회원가입, 게시글 작성, 로그인 시 ID/PW 전송 등에 사용된다.
    • 요청할 때마다 새로운 데이터가 생성될 수 있다. (멱등성 X)
    • 예: www.example.com/posts (새 게시글 데이터와 함께 전송)
  • PUT (전체 수정: Update)
    • 서버의 특정 데이터를 통째로 덮어쓰라고 요청한다.
    • 회원 정보 전체를 수정할 때 사용될 수 있다.
    • 여러 번 요청해도 결과가 같다 (멱등성).
    • 예: www.example.com/users/123 (123번 사용자의 정보를 새 정보로 완전히 교체)
  • PATCH (부분 수정: Update)
    • 서버의 특정 데이터 중 일부만 수정하라고 요청한다.
    • PUT이 전체를 덮어쓴다면, PATCH는 바꿀 부분만 보낸다. (예: 닉네임만 변경)
    • 멱등성이 보장되지 않을 수 있다.
    • 예: www.example.com/users/123 (123번 사용자의 닉네임만 변경)
  • DELETE (삭제: Delete)
    • 서버의 특정 데이터를 삭제하라고 요청한다.
    • 게시글 삭제, 회원 탈퇴 등에 사용된다.
    • 여러 번 요청해도 결과가 같다 (멱등성).
    • 예: www.example.com/posts/456 (456번 게시글 삭제)

 

HTTP 상태코드(Status Code)

서버가 요청을 처리한 결과를 숫자로 알려주는 신호다. 보통 아래와 같이 사용하지만 상황에 따라서는 완전히 다른 상태 코드를 사용할 수도 있다.

2xx

요청의 성공적인 처리를 의미한다.

 

  • 200 OK
    • 가장 일반적인 성공 응답입니다. GET 요청 등이 성공했을 때 받는다.
  • 201 Created
    • POST 또는 PUT 요청에 대한 응답으로, 새로운 리소스가 성공적으로 생성되었음을 의미한다.

 

3xx 

요청을 완료하기 위해서는 추가적인 동작이 필요함(리다이렉션, Redirection)을 의미한다.

 

  • 301 Moved Permanently
    • 요청한 리소스의 주소가 영구적으로 변경되었다.
  • 302 Found
    • 리소스가 일시적으로 다른 주소에 있다.

4xx

클라이언트 측에서 문제가 있음을 의미한다.

 

  • 400 Bad Request
    • 서버가 요청의 문법을 이해할 수 없다. (예: 파라미터를 잘못 보냄)
  • 401 Unauthorized
    • 요청자가 로그인(인증)이 필요하다.

5xx

서버 측의 문제로 요청 처리에 실패했음을 의미한다.

 

  • 500 Internal Server Error
    • 서버에서 코드를 실행하다가 예상치 못한 오류가 발생했다.
  • 503 Service Unavailable
    • 서버가 과부하에 걸렸거나 점검 중이라서 일시적으로 요청을 처리할 수 없다.

 

 

 

 

HTTP 버전


HTTP의 역사에 대해 작성하면 글이 너무 길어지니 여기서는 현재 표준으로 사용중인 1.1 버전부터 3 버전까지만 다루려고 한다.

 

HTTP 1.1


1.0 버전의 치명적인 문제를 해결하고 현재까지 표준으로 널리 사용중인 버전이다.

지속적인 연결

1.0 버전은 요청 1건 당 1개의 TCP 연결을 맺고 끊는 비효율적인 방식이었다. 현재 트래픽이 많이 발생한다 싶은 서비스는 초당 수만 건의 요청이 생기는데 그렇다면 TCP 연결 작업을 초당 수만 번 이상 반복하는 건데 말만 들어도 비효율적임을 알 수 있다.

1.1 버전에서는 TCP 연결을 한 번 맺으면 재사용(Keep-Alive라 한다)하여 여러 리소스를 동일한 연결을 통해 받아오도록 하였다. 이를 통해 성능을 크게 향상시켰다.

HOL Blocking (Head of Line)

1.1의 큰 한계점으로 지적받는다. 연결을 재사용하지만 통신 방식이 순차적이다. 무슨 의미냐 하면, 요청을 순서대로 보냈으면 반드시 응답도 순서대로 받아야 한다는 의미다. 예를 들어, 카페에서 주문이 3개 이상 밀려 있는데 2,3번 주문이 완료되었음에도 불구하고 1번 주문이 완료될 때까지 2,3번 주문은 나가지 못한다.

 

HTTP 2


HOOL Blocking 문제를 해결하기 위해 만들어졌다.

멀티플렉싱 Multiplexing

하나의 TCP 연결 안에서 여러 개 독립된 Stream을 만들어서 요청과 응답의 순서에 상관없이 동시에 주고 받을 수 있게 됐다.

바이너리 프로토콜

1.1은 텍스트 기반이다. 2부터는 0과 1의 바이너리(기계어)를 기반으로 데이터를 파싱하여 속도가 빠르고 오류가 적다.

헤더 압축 HPACK

쿠키와 같은 중복되는 헤더를 압축하여 전송 데이터 양을 획기적으로 줄일 수 있게 됐다.

TCP 수준의 HOL Blocking

HTTP(애플리케이션 계층)의 HOL 문제는 해결했지만, TCP(전송 계층)의 HOL은 여전히 존재한다. TCP는 UDP와 다르게 들어오는 패킷의 순서를 보장한다. 네트워크 문제로 인해 패킷 1개가 유실되거나 하면 TCP는 해당 패킷이 재전송될 때까지 모든 스트림의 전송을 중단시켜버린다.

 

HTTP 3


TCP 수준의 HOL 문제를 해결하기 위해 TCP에서 UDP로 바꾼 최신 버전이다.

QUIC 프로토콜

3 버전은 UDP 기반의 QUIC 프로토콜 위에서 동작한다. QUIC 프로토콜은 UDP의 속도와 독자적으로 구현한 TCP의 신뢰성(패킷 재전송)을 갖추고 있다.

위와 같은 장점으로 인해 각 Stream이 완전히 독립적으로 처리된다. 한 스트림에서 이미지의 패킷 일부가 유실돼도, 텍스트를 다루는 다른 스트림에서는 멈추지 않고 계속 전송된다.

빠른 연결 

기존에는 TCP 연결과 TLS 핸드셰이크 과정이 각각 있었다. 이 부분에서 오는 성능 저하도 분명히 있었다. 3 버전에서는 이를 하나로 통합하여 연결에 걸리는 시간(RTT)을 획기적으로 줄였다. 특히 핑이 불안정한 모바일 네트워크 환경에서 강력한 성능을 보인다고 한다.

 

생각


곧 개인 프로젝트를 하나 시작하려고 한다. 지금껏 모든 프로젝트를 팀 단위로만 진행해왔다. 스스로의 역량을 확인하고 더 높이기 위해 진행해야겠다고 생각했다. 최소한의 인프라 조건에서 최대 성능을 내보는 것이 목표다. 이를 이루기 위해서는 연관된 기술을 이해하는 것이 중요하다.

HTTP를 사용하고 있다는 것을 인지하고 있었지만 막상 무엇인지 감이 잘 안 잡혔던 것 같다. 이번 기회에 확실히 알아가서 다행이다. HTTPS는 추후 SSL/TLS와 함께 다루려고 한다!

 

반응형

'CS > 네트워크' 카테고리의 다른 글

DHCP  (0) 2025.09.30
네트워크 - 소켓, 리눅스 네트워크 관리  (0) 2025.03.13
네트워크  (1) 2025.03.11
네트워크 프로그래밍  (1) 2023.08.31
네트워크(11) - 전송층  (0) 2023.06.14