HTTP 를 제대로 사용하기 전에 읽어보기

최현준·2024년 4월 22일
1

HTTP: 웹 통신의 기본

HTTP는 HyperText Transfer Protocol의 약자로, 인터넷에서 데이터를 교환하는 데 사용되는 프로토콜입니다. 이 문서에서는 HTTP의 기본적인 개념, 버전별 변화, 그리고 HTTPS의 중요성에 대해 설명합니다.

HTTP 이해하기

프로토콜이란?
프로토콜은 데이터 교환을 위한 규칙의 집합입니다. 네트워크에서 서로 다른 기기가 통신하기 위해선 공통의 언어를 사용해야 하며, 이 때 필요한 규약이 바로 프로토콜입니다.

OSI 7 Layer Model과 HTTP

네트워크 통신의 이해를 돕기 위해 OSI 7 Layer Model을 소개합니다. HTTP는 이 모델의 애플리케이션 레이어에서 작동하여, 웹 페이지 접속과 같은 기능을 가능하게 합니다.

참고로 네트워크의 끝(종단)은 노트북이나 스마트폰이 아닙니다.
네트워크의 끝(종단)은 레이어 가장 상위층을 말합니다.

FTP 프로그램은 이미지의 FTP 프로토콜을 활용하여 파일 전송을 간편하게 수행합니다.

메일 확인 프로그램은 위 SMTP 프로토콜을 이용하여 메일을 간편하게 전송합니다.

따라서, 우리가 인터넷에 쉽게 접속할 수 있는 이유는 HTTP 프로토콜을 통해 텍스트와 미디어를 손쉽게 전송할 수 있기 때문입니다.

즉, 클라이언트와 서버 간의 통신에서 HTTP를 통해 요청과 응답을 주고받을 수 있습니다.

HTTP의 구조는 RESTful 설명 시 자세히 다루겠습니다. RESTful 아키텍처를 이해하고 사용하기 위해서는 HTTP의 구조를 알아야 합니다, 특히 인증 과정에서 그러합니다.

HTTP의 발전: 버전별 주요 특징과 변화

HTTP(HyperText Transfer Protocol)는 웹에서 데이터를 교환하는 데 사용되는 핵심 프로토콜입니다. 시간이 흐르면서 HTTP는 여러 버전을 거치며 발전해 왔으며, 각 버전은 웹의 성능과 보안을 향상시키는 데 중요한 역할을 했습니다.

HTTP/0.9 (1991년)

특징: 초기 버전으로, 단일 라인의 GET 메소드만을 지원하며, 응답으로는 HTML 문서의 내용만 전송됩니다.
한계: 헤더, 상태 코드, 그 외 형식의 데이터 전송 미지원.

HTTP/1.0 (1996년)

도입된 기능: HTTP 헤더와 상태 코드가 추가되어 브라우저 요청의 성공과 실패를 명확히 파악할 수 있게 되었습니다.
개선점: Content-Type 헤더를 통해 HTML 이외의 문서도 전송할 수 있게 됨.
제한점: 연결 당 하나의 요청과 응답만 처리 가능.

HTTP/1.1 (1997년)

주요 개선: Persistent Connection 도입으로 연결 지속성 확보, 여러 요청과 응답을 하나의 연결로 처리 가능.
한계: 하나의 연결에서 요청들이 순차적으로 처리되어야 함, 이로 인한 Head Of Line Blocking (HOL) 문제 발생.

HTTP/2.0 (2015년)

혁신: 멀티플렉싱을 통해 여러 요청과 응답을 하나의 연결에서 동시에 처리 가능.
기능 개선: 서버 푸시, Flow Control 및 우선순위 부여 기능을 통한 성능 개선.
HOL 해결: 여러 이미지 파일 같은 리소스가 병렬적으로 요청되고 응답되므로, 하나의 요청 처리 지연이 다른 요청에 영향을 주지 않음.

HTTP/3.0 (개발 중)

기반 프로토콜: QUIC (Quick UDP Internet Connections), Google이 개발한 UDP 기반 프로토콜.
특징: TCP의 한계를 극복하고, 각 스트림이 독립적으로 처리됨으로써 HOL 문제를 완전히 해결.
개선점: 3-way handshake 최적화 및 전송 속도와 안정성 향상.
기술적 문서
RFC 2068 (1997년)부터 시작하여 RFC 2616 (1999년), RFC 7230~7235 (2014년)에 이르기까지, 각 HTTP 버전의 표준은 RFC 문서를 통해 제공됩니다. 현재 표준은 RFC 7230 이후 문서를 참조합니다.
이렇게 HTTP는 웹의 기본이 되는 통신 규약으로서, 시간이 지남에 따라 다양한 기능이 추가되고 성능이 개선되어 왔습니다.

Head Of Line Blocking (HOL)

Head Of Line Blocking (HOL)은 특히 HTTP/1.1과 같은 프로토콜에서 여러 데이터 요청이 단일 TCP 연결을 통해 순차적으로 처리될 때 발생하는 문제입니다. 이 문제는 첫 번째 패킷이 지연되거나 손실될 경우, 해당 패킷이 처리되기 전까지 후속 패킷들이 처리되지 못하는 현상을 말합니다. 이는 네트워크 효율성을 크게 저하시킬 수 있습니다.

HOL의 실제 예시 (ASCII Art)
아래는 웹 페이지에서 세 개의 이미지 파일(a.png, b.png, c.png)을 요청하는 과정에서 발생하는 HOL 문제를 ASCII 코드로 표현한 예제입니다:

클라이언트 요청:
GET /a.png HTTP/1.1
GET /b.png HTTP/1.1
GET /c.png HTTP/1.1

서버 응답 (TCP 스트림):
| A 요청 처리 | A 응답 전송 | B 요청 처리 | B 응답 전송 | C 요청 처리 | C 응답 전송 |

문제 상황:
| A 요청 처리 지연 | -------- 대기 -------- | -------- 대기 -------- |

위 예제에서 보이듯, 'A 요청 처리 지연'이 발생하면, B와 C의 처리가 A의 처리와 응답이 완료될 때까지 지연됩니다. 이는 모든 요청이 하나의 연결을 통해 순차적으로 처리되기 때문입니다.

HTTP/2에서의 개선
HTTP/2는 이러한 문제를 해결하기 위해 단일 TCP 연결 내에서 여러 요청을 동시에 병렬로 처리할 수 있는 멀티플렉싱 기능을 도입하였습니다. 이를 통해 하나의 요청 처리가 지연되어도 다른 요청의 처리와 응답이 독립적으로 진행될 수 있습니다.

HTTP/2 멀티플렉싱 처리:
| A 요청 | B 요청 | C 요청 |
|--------|--------|--------|
| A 응답 | B 응답 | C 응답 |

위에서처럼 HTTP/2에서 각각의 요청이 독립적으로 처리되고 응답되도록 개선되었습니다. 이로 인해 하나의 요청 처리가 지연되어도 다른 요청에 영향을 주지 않습니다.

이러한 개선을 통해 HTTP/2는 웹 페이지의 로딩 속도를 향상시키고 사용자 경험을 개선하는 데 크게 기여합니다.

HTTP 구조: 개요 및 상세 분석

HTTP의 구조를 이해하는 것은 RESTful 아키텍처와 효율적인 웹 서비스 설계에 필수적입니다. HTTP 메시지는 크게 세 부분으로 나뉩니다: 시작라인, 헤더, 그리고 메시지 본문입니다.

시작라인(Start Line)

구성: HTTP 메서드, 요청 대상, HTTP 버전
예시: GET /search HTTP/1.1 - 이 예시는 서버에 '/search' 경로에 대한 정보를 요청합니다.

HTTP 메서드(Methods)

정의: 요청의 종류를 나타내며, 서버에서 수행해야 할 작업을 명시합니다.

일반적인 메서드:

GET: 데이터를 조회할 때 사용합니다.
POST: 새로운 데이터를 생성할 때 사용합니다.
PUT: 데이터를 업데이트할 때 사용합니다.
DELETE: 데이터를 삭제할 때 사용합니다.
OPTIONS: 사용 가능한 통신 옵션을 설명할 때 사용합니다.

요청 대상(Request Target)

설명: 요청이 전송되는 특정 리소스의 URI입니다.
예시: /login - 이는 로그인 페이지 혹은 API의 경로입니다.

HTTP 버전

설명: 사용중인 HTTP 프로토콜의 버전을 명시합니다.
예시: HTTP/1.1, HTTP/2, HTTP/3

헤더(Headers)

기능: 요청과 응답에 대한 메타데이터를 포함하며, 여러 키-값 쌍으로 구성됩니다.
주요 헤더 정보 예시:
Content-Type: 메시지 본문의 미디어 유형을 명시합니다. 예: application/json
Content-Length: 메시지 본문의 길이를 바이트 단위로 명시합니다.
Host: 요청이 전송되는 서버의 주소입니다.
User-Agent: 요청을 보내는 클라이언트의 정보를 제공합니다.
Accept: 클라이언트가 처리할 수 있는 미디어 타입을 명시합니다.
Connection: 해당 요청 후 연결을 유지할지 여부를 명시합니다.
메시지 본문(Body)
설명: 실제 전송할 데이터를 포함합니다. GET 요청과 같이 데이터를 전송하지 않는 요청들은 본문이 없을 수 있습니다.
예시: POST 요청에서 JSON 형태로 데이터를 전송할 때 사용됩니다.
http

POST /payment-sync HTTP/1.1
Host: intropython.com
Content-Type: application/json
Content-Length: 83
Accept: application/json
Connection: keep-alive
User-Agent: HTTPie/0.9.3

{
    "imp_uid": "imp_1234567890",
    "merchant_uid": "order_id_8237352",
    "status": "paid"
}

HTTPS: 안전한 HTTP

HTTPS는 HTTP에 보안 계층을 추가하여 데이터를 암호화하고, 중간자 공격으로부터 데이터를 보호하는 프로토콜입니다. 이 섹션에서는 HTTPS의 핵심 구성요소와 통신 과정을 자세히 설명합니다.

SSL/TLS 사용

HTTPS는 SSL(Secure Sockets Layer) 또는 TLS(Transport Layer Security)를 사용하여 데이터를 암호화합니다. 이 기술들은 데이터 전송 중 정보를 보호하고, 서버와 클라이언트 간에 안전한 통신 채널을 확립합니다.

인증 과정

서버 인증: 서버는 클라이언트에게 디지털 인증서를 제공합니다. 이 인증서에는 서버의 공개키와 인증 기관(Certificate Authority, CA)에 의한 서명이 포함되어 있습니다.
클라이언트 검증: 클라이언트는 CA의 공개키를 사용하여 서버의 인증서를 검증하고, 서버의 신뢰성을 확인합니다.
암호화된 세션 설정: 검증이 완료되면, 클라이언트와 서버는 대칭 키를 교환하여 세션 데이터를 암호화합니다.
HTTPS의 동작 예시

POST /payment-sync HTTP/1.1
Host: intropython.com
Accept: application/json
Accept-Encoding: gzip, deflate
Connection: keep-alive
Content-Length: 83
Content-Type: application/json
User-Agent: HTTPie/0.9.3

{
    "imp_uid": "imp_1234567890",
    "merchant_uid": "order_id_8237352",
    "status": "paid"
}

이 예시에서는 /payment-sync 엔드포인트로 결제 정보가 JSON 형식으로 안전하게 전송됩니다. 응답은 일반적으로 JSON 형식으로 반환됩니다.

HTTP와 HTTPS

HTTP 통신은 기본적으로 평문 데이터를 사용하므로, 통신 내용이 도청될 수 있습니다. 반면, HTTPS는 암호화를 통해 이러한 위험을 방지합니다.

HTTPS 암호화 과정

공개키 및 대칭키 교환:

클라이언트는 서버로부터 받은 공개키로 대칭키를 암호화하여 전송합니다.
서버는 자신의 비밀키로 대칭키를 복호화합니다.

암호화된 데이터 전송:

클라이언트와 서버는 이 대칭키를 사용하여 세션 동안 데이터를 암호화하고 복호화합니다.
HTTP 상태 코드 (Status Codes)
HTTP 응답은 상태 코드를 통해 요청의 결과를 나타냅니다:

1xx (정보적): 요청이 수신되어 처리 중입니다.
2xx (성공): 요청이 성공적으로 처리되었습니다. 예: 200 OK, 201 Created.
3xx (리다이렉션): 요청을 완료하기 위해 추가 조치가 필요합니다.
4xx (클라이언트 오류): 요청에 오류가 있습니다. 예: 400 Bad Request, 401 Unauthorized.
5xx (서버 오류): 서버가 요청을 처리할 수 없습니다. 예: 500 Internal Server Error.
이러한 구조와 프로토콜의 이해는 웹 개발과 보안에 있어 중요합니다. 각 상태 코드는 문제 해결 시 유용한 정보를 제공하므로, 개발자는 이를 숙지하고 적절히 활용해야 합니다.

0개의 댓글