카테고리 없음

HTTP란?

1-yuna 2025. 1. 8. 20:18

목차

    HTTP

    HTTP란? 

    웹 브라우저와 웹 서버가 다양한 종류의 데이터를 주고받기 위해 사용하는 TCP 통신 기반 프로토콜(약속)이다.

     

    원래는 하이퍼 텍스트 문서(HTML)를 주고받기 위해 설계되었지만, 
    HTTP 1.0 버전 이후부터 클라이언트와 서버는 데이터의 형식을 정의하고 다양한 형태의 데이터를 교환할 수 있게 되었다. 
    ex) 이미지, 오디오, 비디오, 텍스트 파일, JSON 등

     

    🤔 TCP? 
    사실 이러한 HTTP는 TCP 프로토콜을 기반으로 동작한다.
    TCP에 대해 간단히 설명하면, 데이터가 정확하게 순서대로 도착하도록 보장하는 통신 방법이다.

     

     


    HTTP 특징 

    1) 클라이언트 서버 구조 

        - 클라이언트가 서버에 요청을 보내면, 서버가 요청에 대한 응답을 보내는 클라이언트-서버 구조로 이루어져 있다. 

     

     

    2) 비연결성 (HTTP 1.0 기준) 

        - TCP : 클라이언트가 요청을 보내지 않더라도 계속 연결을 유지해야한다.  -> 서버 자원 소모

        - HTTP: 요청을 주고받을 때만 연결을 유지하고 응답을 주고 나면 TCP 연결을 끊는다. -> 최소한의 자원으로 서버 유지

     

        그러나 수많은 자원들을 보낼때마다 연결을 끊고 다시 반복하는 것은 네트워크 자원과 시간이 낭비되어 매우 비효율적이다.

        따라서 HTTP 1.1 이후 부턴 지속 연결을 사용하여 위의 문제들을 해결하였다. 

     

     

    3) 무상태
        - TCP : 서버가 클라이언트의 상태를 보존한다. => 유상태 (Stateful)

        - HTTP: 서버가 클라이언트의 상태를 보존하지 않는다. => 무상태 (Stateless) 

    🤔 클라이언트의 상태? 
    클라이언트의 상태란, 클라이언트의 식별 정보를 의미한다. 
    ex) 로그인한 후, 클라이언트가 상태를 유지해야 서버는 어떤 클라이언트가 요청을 보냈는지 식별할 수 있다. 

    🤔 무상태이면 서버는 어떻게 식별하나?
    1) 쿠키
        - 클라이언트가 서버로부터 쿠키를 받아, 이를 요청에 포함시킨 후 서버는 요청에 포함된 쿠키를 읽고 클라이언트를 식별한다.
    2) URL 파라미터 
        - 클라이언트가 요청할 때 URL에 식별번호를 포함시킬 수 있다. 
           ex) https://example.com/profile?userId=12345
    3) HTTP 헤더
         - HTTP 요청 헤더에 인증 토큰을 포함할 수 있다. 
    4) 세션 ID
        - 세션ID(고유한 식별자)를 발급하고 클라이언트는 세션ID를 요청에 포함하여 서버에 보낸다.

     

     


    HTTP 구조 

    HTTP의 request와 response 는 크게 Start Line , Headers , Body 세 가지로 나눌 수 있다.  (- HTTP 1.1 기준)

     

    < HTTP request >

    # Start Line
    GET /index.html HTTP/1.1    
    
    # Headers
    Host: www.example.com                  
    User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64)
    Accept: text/html,application/xhtml+xml,application/xml;q=0.9
    Accept-Language: en-US,en;q=0.5
    Connection: keep-alive
    
    # Body
    username=user1&password=1234

     

    1) Start Line : HTTP 메서드, Request-URI, HTTP 버전

     

    2) Headers

        - Host : 요청할 서버의 호스트 이름

        - User-Agent : 클라이언트 프로그램(브라우저)의 정보

        - Accept : 클라이언트가 받을 수 있는 데이터 형식 

        - Accept-Language : 클라이언트가 선호하는 언어 

        - Connection : 요청 후 연결을 유지 ( 지속적 연결 ) 

    ❗️ Host : 요청할 서버의 도메인 이름 -> 요청할 서버의 호스트 이름 

    🤔 호스트와 도메인 무슨 차이일까? 
    1) 호스트
        - 네트워크에서 서버 (또는 컴퓨터)를 식별하는 이름 
        ex) www.example.com 에서 www는 호스트 이름이다. 

    2) 도메인
        - 인터넷에서 웹사이트 등을 식별하는 이름 
        ex) www.example.com 에서 example.com 은 도메인 이름 

     

    3) Body

        - 서버로 보내는 실제 데이터를 포함 

     

     

    <HTTP response >

    # Status Line
    HTTP/1.1 200 OK
    
    # Headers
    Date: Thu, 09 Jan 2025 12:34:56 GMT
    Server: Apache/2.4.41
    Content-Type: text/html; charset=UTF-8
    Content-Length: 138
    Connection: keep-alive
    
    # Body
    <!DOCTYPE html>
    <html>
    <head><title>Example</title></head>
    <body><h1>Hello, World!</h1></body>
    </html>

    1) Start Line : HTTP 버전 , Status Code (상태 코드)  , Reason Phrase (상태 메시지)

     

    2) Headers

        - Date : 응답이 생성된 날짜와 시간

        - Server: 소프트웨어 정보 

        - Content-Type : 본문 데이터 형식 

        - Content-Length : 응답 본문의 길이를 바이트 단위로 나타냄  

        - Connection : 연결의 상태를 지정함 ( 지속적 연결 ) 

     

    3) Body

        - 서버가 클라이언트에게 반환하는 데이터 

     


     

    HTTP 버전

    HTTP 0.9

    1) 초기 버전으로 매우 단순하다.

    2) get 메서드만 지원한다. 

    3) 응답은 HTML 문서만 전송한다. 

    /*요청*/
    GET /index.html

    /*응답*/
    <HTML>
    A very simple HTML page
    </HTML>

     

     


     

    HTTP 1.0

    특징

    1) 추가 메서드 도입

        - GET, POST

     

    2) 버전 정보 포함

        - 어떤 버전의 HTTP를 사용하는지 명확히 파악 가능하다. 

     

    3) 헤더 개념 도입
        - 이전에는 요청과 응답이 매우 간단했기 때문에, 서버가 보내는 데이터 형식을 명확히 지정할 수 없었다.

        - 헤더를 도입함으로써 필요한 데이터 형식을 요청하고, 사용한 데이터 형식을 응답할 수 있다.

     

    4) 상태코드 라인 추가

        - 요청 실패, 성공 파악 가능하다.

     

    # 요청
    GET /mypage.json HTTP/1.0
    Accept: application/json
    
    # 응답
    HTTP/1.0 200 OK
    Content-Type: application/json
    {
        "message": "This is a JSON response."
    }

     

     

    한계

    1) 비지속적 연결

        - 하나의 TCP 연결로 하나의 요청과 응답만 처리할 수 있다.

           즉, 여러개의 자원에 대한 요청을 처리할 때마다 새로운 연결이 필요하다.

           ex) 여러 자원 ( 이미지, 자바스크립트, css 등) 각각의 자원에 대해 새로운 TCP 연결을 열어야 한다.

           

    비지속적 연결

     

     


     

    HTTP 1.1

    특징

    1) 지속적연결 

        - HTTP 1.0 : 각 요청마다 새로운 연결을 만들어야 했다. (비지속 연결) 

        - HTTP 1.1 : 모든 자원에 대한 응답이 돌아온 후에 연결을 종료한다. (지속 연결)

    지속 연결

     

    2) 파이프라이닝 도입 

        - HTTP 1.0 : 요청을 보내고 응답을 받은 뒤 서버가 끊어지는 문제를 (비지속적 연결) 지속적 연결로 해결했다.

                             그러나 하나의 요청을 보내고 응답이 와야, 새로운 요청을 보낼 수 있다. 

        - HTTP 1.1 : 요청을 동시에 서버로 보낼 수 있기 때문에 대기 시간을 줄일 수 있다. ( 파이프라이닝 ) 

     

    비지속적연결, 지속적 연결, 파이프라이닝

     

    3) 호스트헤더 명시 

        - HTTP 1.0 : host 헤더가 반드시 명시되지 않아도 됐다.

        - HTTP 1.1 : 필수로 명시해줘야 함 -> 가상 호스트 환경을 지원하기 위해 도입된 규칙이다.

     

    4) 추가 메서드 도입

        - GET, POST, PUT, DELETE, OPTIONS, HEAD 

     

    한계

    1) HOL Blocking

        - 파이프라이닝을 도입하여 요청을 동시에 보낼 수 있지만 응답은 순차적이다.

          따라서 첫 번째 요청이 지연되면, 뒤에 있는 모든 요청도 기다려야 한다. 

       

    => 이런 문제를 해결하기 위해 여러 TCP 연결을 동시에 열어, 각 요청을 다른 연결로 보냈다.  

    => 네트워크 리소스 낭비 

     

     


     

    HTTP 2

    특징 

    1) 멀티플렉싱 

        - HTTP 1.1 : 처리는 순차적이기 때문에 여러 연결(TCP 연결) 을 해야했다. -> 속도저하, 네트워크 낭비

        - HTTP 2 :  하나의 연결에서 여러개의 스트림을 사용하여 동시에 요청과 응답을 처리한다. -> HOL Blocking 일부 해결

    🤔 스트림? 
    여러 요청을 동시에 처리하려면, 각 요청을 구분할 수 있어야한다. 
    이때 각 요청을 스트림이라 부른다. (독립적인 데이터 흐름) 

     

    2) 헤더 압축

        - HTTP 1.1 : 요청과 응답마다 같은 헤더 정보를 반복해서 보낸다. 

        - HTTP 2 : 헤더 정보를 압축해서 보낸다. 

     

    3) 바이너리 기반 

        - HTTP 1.1 : 사람이 읽을 수 있는 텍스트 포맷이다. -> 속도 저하 

        - HTTP 2 : 컴퓨터가 읽기 쉬운 바이너리(0과 1) 포맷이다.

     

    /*HTTP 1.1*/
    GET /index.html HTTP/1.1
    Host: www.example.com
    User-Agent: Mozilla/5.0

    /*HTTP 2*/
    0000 1001 0110 0011 1110 1010 ...

     

     

     

    TCP의 한계 

    1) 느린 연결 설정

        - TCP는 3-way handshake을 사용한다.

          해당 과정은 오래걸리고 네트워크가 잠깐 끊기면 TCP 연결을 다시 설정해야한다. -> 연결 지연

     🤔 3-way handshake 란? 
     TCP는 데이터 전송 전에 유저와 서버를 미리 연결하는데 이 과정을  3-way handshake이라 한다. (연결 설정) 

    미리 연결하는 이유는? 
    1) 신뢰성 보장 
        - 클라이언트와 서버가 서로 확인하고, 연결 준비 상태를 확인하기 위함 
    2) 재전송 가능 
        - 해당 과정이 없으면, 초기 시퀀스 번호가 설정되지 않아 패킷 손실 발생시 이를 추적하고 재전송할 방법이 없다 


    1) SYN : 연결 준비됐어? 
    2) SYN + ACK : 응 준비됐어 
    3) ACK : 연결할게~ 

     

    2) HOL Blocking 

        - HTTP/2는 여러 요청을 한 TCP에서 멀티플렉싱하여 처리하였지만

          한 스트림에서 패킷손실이 나면, 그 스트림의 나머지 데이터가 순서대로 전송될 때까지 다른 스트림의 데이터도 모두 지연된다. 

     


    HTTP 3

    TCP의 한계를 극복하고자 HTTP 3가 등장했다. 

    HTTP 3는 Google의 QUIC 프로토콜을 기반으로 개발했다. 

     

    🤔 QUIC 프로토콜이란? 
    UDP를 기반으로 만들어진 프로토콜이다. 
    UDP는 TCP와 다르게 3-way handshake(연결 설정)가 없다. 

    장점
    - 3-way handshake가 없어, 간단하고 빠른 프로토콜이다. 
    단점
    - 3-way handshake가 없어, 신뢰성이 부족하다. ( 데이터가 손실/ 순서가 바뀌어도 자동으로 감지, 복구 기능이 없다)

    즉, UDP를 사용하여 속도를 높이고자 했지만, 신뢰성 문제가 발생하여 구글은 UDP 기반의 QUIC 프로토콜을 개발했다. 

     

    특징 

    1) 연결 설정 속도 향상 

        - QUIC는 초기 연결시 0-RTT를 지원한다. 이는 연결설정을 하지않고, 이전 연결 정보를 재사용한다.  

          -> 이전 정보가 없으면? : 1-RTT를 사용한다. 이는 클라이언트가 요청을 보내고 서버가 응답하는 과정을 말한다. 

     

    2) HOL Blocking 개선 

        - HTTP 2: 한 스트림에서 데이터가 손실되면 다른 스트림의 데이터도 모두 지연됐다. 

        - HTTP 3: UDP는 TCP와 달리 연결 지향적이지 않기 때문에, 각 스트림을 독립적으로 처리하여 지연되는것을 막을 수 있다. 

     

    3) 신뢰성 부족 개선 

        - TCP는 3-way handshake 가 있어, 초기 시퀀스 번호가 설정되어 패킷을 감지하고 재전송하는 방식으로 신뢰성을 보장한다.

        - QUIC는 3-way handshake를 사용하지 않고 자체적으로 각 패킷에 고유한 시퀀스 번호를 할당하여,

           패킷이 손실되었는지 순서가 바뀌었는지 감지할 수 있다.