앞에서 DNS가 도메인 이름을 IP 주소로 바꾸는 과정을 알아봤다.

사용자가 브라우저에 웹사이트 주소를 입력하면 DNS를 통해 서버의 IP 주소를 확인하고, 그다음 실제 서버와 통신을 시작한다.

그런데 IP 주소를 알아냈다고 해서 웹페이지가 바로 화면에 나타나는 것은 아니다.

서버에 어떤 페이지가 필요한지 알려줘야 하고, 서버 역시 요청받은 결과를 다시 브라우저에 보내줘야 한다.

이때 사용되는 대표적인 애플리케이션 계층 프로토콜이 HTTP(HyperText Transfer Protocol)​다.

흐름을 아주 단순하게 표현하면 다음과 같다.

브라우저
   │
   │ HTTP Request
   ▼
웹 서버
   │
   │ HTTP Response
   ▼
브라우저

브라우저가 “이 페이지를 주세요.”​라고 요청하면 서버가 “여기 있습니다.”​라고 응답하는 구조라고 생각하면 된다.

하지만 실제 HTTP 통신에는 요청 방법, 주소, 헤더, 데이터, 상태 코드 등 다양한 정보가 포함된다.

이번 글에서는 HTTP 요청과 응답이 실제로 어떤 구조로 이루어져 있고, 브라우저와 서버 사이에서 어떻게 오가는지 살펴보자.


HTTP는 무엇을 위한 프로토콜일까?

HTTP는 웹에서 데이터를 주고받기 위한 통신 규칙이다.

웹 브라우저와 웹 서버가 서로 다른 프로그램이라고 생각해보자.

브라우저는 서버에게 어떤 형식으로 요청을 보내야 하는지 알아야 하고, 서버 역시 브라우저가 이해할 수 있는 방식으로 응답해야 한다.

이런 서로 간의 약속을 정해놓은 것이 HTTP다.

예를 들어 브라우저가 서버에 다음과 같이 요청할 수 있다.

GET /index.html HTTP/1.1
Host: example.com

서버는 이에 대해 다음과 같이 응답할 수 있다.

HTTP/1.1 200 OK
Content-Type: text/html

<html>
    ...
</html>

처음 보면 복잡해 보이지만 구조를 나눠서 보면 어렵지 않다.

HTTP Request
→ 클라이언트가 서버에 보내는 요청

HTTP Response
→ 서버가 클라이언트에게 보내는 응답

HTTP 통신은 요청과 응답으로 이루어진다

HTTP의 가장 기본적인 구조는 Request → Response다.

Client                         Server
  │                              │
  │──── HTTP Request ───────────>│
  │                              │
  │                              │ 요청 처리
  │                              │
  │<─── HTTP Response ───────────│
  │                              │

여기서 중요한 것은 서버가 먼저 웹페이지를 보내는 것이 아니라는 점이다.

일반적인 HTTP 통신에서는 클라이언트가 먼저 요청을 보내고 서버가 그 요청에 대한 응답을 반환한다.

예를 들어 사용자가 브라우저에서

https://example.com

에 접속한다고 해보자.

브라우저는 먼저 서버와 통신할 준비를 한 뒤 HTTP 요청을 보낸다.

GET / HTTP/1.1
Host: example.com

서버는 요청을 확인하고 결과를 만들어 응답한다.

HTTP/1.1 200 OK

<html>
...
</html>

이것이 웹 통신의 기본적인 형태다.


HTTP Request에는 무엇이 들어갈까?

HTTP 요청에는 서버가 요청을 이해하는 데 필요한 여러 정보가 들어간다.

대표적으로 다음과 같은 요소가 있다.

Request Line
Headers
Blank Line
Body

간단한 구조를 보면 다음과 같다.

GET /index.html HTTP/1.1
Host: example.com
User-Agent: Chrome
Accept: text/html

각 부분을 살펴보자.


1. Request Line

첫 번째 줄에는 요청의 핵심 정보가 들어간다.

GET /index.html HTTP/1.1

여기에는 크게 세 가지가 있다.

GET
/index.html
HTTP/1.1

각각을 보면

GET
→ 어떤 작업을 할 것인지

/index.html
→ 어떤 리소스를 요청하는지

HTTP/1.1
→ 어떤 HTTP 버전을 사용하는지

를 나타낸다.

여기서 GET은 웹에서 가장 흔하게 볼 수 있는 HTTP 메서드 중 하나다.


HTTP Method는 요청의 목적을 나타낸다

HTTP에서는 요청의 목적에 따라 여러 메서드를 사용할 수 있다.

대표적인 것은 다음과 같다.

Method일반적인 용도
GET데이터 조회
POST데이터 생성 또는 전달
PUT데이터 전체 수정
PATCH데이터 일부 수정
DELETE데이터 삭제

예를 들어 게시판에서 글을 조회한다고 생각하면

GET /posts/10

과 같은 요청을 사용할 수 있다.

새로운 글을 등록한다면

POST /posts

와 같은 요청을 사용할 수 있다.

중요한 것은 HTTP 메서드가 “서버에서 반드시 이렇게 처리해야 한다”는 구현 자체를 강제하는 것은 아니라는 점​이다.

웹 애플리케이션이 해당 메서드를 어떤 방식으로 처리할지는 서버 프로그램의 구현에 따라 달라진다.


2. HTTP Header

Request Line 다음에는 HTTP Header가 나온다.

헤더에는 요청에 대한 추가 정보가 들어간다.

예를 들어

Host: example.com
User-Agent: Chrome
Accept: text/html

처럼 작성할 수 있다.

대표적인 헤더를 보면 다음과 같다.

Header의미
Host요청 대상 호스트
User-Agent클라이언트 프로그램 정보
Accept원하는 응답 데이터 형식
Content-Type요청 본문의 데이터 형식
Content-Length본문의 크기
Authorization인증 정보 전달에 사용

특히 Host는 하나의 서버가 여러 도메인을 서비스하는 환경에서 중요한 역할을 한다.

예를 들어 하나의 서버 IP에서

example.com
shop.example.com
api.example.com

같은 여러 도메인을 운영할 수도 있다.

HTTP 요청의 Host 정보를 통해 서버는 어떤 호스트를 대상으로 요청했는지 판단할 수 있다.


3. HTTP Body

HTTP 요청에는 필요에 따라 Body가 들어간다.

특히 POST, PUT, PATCH 같은 요청에서 데이터를 서버로 전달할 때 많이 사용한다.

예를 들어 회원가입 요청이라면 다음과 같은 데이터를 보낼 수 있다.

POST /users HTTP/1.1
Host: example.com
Content-Type: application/json

{
    "name": "Kim",
    "email": "user@example.com"
}

여기서 JSON 데이터가 HTTP Body에 해당한다.

즉 HTTP 요청은 단순히

"페이지 주세요."

만 보내는 것이 아니라,

어떤 작업인지
어떤 리소스인지
클라이언트가 어떤 환경인지
어떤 데이터를 보내는지

등을 함께 전달할 수 있다.


HTTP Response는 어떻게 생겼을까?

서버가 요청을 처리하면 HTTP Response를 만들어 클라이언트에게 전달한다.

기본적인 구조는 다음과 같다.

Status Line
Headers
Blank Line
Body

예를 들어 서버가 정상적으로 HTML 페이지를 반환한다면 다음과 같은 응답이 가능하다.

HTTP/1.1 200 OK
Content-Type: text/html
Content-Length: 1250

<html>
    <body>
        Hello World
    </body>
</html>

여기서 가장 먼저 확인할 부분이 200 OK다.

이것은 서버가 요청을 정상적으로 처리했다는 의미다.


Response의 상태 코드는 무엇일까?

HTTP Response에는 상태 코드(Status Code)​가 들어간다.

예를 들어

200
404
500

같은 숫자를 본 적이 있을 것이다.

이 숫자는 서버가 요청을 어떻게 처리했는지를 알려준다.

대표적으로

2xx → 성공
3xx → 리다이렉션
4xx → 클라이언트 측 요청 문제
5xx → 서버 측 문제

로 구분한다.

예를 들어

200 OK

는 정상 처리,

404 Not Found

는 요청한 리소스를 찾지 못했다는 의미다.

500 Internal Server Error

는 서버 내부에서 오류가 발생했다는 의미다.

상태 코드는 종류가 상당히 많기 때문에 다음 글에서 따로 자세하게 살펴볼 예정이다.


Response Header도 중요한 역할을 한다

응답에도 Header가 포함된다.

예를 들어

Content-Type: text/html
Content-Length: 1250
Cache-Control: max-age=3600
Set-Cookie: session=abc123

등의 정보를 서버가 보낼 수 있다.

여기서 Content-Type은 특히 중요하다.

예를 들어

Content-Type: text/html

이라면 HTML 데이터라는 의미이고,

Content-Type: application/json

이라면 JSON 데이터라는 의미다.

브라우저나 애플리케이션은 이런 정보를 참고해서 받은 데이터를 어떻게 처리할지 판단한다.


실제 웹사이트 접속 과정을 연결해보자

이제 앞에서 배운 내용을 모두 연결해보자.

사용자가 브라우저에

https://example.com

을 입력했다고 가정한다.

1. 도메인 확인

먼저 DNS를 통해 도메인의 IP 주소를 확인한다.

example.com
      ↓
DNS
      ↓
203.0.113.10

2. 서버와 연결

HTTP를 전송하기 위한 네트워크 연결을 준비한다.

HTTP/1.1이나 HTTP/2처럼 TCP를 사용하는 경우에는 TCP 연결이 만들어진다.

HTTPS라면 그 위에서 TLS 연결도 진행된다.

DNS
 ↓
IP 주소
 ↓
TCP 연결
 ↓
TLS 연결

HTTP/3을 사용하는 경우에는 QUIC을 이용하기 때문에 전통적인 TCP 연결 과정과는 다르다.


3. 브라우저가 HTTP Request를 보낸다

연결이 준비되면 브라우저가 서버에 요청을 보낸다.

GET / HTTP/1.1
Host: example.com
Accept: text/html

서버는 이 요청을 받아 어떤 리소스를 요청했는지 확인한다.


4. 서버가 요청을 처리한다

서버에서는 요청에 따라 다양한 작업이 수행될 수 있다.

정적인 HTML 파일을 읽을 수도 있고,

GET /index.html
       ↓
HTML 파일 반환

데이터베이스를 조회할 수도 있다.

GET /products/10
       ↓
웹 서버
       ↓
DB 조회
       ↓
상품 정보 생성

로그인이나 결제 같은 작업에서는 더 복잡한 서버 로직이 실행될 수도 있다.

HTTP 자체는 이런 내부 처리를 직접 결정하지 않는다.

HTTP는 기본적으로 클라이언트와 서버가 데이터를 어떤 형식으로 주고받을지에 대한 통신 규칙이라고 보면 된다.


5. 서버가 HTTP Response를 보낸다

서버가 요청 처리를 완료하면 응답을 만들어 브라우저로 보낸다.

HTTP/1.1 200 OK
Content-Type: text/html

<html>
    ...
</html>

브라우저는 이 응답을 받아 HTML을 해석하고 화면에 페이지를 표시한다.

그런데 HTML 안에 다른 CSS나 JavaScript, 이미지 등이 포함되어 있다면 브라우저가 추가 요청을 보낼 수도 있다.

HTML
 │
 ├── CSS 요청
 ├── JS 요청
 ├── 이미지 요청
 └── 폰트 요청

따라서 웹사이트 하나를 열었다고 해서 HTTP 요청이 반드시 한 번만 발생하는 것은 아니다.


HTTP/1.1, HTTP/2, HTTP/3는 무엇이 다를까?

HTTP도 시간이 지나면서 발전했다.

대표적으로 HTTP/1.1, HTTP/2, HTTP/3가 있다.

HTTP/1.1

전통적인 HTTP 방식이다.

하나의 연결에서 여러 요청을 처리할 수 있도록 지속 연결을 사용할 수 있지만, 여러 리소스를 효율적으로 처리하는 데 한계가 있었다.


HTTP/2

HTTP/2에서는 하나의 TCP 연결을 이용하면서 여러 HTTP 요청과 응답을 멀티플렉싱(Multiplexing)​할 수 있다.

개념적으로 보면

하나의 TCP 연결
      │
 ┌────┼────┬────┐
 ↓    ↓    ↓    ↓
요청1 요청2 요청3 요청4

처럼 여러 요청을 하나의 연결에서 동시에 처리할 수 있다.

그래서 웹페이지에 필요한 리소스가 많을 때 HTTP/1.1보다 효율적으로 통신할 수 있다.


HTTP/3

HTTP/3는 전송 계층에서 QUIC을 사용하며 UDP 위에서 동작한다.

HTTP/1.1
HTTP/2
   ↓
 TCP

HTTP/3
   ↓
 QUIC
   ↓
 UDP

QUIC은 연결 설정과 보안, 스트림 처리 등을 결합해 현대적인 웹 환경에서 더 효율적인 통신을 목표로 한다.

따라서 HTTP라고 해서 항상 TCP 위에서 동작하는 것은 아니다.


HTTP 요청과 응답을 한 번에 정리하면

전체적인 흐름을 하나의 그림으로 보면 다음과 같다.

                 Client
              (Web Browser)
                    │
                    │
              HTTP Request
                    │
                    ▼
              ┌───────────┐
              │ Web Server │
              └───────────┘
                    │
             요청 처리 / DB 조회
                    │
                    │
              HTTP Response
                    │
                    ▼
                 Browser
                    │
                    ▼
              화면에 렌더링

HTTP 요청에는

Method
Path
Headers
Body

등이 들어갈 수 있고,

HTTP 응답에는

Status Code
Headers
Body

등이 포함된다.


개발할 때 HTTP 통신을 직접 확인할 수도 있다

웹 개발을 하다 보면 HTTP 요청과 응답을 직접 확인해야 하는 경우가 많다.

브라우저의 개발자 도구를 열고 Network 탭을 보면 실제 HTTP 통신을 확인할 수 있다.

예를 들어 페이지를 새로고침하면

Request URL
Request Method
Status Code
Remote Address
Response Headers
Request Headers
Response

등의 정보를 볼 수 있다.

예를 들어 다음과 같이 표시될 수 있다.

Request Method: GET
Request URL: https://example.com/
Status Code: 200
Content-Type: text/html

이 정보를 보면 우리가 지금까지 공부했던

도메인
 ↓
DNS
 ↓
IP
 ↓
TCP/TLS
 ↓
HTTP Request
 ↓
HTTP Response

과정이 실제 브라우저에서도 어떻게 나타나는지 확인할 수 있다.


마무리

HTTP 통신을 가장 간단하게 정리하면 클라이언트가 Request를 보내고 서버가 Response를 보내는 과정이다.

Client
  │
  │ Request
  ▼
Server
  │
  │ Response
  ▼
Client

HTTP Request에는

GET /index.html HTTP/1.1
Host: example.com

처럼 어떤 리소스를 요청하는지와 여러 부가 정보가 들어갈 수 있다.

서버는 요청을 처리한 뒤

HTTP/1.1 200 OK
Content-Type: text/html

같은 Response를 보내고 필요한 데이터를 Body에 담아 전달한다.

그리고 여기서 중요한 것이 상태 코드다.

서버가 정상적으로 처리했는지, 다른 곳으로 이동해야 하는지, 요청에 문제가 있는지, 서버에 문제가 있는지를 상태 코드로 알려준다.

결국 웹 브라우저에서 페이지 하나를 보는 과정은 단순히

웹페이지 열기

가 아니라,

도메인 입력
   ↓
DNS 조회
   ↓
IP 주소 확인
   ↓
TCP / QUIC 연결
   ↓
TLS 연결(HTTPS)
   ↓
HTTP Request
   ↓
서버 처리
   ↓
HTTP Response
   ↓
브라우저 렌더링

이라는 여러 단계가 이어지는 과정이다.

다음 글에서는 이 과정에서 자주 보게 되는 200, 301, 404, 500 같은 HTTP 상태 코드가 각각 무슨 의미인지 하나씩 살펴보자.

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다

글쓴이

rjsan46@koreabites.com

관련 게시물

웹 브라우저에 주소를 입력하면 일어나는 일

웹 브라우저 주소창에 웹사이트 주소를 입력하고 엔터를 누르면 바로 화면이 나타나는 것처럼 보인다. 하지만 실제로는 그 짧은 순간에 꽤 많은 일이 일어난다....

모두 읽어보기

소켓이란 무엇일까? 프로그램과 네트워크를 연결하는 통로

네트워크를 공부하다 보면 IP 주소와 포트 번호라는 말을 계속 만나게 된다. IP 주소는 어떤 컴퓨터와 통신할 것인지 구분하고, 포트 번호는 그 컴퓨터에서...

모두 읽어보기

쿠키와 세션은 어떻게 다를까?

웹사이트를 이용하다 보면 한 번 로그인한 뒤 다른 페이지로 이동해도 로그인 상태가 계속 유지되는 것을 볼 수 있다. 예를 들어 쇼핑몰에 로그인한...

모두 읽어보기

SSL과 TLS는 어떤 역할을 할까?

앞에서 HTTPS가 HTTP보다 안전한 이유를 살펴봤다. HTTPS는 단순히 HTTP 자체가 더 안전하게 만들어진 프로토콜이 아니라, HTTP 통신에 TLS라는 보안 계층을 적용한 것이라고...

모두 읽어보기

포트 번호로 네트워크 서비스를 구분하는 방법

컴퓨터가 네트워크를 통해 다른 컴퓨터와 통신할 때 가장 먼저 떠오르는 것이 IP 주소다. 예를 들어 어떤 서버의 IP 주소가 192.168.0.10이라고 해보자. 그런데...

모두 읽어보기

HTTPS는 HTTP보다 무엇이 안전할까?

인터넷에서 웹사이트에 접속하다 보면 주소창에 http://가 붙어 있는 경우도 있고 https://가 붙어 있는 경우도 있다. 요즘은 대부분의 웹사이트가 HTTPS를 사용하기 때문에 사실상...

모두 읽어보기