🚨(스포주의) HTTP 몰아보기 (결말포함)

2026. 2. 24. 22:32·CS/Web 이론

What is HTTP?

HTTP는 서버와 클라이언트가 데이터를 주고받는 통신 규약이다. 0과 1의 비트 배열로 변환할 수 있다면, 텍스트, 이미지, 영상, 음성 어떤 형태의 데이터든 전송이 가능하다. 우리가 웹사이트에 접속할 때, 앞에 http가 붙는 것을 볼 수 있는데, HTTP를 이용해 통신하겠다는 뜻이다. HTTP에서 보안을 더하면 HTTPS가 되는데 이건 다른 게시글에서 설명하겠다. HTTP의 핵심 특징은 두가지가 있는데, 처음엔 장점으로 작용하였으나 향후 특정상황에서 단점으로 작용하기도 하였다.

 

  • HTTP는 자원 절약을 위해 전송이 끝나면 연결을 끊는다.
  • HTTP는 이전 상태를 저장하지 않는다. (우리가 쿠키와 세션을 사용하는 이유)

 

사실 이런 특징들은 HTTP가 만들어질 상황에선 불가피한 선택이었다. 당시 과학자들이 쉽게 자료를 공유하기 위해 Web을 만들면서 누구나, 어떤 기기에서 접근할 수 있도록 만들어졌기 때문이다.


HTTP의 구조

HTTP는 철저하게 요청(Request)과 응답(Response)의 구조로 이루어져 있다. 구조 자체는 요청과 응답 둘 다 다음과 같고 요청인지 응답인지에 따라 안에 담기는 내용이 달라진다.

 

  1. 시작 줄 (Start Line)
  2. 헤더 (Headers) 
  3. 공백 라인 (Empty Line)
  4. 본문 (body)

 

HTTP 요청 (Request)

HTTP 요청 시 안에 담기는 내용들은 다음과 같다.

구성 요소 주요 내용 예시 (GET 요청)
시작 줄 (Start Line) HTTP 메서드, 요청 타겟(경로), HTTP 버전 GET /index.html HTTP/2.0
헤더 (Headers) 서버에 전달하는 추가 메타데이터 (호스트, 브라우저 정보 등) Host: www.example1.com
공백 라인 (Empty Line) 헤더와 본문을 구분하는 필수 빈 줄 -
본문 (Body) 서버로 보낼 실제 데이터 (POST/PUT 시 사용) {"id": "user123"} (JSON 등)

 

시작 줄에는 메서드, 경로, 버전으로 3가지 정보가 담겨진다. HTTP 메서드는 곧 다룰 거긴 한데, 지금은 간단히 데이터를 요청해서 얻는다고 생각하면 된다. HTTP 버전에 대해서 이따가 자세히 설명하겠다.

 

헤더에서 요청 내용에 대한 메타데이터를 전달한다. 쿠키나 토큰도 여기에 포함된다.

 

본문에는 서버로 보낼 실제 데이터를 담는다. 예를 들어 로그인을 한다고 하면 로그인 할 때 입력한 아이디와 비밀번호의 실제 값은 본문에 담아서 보내게 된다.

헤더와 본문을 왜 나눠야할까?

이런 의문이 든다면, 택배를 생각해보면 쉽다. 택배를 분류 및 운반할 때 굳이 택배를 열어서 확인해보지 않는다. 이게 어디로 가는지 안에 어떤 내용물이 담겨져 있으니 어떻게 주의해야할지 송장을 보고 바로바로 알 수 있기 때문이다. 서버도 마찬가지다. 하루에도 수많은 요청을 처리하는데 내용을 일일히 다 확인해볼 수는 없다. 게다가 최대 처리 가능한 용량이 10MB인데 1GB짜리 정보를 누군가가 보내려 한다면, 헤더의 파일 크기만 보고도 즉시 연결을 끊을 수 있다. 속도도 빠르고 자원도 아끼는 셈이다.

 

예시는 다음과 같다.

POST /api/login HTTP/2.0
Host: www.example1.com
Content-Type: application/json  
Content-Length: 45            

{
  "userId": "gemini_user",     
  "password": "secret_password"
}

 

HTTP 응답 (Response)

전체적인 구조는 같지만 겹치는 내용이 거의 없다.

구성 요소 주요 내용 예시 (GET 요청)
시작 줄 (Start Line) HTTP 버전, 상태 코드, 상태 문구 HTTP/2.0 200 OK
헤더 (Headers) 응답 데이터 정보, 서버 정보, 보안 설정 등 Content-Type: text/html
공백 라인 (Empty Line) 헤더와 본문을 구분하는 필수 빈 줄 -
본문 (Body) 서버로 보내주는 실제 데이터 (HTML 등) <html> ... </html>

 

요청 때와 같은 정보가 들어 있는 게 HTTP 버전 밖에 없다. 상태 코드와 문구에 대해서는 이따가 자세히 설명하겠다.

 

예시는 다음과 같다.

HTTP/2.0 200 OK               
Content-Type: application/json


{
  "message": "로그인에 성공했습니다!", 
  "lastLogin": "2026-02-24"
}

HTTP 메서드

HTTP 메서드는 해당 자원을 어떻게 하고 싶은지를 나타내는 라벨이라고 생각하면 된다. 총 9개로 이루어져 있지만, 진하게 표시한 5개를 주로 많이 쓴다.

 

  1. GET
  2. POST
  3. PUT
  4. PATCH
  5. DELETE
  6. HEAD
  7. OPTIONS
  8. CONNECT
  9. TRACE

 

HEAD는 헤더만 받을 때, OPTIONS는 서버가 해당 메서드를 지원하는지 확인할 때, CONNECT는 통신하는 통로를 만들 때, TRACE는 디버깅 할 때 각각 사용하지만 TRACE는 보안상의 이유로 기능을 거의 꺼둔다.

 

HTTP 메서드에서는 안정성과 멱등성이라는 중요한 두 개념이 있는데, 안정성은 호출해도 서버의 데이터가 변하지 않는 속성이고, 멱등성은 한 번 호출하나 50번 호출하나 100번 호출하나 결과가 항상 같은 속성을 말한다.

 

GET

GET은 말 그대로 데이터를 요청해서 얻는 것이다. 요청할 때 Body가 없고(당연함) 안정성과 멱등성 모두를 갖고 있다.

Body가 없는데 무엇을 요청할지 어떻게 알지?

이런 의문이 생길 수도 있다. HTTP 요청에선 시작줄에서 메서드와 함께 경로를 요청하기 때문에 Body나 Header에 무엇을 요청할지  내용이 없어도 경로를 통해 알 수 있다.

 

POST

POST는 서버에 새로운 데이터를 넣을 때 사용한다. 이 한 문장에서 느껴지겠지만, 안정성도 멱등성도 갖지 않는다. 특이한 것은 단순히 새로운 리소스를 생성하는 것 말고 컨트롤러 역할을 하여 복잡한 로직을 수행하기도 한다.

 

눈치가 빨랐으면 위에서 로그인이 POST로 요청된 것을 알아챘을 것이다. 회원가입이 POST인 것은 당연하지만, 로그인은 왜 POST로 요청하는 것일까? 이것이 복잡한 로직을 수행하는 예시이다. 로그인은 다음과 같은 과정을 거친다.

 

  1. DB에서 계정(ID)을 찾는다.
  2. 암호화된 비밀번호를 비교한다. (복호화 하는 거 아님) 
  3. 세션이나 토큰을 생성한다.
  4. 로그인 기록을 저장한다.

 

3번의 이유로 POST를 사용하는 것이다. 이 외에도 결제 처리나 대량 메일 전송 등에도 이용된다고 한다.

 

PUT vs PATCH

둘 다 데이터를 수정하는 것이긴 한데, 차이가 있다.

 

PUT은 사전적으로 '놓다'의 의미를 가지고 있다. 즉 해당 필드 위에 새 필드를 놓는다고 생각하면 쉽다. 필드가 없다면 새로 만들고, 있다면 전체를 다 교체하는 기능을 한다. 멱등성은 갖지만 안정성은 갖지 않는다.

 

PATCH는 '덧대는 천'이나 '조각'이라는 뜻을 갖고 있듯이 일부분만 수정하는 것을 의미한다. 게임할 때도 패치한다고 하면 게임 전체를 다른 게임으로 바꾸는 게 아니라 게임 캐릭터 하나를 고치는 식으로 수정한다. 마찬가지로 안정성은 갖지 않는다. 하지만, 멱등성은 가질 수도 안 가질 수도 있다. (나이를 30살로 설정해줘와 +1해줘의 차이)

 

예를 들어 한 유저에 대해 PUT을 호출한다고 하면 그 유저가 아예 다른 유저로 교체되는 것이고, PATCH를 호출한다고 하면 해당 유저의 닉네임만 바꾼다고 생각하면 된다. 

 

DELETE

서버의 데이터를 삭제할 때 사용한다. 이름에서도 느껴지겠지만 안정성을 갖지는 않지만, 멱등성은 갖는다. 


HTTP 상태 코드

HTTP 호출의 결과를 간단하게 알려주는 코드이다. 그 유명한 404가 여기서 나왔다. 상태 코드는 1xx ~ 5xx로 나누어져 있고 제일 앞 숫자에 따라 카테고리가 나누어진다.

범위 의미
1xx 정보 (Informational)
2xx 성공 (Successful)
3xx 리다이렉션 (Redirection)
4xx 클라이언트 오류 (Client Error)
5xx 서버 오류 (Server Error)

 

진하게 표시한 친구들이 자주 보게 될 코드이다.

 

2xx - 성공

200 OK - 요청이 성공적으로 되었습니다. 성공의 의미는 HTTP 메소드에 따라 달라진다.

201 Created - 요청이 성공적이었으며 그 결과로 새로운 리소스가 생성되었습니다. 이 응답은 일반적으로 POST 요청 또는 일부 PUT 요청 이후에 따라온다.

 

3xx - 리다이렉션

리다이렉션은 자동으로 사용자를 이전한 새 페이지로 보내버린다. 그렇다면 왜 리다이렉션을 사용핳까? 그것은 즐겨찾기를 생각하면 된다. 기존에 즐겨찾기로 웹페이지에 접속하는 사용자들을 놓치지 않기 위해서 사용한다. 또 http로 들어온 사람을 강제로 https로 끌고 갈 수도 있다.

 

301 Moved Permanently - 요청한 자원이 영구적으로 새 주소로 옮겨졌다. (자동으로 새 주소 이동)

302 Found - 잠시 다른 주소에 있다.

 

4xx - 클라이언트 오류

400 Bead Request - 요청이 잘못됐다.

401 Unauthorized - 로그인이 안 되어 있어서 권한이 없는 것이다.

403 Forbidden - 로그인이 되어 있어도 권한이 없다.

404 Not Found - 요청한 주소를 찾을 수 없다.

 

5xx - 서버 오류

500 Internal Server Error - 서버 내부에서 알 수 없는 에러가 발생했다. 이게 나오면 대부분 개발하면서 실수한 경우..

503 Service Unavailable - 서버가 과부하 걸렸거나 점검 중이다.

 


HTTP의 역사

  • HTTP/0.9
    1. 최초의 버전이다.
    2. 헤더가 없다. (그래서 HTML 파일만 전송 가능)
    3. GET 메서드만 지원한다.
  • HTTP/1.0
    1. 요청 헤더에 HTTP 버전이 생겼다.
    2. 응답 헤더에는 content-type이 생겨서 html 외 형태의 파일도 전송이 가능해졌다.
    3. 연결 한 번에 하나의 요청만 처리 가능하다. 매번 새롭게 연결해야 한다.
    4. TCP를 사용하기 시작했다.
  • HTTP/1.1
    1. 현재 가장 많이 사용되는 버전이다.
    2. 우리가 아는 대부분의 기능이 여기서 구현됐다.
    3. 이 후에는 성능 개선을 업데이트 됐다.
  • SPDY 
    1.  Google이 1.1의 성능을 개선하기 위해 만들었다.
    2. 후에 HTTP/2.0에 흡수되었다.
  • HTTP/2.0
    1. 헤더 압축으로 데이터 크기 감소되었다.
    2. 서버 푸시로 서버가 필요한 리소스를 미리 보내기 시작했다.
    3. 멀티 플렉싱을 통해 줄서기 문제를 해결했다.
    4. 2.0부터는 HTTPS가 강제된다.
  • HTTP/3.0
    1. TCP의 한계로 인해 UDP 기반의 QUIC 프로토콜을 도입했다.

 

왜 2.0, 3.0보다 1.1이 더 많이 사용될까?

윈도우도 신버전이 나오자마자 사람들이 새로운 버전으로 갈아타지 않는다. 호환성의 문제도 있고, 굳이 지금도 잘 작동하는데 돈을 내고 버전을 업그레이드 할 필요는 없는 것과 마찬가지로 HTTP도 그렇다. 1.1에서 이미 많은 웹 서비스들이 출시되었고 단순한 서비스에서는 1.1로도 충분했다. 굳이 고쳐 쓸 필요가 없다. 게다가 HTTPS 강제되기 때문에 개발의 난이도도 상승한다. 한마디로 기술의 관성이다.

 


HTTP/1.1

현재 가장 많이 사용되고 있는 HTTP 버전이다. 20년 이상의 전통을 유지하고 있다. 대부분의 기능이 1.1에서 추가되어다고 생각하면 된다. 1.0에서부터 TCP가 사용되기 시작했는데, HTTP의 비연결성으로 인해 데이터를 한번 주고 받을 때마다 매번 TCP를 끊었다 연결했다 해야하는 번거로움이 있었다. 1.1로 넘어오면서  Connection: Kepp-alive를 통해 TCP 연결을 잠시 지속하면서 이러한 문제를 해결했다.

 

HTTP는 무상태성인데 어떻게 연결을 확인하고 지속하지?

연결을 유지하고 있는 주체는 사실 TCP다. HTTP와 TCP는 계층이 다르다. TCP는 HTTP보다 하위 계층이다. 메세지를 보내는 사용자끼리는 소통하지 않지만, 그 통로를 만든 기술자들끼리는 소통한다고 생각하면 된다.

 

파이프라이닝이라는 기법을 통해 1번 요청의 응답이 오기 전에 2번 요청, 3번 요청을 미리 던지는 방법도 사용됐지만, 어차피 서버는 순서대로 응답을 할 수 밖에 없기 때문에 1번 응답이 늦어지면 결국 2번, 번도 늦어지는 HOLB(Head-of-Line Blocking)문제가 여전했기 때문에 사실상 사장되었다.

 

외에도 호스트 헤더의 의무화, 상태 코드의 다양화, 청크 인코딩 등의 변동사항이 있었다.

'CS > Web 이론' 카테고리의 다른 글

🌐HTTP가 여러 개면 HTTPS?  (0) 2026.02.25
'CS/Web 이론' 카테고리의 다른 글
  • 🌐HTTP가 여러 개면 HTTPS?
asht1124
asht1124
DEV blog
  • asht1124
    ASHT
    asht1124
  • 전체
    오늘
    어제
    • 분류 전체보기 (18)
      • 프런트엔드 (0)
      • 백엔드 (0)
        • Sping (0)
      • Dev-ops (0)
      • CS (18)
        • Web 이론 (2)
        • 보안 (1)
        • DB (4)
        • 네트워크 (3)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    멀티 프로세스
    2NF
    데이터 무결성
    보안
    API
    정규화
    멀티 스레드
    4-way handshake
    인터페이스
    REST API
    acid
    rdb
    프로토콜
    프로세스
    rest
    BCNF
    스레드
    비대칭키
    RESTful API
    3NF
    PCB
    tcb
    3-way handshake
    비밀키
    nosql
    OAS
    tcp
    1NF
    http
    반정규화
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.6
asht1124
🚨(스포주의) HTTP 몰아보기 (결말포함)
상단으로

티스토리툴바