HTTP

HTTP

1. HTTP

HTTP 개념

인터넷에서 단순히 웹 사이트가 주소만 넣으면 해당 사이트를 보여주는 것이 아니다. 그 안에서는 클라이언트가 서버에게 원하는 데이터를 요청하고, 요청한 내용에 대한 응답을 받고, HTML/CCS/이미지 등 받은 자원을 잘 가공해 사용자의 눈앞에 보여주는 과정들이 들어있다.

HTTP(Hypertext Transfer Protocol)는 웹 브라우저와 웹 서버 간에 데이터를 주고 받기 위해 사용하는 프로토콜이다. 이전에는 HTML 같은 하이퍼텍스트 형태의 데이터만 통신할 수 있었지만, 오늘날에는 이미지나 동영상처럼 웹을 구현하기 위한 다른 다양한 형식도 전달할 수 있다.

HTTP 특징

  • HTTP는 클라이언트/서버 모델을 따른다

요청하고 응답하는 과정에서 클라이언트와 서버는 각각 HTTP 메시지를 주고 받으며 통신한다.

HTTP 메시지

클라이언트와 서버 사이에 데이터가 교환되는 방식

  • 요청 메시지 : 클라이언트가 서버에게 요청하는 메시지
  • 응답 메시지 : 클라이언트의 요청을 해석한 서버가 응답하는 메시지
  • HTTP는 상태를 가지지 않는다.(stateless)

상태가 없다는 것은 클라이언트와 서버가 첫 번째 통신에서 데이터를 주고받아도 두 번째 통신에서 클라이언트는 앞서 받은 데이터를 유지하지 않는다는 것이다.

ex) 쇼핑몰에서 로그인하고(첫 번째 통신) 장바구니에 물건을 담으려는데(두 번째 통신) 다시 로그인하라고 하는 것(상태를 가지고 있지 않음 == 앞서 받은 데이터를 유지하지 않음)

이처럼 상태가 없는 통신은 이전에 받은 데이터 정보를 확인할 수 없기 때문에 상대적으로 효율이 떨어진다. 그래서 웹 브라우저의 쿠키나 웹 서버의 세션처럼 상태를 저장하는 공간을 이용해 상태를 유지한다. 통신할 때, 쿠키나 세션에 저장된 데이터를 보고 앞뒤 문맥을 파악하는 것이다.

  • HTTP는 한 번 통신을 주고받으면 연결을 끊는 비연결성(connectionless) 프로토콜이다.

비연결성이란, 클라이언트와 서버가 연경르 맺은 후 클라이언트의 요청에 섭가 응답을 마치면 연결이 끊어지는 특성을 의미한다.

이러한 특징은 연결을 계속 유지할 때 발생하는 비용 낭비를 줄일 수 있지만, 요청마다 연결을 맺어야 하므로 TCP의 3방향 핸드셰이크처럼 연결 절차가 반복되는 문제가 발생한다. (오늘날 많이 사용하는 HTTP 버전에서는 이를 개선해 연결을 지속할 수 있다.)

HTTP 메시지 구조

[요청 메시지]

요청 메시지에는 클라이언트가 서버에게 요청하는 정보가 담겨 있다.

  • 요청 라인 : 클라이언트가 무엇을, 어떤 방식을 통해, 어떻게 처리하고자 한다는 정보
    • 요청 메서드 : (어떻게) 클라이언트가 서버에게 요청하는 데이터가 어떻게 처리되면 좋을지를 나타냄
    • 경로 : (무엇을) 가져오려는 자원의 경롤르 표시
    • 프로토콜 버전 : (어던 방식을 통해) 통신에 사용할 HTTP 프로토콜의 버전
  • 요청 헤더 : HTTP 메시지에 대한 추가 정보 제공
  • 빈 라인 : 헤더와 본문 구별
  • 본문 : 응답을 받기 위한 별도의 데이터를 담음 ex) 회원가입을 해서 내 정보를 서버에 보내고 싶을 때 이름/아이디/비밀번호 등 정보를 담는 용도

[응답 메시지]

  • 응답 라인
    • 프로토콜 버전
    • 상태 코드 : 클라이언트의 요청에 따른 서버의 응답을 숫자로 나타낸 것 ex) 200, 404..
    • 상태 메시지 : 상태 코드를 이해하기 쉽게 영어로 풀어 쓴 메시지
  • 헤더
  • 빈 라인
  • 본문 : 요청에 관한 자원

2. GET vs POST, PUT vs PATCH

헤더나 본문이 따로 있지만, 요청 메서드가 필요한 이유는 클라이언트가 서버로부터 데이터를 받고 싶은지 / 데이털르 추가하고 싶은지 등 목적을 전달해 웹 서버에서 처리한느 방식이 달라지기 때문이다.

요청 메서드의 종류

  • GET : 서버에서 데이터를 가져오는 메서드
    • 서버의 상태가 변경되지 않음
  • HEAD : HTTP 헤더 정보만 요청
    • 응답 메시지는 본문 없이 도착
    • 웹 서버가 정상적으로 동작하는지 등 서버 상태를 미리 확인하기 위해 사용
  • POST : 클라이언트가 담고 있는 정보를 서버에게 전송할 때 사용하는 메서드
    • 서버의 상태가 변경됨
  • PUT : 데이터를 완전히 교체하는 메서드
  • PATCH : 데이터 일부만 수정하는 메서드
  • DELTE : 클라이언트가 지정한 데이터를 삭제하는 메서드
  • OPTIONS : 서버 측에서 제공할 수 있는 메서드가 무엇인지 알기 위해 사용
    • ex) Allow : GET, POST, HEAD

안전성 / 멱등성

  • 안전성 : 클라이언트가 요청을 해도 서버의 자원이 변하지 않는 특성
    • GET, HEAD, OPTIONS
  • 멱등성 : 서버의 자원이 바뀌어도 상관없으나, 1번 요청했을 때와 여러번 요청했을 때 자원의 상태가 같은가? == 1번 요청했을 때와 여러 번 요청했을 때 자원의 상태가 같은가?
    • GET, HEAD, OPTIONS, PUT, DELETE

POST는 요청을 보낸 만큼 새 데이터가 추가되기 때문에 멱등성을 가지지 않는다고 정의한다.

PUT은 기존 데이터를 대체하기 때문에 한 번 요청했을 때와 여러 번 요청했을 때 자원의 상태가 같기 때문에 멱등성을 갖는다고 정의한다.

하지만 PATCH는 기존 데이터를 대체하는 것이 아니라 일부만 변경하기 때문에, 만약 “나이에 1을 더해줘” 라는 요청이라면 한 번 요청했을 때와 여러 번 요청했을 때의 자원의 상태가 다르기 때문에 멱등성을 가지지 않는다고 정의한다.

3. 헤더

TCP/IP와 HTTP 모두 헤더를 갖는다. 헤더만 보고도 해당 데이터에 대한 핵심 정보를 바로 파악할 수 있기 때문에 프로토콜에서 헤더를 파악하는 일은 중요하다.

HTTP 헤더는 클라이언트와 서버가 메시지를 주고받을 때, 본문뿐만 아니라 부가적인 정보를 전송하기 위해 사용한다.

HTTP 헤더의 특징

  • 헤더를 보면 클라이언트와 서버가 주고 받은 요청과 응답이 어떤 정보를 갖고 있고, 어떻게 처리하면 좋을지 등을 확인할 수 있음
  • 사람이 읽을 수 있는 텍스트 형태로 작성
  • 헤더가 없어도 통신할 수 있어 클라이언트와 서버가 필요한 만큼 헤더를 작성할 수 있음
  • ‘헤더명 : 헤더값’의 형식으로 작성하며, 대소문자를 구분하지 않음

HTTP 헤더의 종류

  • 공통 헤더(general header)
    • 요청 메시지와 응답 메시지 모두 적용되는 헤더
    • Date : 메시지가 발생한 날짜와 시각을 표현
    • Cache-Control : 기존에 받은 데이터 저장 여부를 설정
  • 요청 헤더(request header)
    • 요청 메시지에 작성 / 클라이언트에 대한 정보 또는 변경될 데이터에 관한 내용을 포함
    • Host : 데이터를 요청하는 서버의 호스트 이름
    • User-Agent : 클라이언트의 정보
  • 응답 헤더(response header)
    • 응답 메시지에 대한 정보
    • Server : 서버에 대한 정보
  • 엔티티 헤더(entity header)
    • 메시지 본문에 대한 정보를 포함
    • Content-Length : 본문의 길이
    • Content-Type : 본문의 정보

4. 상태 코드

상태 코드란?

HTTP에서는 상태 코드를 보면 통신 상태를 파악할 수 있다. 상태 코드는 클라이언트의 요청에 따른 서버의 응답 상태를 세 자리 숫자로 나타낸 것이다. 이 코드를 보면 요청과 응답의 통신 성공 여부뿐만 아니라 문제가 발생했을 때 어디가 원인인지도 파악할 수 있다.

상태 코드의 5가지 클래스

  • 1XX 클래스

    • 조건부 응답
    • 웹 서버가 현재 요청을 받앗으며 작업을 진행하고 있다는 의미
    • 100(Continue) : 서버가 첫 번째 요청을 받았으며 추가 요청을 기다리고 있음을 나타냄
    • 주식 정보와 같이 실시간으로 데이터를 받아야 하는 통신에서 주로 사용
  • 2XX 클래스

    • 클라이언트가 요청한 작업을 서버가 성공적으로 처리했음을 의미
    • 200(Ok)
    • 201(Created) : 데이터가 생성되었음을 의미
    • 204(No Content) : 성공적으로 처리는 했지만 본문은 빼고 전달해 통신 속도를 줄임
  • 3XX 클래스

    • 리다이렉션 완료 응답으로 요청을 완료하기 위해 재전송이 필요하다는 의미
    • 301(Moved Permanently) : 추가로 요청한 페이지로 영구 이동
    • 302(Found) : 추가로 요청한 페이지로 일시적 이동
  • 4XX 클래스

    • 클라이언트 측에 오류가 있음을 의미
    • 400(Bad Request) : 클라이언의 요청 내용에 문제가 있음
    • 401(Unauthorized) : 인증되지 않은 사용자
    • 404(Not Found) : 요청에는 문제가 없지만, 요청한 데이터가 없다는 뜻
  • 5XX 클래스

    • 서버가 요청을 수행하지 못했다는 의미
      • 500(Internal Server Error) : 서버 내부적으로 오류가 발생해 응답에 실패했다는 의미
      • 502(Bad Gateway) : 서버가 다른 서버로부터 잘못된 응답을 받는 등 서버 간 네트워크에 문제가 생겨 통신이 제대로 되지 않았음을 의미

5. SSL, TLS, HTTPS

HTTP의 한계, 보안

  • 중간자 공격(Man in the middle attack, MITM)
  • 통신 상대 확인 X

HTTP는 정보를 누구나 볼 수 있게 암호화하지 않은 평문으로 전송했다. 이는 개발자들이 쉽게 메시지를 확인할 수 있다는 면에서는 장점이지만, 중간에 정보를 몰래 탈취할 수 있어 보안에 취약하다. 보안의 문제 때문에 탄생한 것이 HTTPS(Hyper Transfer Protocol Secure)이다.

HTTPS

HTTPS는 당사자만 볼 수 있도록 내용을 암호화하여 보안 문제를 해결했다.

SSL / TLS

HTTPS의 암화화는 SSL(Secure Sockets Layer)에서 담당한다. SSL은 클라이언트와 서버가 서로 데이터를 암호화해 통신할 수 있도록 돕는 보안 계층이다.

대칭키 / 공개키

컴퓨터에서는 암호화를 위해 비밀번호 같은 개념인 키가 필요하다. 키가 있어야 암호화를 하고, 반대로 암호를 푸는 복호화도 할 수 있다.

  • 대칭키 기법

대칭키 기법은 하나의 키로 암호화와 복호화를 둘 다 할 수 있는 암호화 기법이다. 클라이언트와 서버가 같은 키를 가지고 있다가 데이터가 오면 해당 키로 복호화하고, 해당 키로 데이터를 암호화하여 전송하는 것이다.

대칭키 기법은 암호화/복호화 속도가 빠르지만, 서로 키를 안전하게 교환하기가 어렵다는 단점이 있다. 클라이언트와 서버가 같은 키를 가지고 있어야 하므로 서로 키를 주고받아야 하는데, 이때 보안에 문제가 생길 수 있기 때문이다.

  • 공개키 기법

공개키 기법은 서로 다른 키 두 개를 암호화와 복호화를 한다는 특징이 있다. 이때 사용하는 키 두 개를 각각 공개키, 개인키라고 부른다. 공개키와 개인키는 늘 한 쌍으로 동작한다.

공개키로 데이터를 암호화하여 전송하고, 받은 데이터를 개인키로만 복호화할 수 있고 그 반대도 될 수 있다. 서버가 개인키를 가지고 있고, 클라이언트에게 공개키를 전달해 서로 데이터를 암호화해서 주고받는다면 누군가 공개키를 가로챘다고 하더라도 개인키를 모르기 때문에 데이터를 복호화할 수 없어 보안에 더욱 안전하다.

암호화 과정이 복잡하기 때문애 속도는 느리지만, 대칭키보다 더 안전하게 데이터를 주고받을 수 있다는 장점이 있다.

SSL에서는 두 기법을 함께 사용하여 서로의 단점을 보완한다.

SSL 동작 과정

  1. Client Hello
  • 클라이언트는 서버에 인사
  • 랜덤한 데이터 / 지원 가능한 암호화 방식 을 서버에 전달
  1. Server Hello
  • 서버도 클라이언트에게 인사
  • 랜덤한 데이터 / 지원 가능한 암호화 방식 / 인증서 를 클라이언트에 전달
    • 인증서 : CA(Certificate Authority)에서 발급받은 문서로, 서버가 신뢰할 수 있는지 보장하는 역할
  1. 인증서 확인
  • 서버가 전달한 인증서가 CA가 발급한 인증서 목록 중에 있는지 1차 확인
  • CA에서 공유하는 공개키를 가지고 인증서 복호화하여 2차 확인
  1. 대칭키 임시로 발급
  • 클라이언트는 키를 주고받기 위해 대칭키를 임시로 만든다.
  • 클라이언트와 서버가 서로 주고받은 랜덤한 데이터를 조합해 임시 키(pre master secret) 생성
  • 임시키는 대칭키이기 때문에 보안의 위험이 있어 앞서 갖고 있던 공개키로 암호화하여 서버에 전달
  1. 임시 키 전달
  • 서버는 가지고 있던 비밀키로 암호를 해독해 임시 키 전달받음
  1. 클라이언트-서버 통신
  • 임시 키는 일련의 과정을 거쳐 세션 키로 바뀌고, 클라이언트와 서버가 통신을 진행함
  1. 세션 단계
  • 세션 단계에서는 세션 키를 이용해 대칭키 기법으로 데이터를 암호화해서 통신하고, 데이터 정손이 끝나면 세션을 종료해 통신을 마침

6. HTTP 변천사

태초의 HTTP(HTTP/0.9)

  • 데이터를 요청한다는 본문과 요청한 메시지에 대한 결과를 본문에 담아 응답
  • 데이터의 상태를 보여주는 헤더 X
  • HTML 파일 한 종류만 전송할 수 있기 때문에 데이터 타입 등의 정보를 기입할 필요가 없었음
  • GET만 지원

HTTP 1.0

  • 데이터의 상태를 보여주는 헤더가 생김
  • 메서드 HEAD, POST 추가
  • HTML 뿐만 아니라 이미지, 파일 등 다양한 타입의 데이터를 주고받을 수 있게 되어, Content-Type을 통해 확인 가능
  • 단점
    • 모든 요청마다 새로운 TCP 연결이 필요
    • 이전 요청에 대한 응답이 도착해야만 다음 응답을 보낼 수 있음
  • 공식 표준은 아니었음

HTTP/1.1

  • 지속적 연결 상태(Persist Connection) 기법
    • 한 번 TCP 연결을 맺으면 따로 연결을 끊지 않는 이상 기본적으로 연결을 유지
    • 3방향 핸드셰이크를 한 번으로 줄여 서버나 CPU 등의 메모리 자원 절약
  • 파이프라이닝(Pipelining)
    • 첫 번째 요청에 대한 응답이 완전히 전송되기 전에 두 번째 전송 요청을 가능하게 하는 기법
    • 불필요한 지연을 막고 더 빠른 통신이 가능
  • 단점
    • 응답과 요청은 1:1 대응
    • 요청이 들어간 순서대로 처리하여 앞의 요청 시간이 길어지면 뒤에 있는 요청도 지연됨

HTTP/2

  • 성능 향상에 초점을 맞춘 프로토콜
  • 스트림 다중화(Multiplexed Streams)
    • 응답의 순서와 상관없이 한 연결 안에서 여러 개의 메시지를 주고받을 수 있음
  • 서버 푸시(Server Push)
    • 클라이언트가 요청하지 않아도 서버에서 미리 필요한 리소스를 푸시 -> 더 높은 성능과 빠른 속도를 보장

스트림 다중화 및 서버 푸시와 같이 HTTP/2에 새로운 변화를 가능하게 한 핵심 기능은 바이너리 프레이밍(binary framing)이다.

  • 바이너리 프레이밍
    • 텍스트 형식의 HTTP 메시지를 더 작은 단위로 쪼개 바이너리 형태로 캡슐화한 것
    • 기존 HTTP 메시지가 header, body로 구성된 한 묶음이었다면, 이제는 각각을 프레임이라는 더 작은 단위로 세분화해 전송 -> 받는 쪽에서 분리된 프레임을 재조립해 사용

받은 파일의 압출을 풀기 위해서는 바이너리 프레이밍을 위한 새 계층이 별도로 필요했기 때문에 HTTP/1.2가 아닌 HTTP/2가 된 것이다.

HTTP/3

HTTP/2 의 문제는 TCP 위에서 작동하고 있다는 것이다. TCP의 문제는 HOLB(Head of Line Blocking)이다. TCP는 무조건 순서대로 데이터를 처리하기 때문에, 중간에 데이터 일부가 손실되면 이를 해결하는 동안 다른 데이터를 처리할 수 없다. HOLB는 데이터에 이상이 생겼을 때 생기는 병목 현상을 의미한다.

TCP의 문제를 해결한 프로토콜은 구글에서 개발한 QUIC(Quick UDP Internet Connection)이다. UDP 위에서 빠르게 작동해 빠른 속도를 보장하고, TCP가 가지고 있던 데이터 검증 기능을 구현해 신뢰성까지 보장한다. 이를 가능하게 한 특징은 멀티플렉싱(Multiplexing) 기법이다.

  • 멀티플렉싱
    • 하나의 연결에 여러 전송 경로를 두는 기법
    • 한 경로에 문제가 생겨도 다른 경로를 지킬 수 있게 해 HOLB 문제에 자유로워지면서 데이터를 안전하게 운발할 수 있음

QUIC는 TLS까지 대체하기 때문에 TCP의 3방향 핸드셰이크뿐만 아니라 TLS에서 데이터 암호화를 위해 수행하는 핸드셰이크도 생략되어 속도를 높였다. QUIC를 사용한 프로토콜이 HTTP/3이다.