ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • HTTP의 역사
    SE General 2021. 8. 2. 17:52
    반응형

    HTTP (Hypertext Transfer Protocol)는 인터넷 상에서 가장 많이 쓰이고 적용된 애플리케이션 프로토콜입니다. 단순한 하나의 키워드와 다큐먼트 패스로 시작하여, HTTP는 브라우저 뿐만 아니라 거의 모든 인터넷 기반 소프트웨어 및 하드웨어 애플리케이션에 사용되고 있습니다. 

     

    이 글에서는 HTTP의 역사를 살펴보고, 버젼에 따라 중점적인 디자인 변경사항을 알아보도록 하겠습니다:

     

    • HTTP 0.9
    • HTTP 1.0
    • HTTP 1.1
    • HTTP 2.0
    • HTTP/3

    HTTP 0.9

    '팀 버너스 리'에 의해 제안된 초기의 HTTP는 그의 다른 아이디어인 WWW(World Wide Web)의 적용을 위해 '단순함을 염두해두고' 디자인 되었습니다. 그리고 그러한 의도는 잘 작동하는 듯 하였습니다.

     

    1991년, 버너스 리는 새로운 프로토콜에 대한 필요성을 제안하며 몇 가지 디자인 목표를 제시하였습니다. 그것들은 바로 파일 전송 기능, 하이퍼텍스트 아카이브를 인덱스 검색 요청을 할 수 있는 기능, 포맷-변경 가능한 부분, 클라이언트에게 다른 서버를 참조하도록 하는 기능이었습니다. 이론을 실체화하기 위해서 간단한 프로토타입이 만들어졌고, 그 프로토타입을 요구된 기능들의 일부만을 구현하였습니다.

     

    • 클라이언트 요청은 단일한 ASCII 글자 스트링
    • 클라이언트 요청은 캐리지 리턴을 통해 끝남 (CRLF)
    • 서버 응답은 ASCII 글자 스트림
    • 서버 응답은 하나의 하이퍼텍스트 마크업 언어 (HTML)
    • 연결(Connection)은 문서 전송이 완결된 후에 종료됨

     

    비록 위의 기능들이 실제보다 복잡해보여도, 이러한 규칙들이 가능하게 하는 것은 매우 간단하고 현재까지도 몇몇의 웹서버가 지원하는 텔넷-freindly한 프로토콜이었습니다:

     

    $> telnet google.com 80
    
    Connected to 74.125.xxx.xxx
    
    GET /about/
    
    (hypertext response)
    (connection closed)​

     

    요청은 GET 메소드와 요청하는 문서의 패스로 구성되며 한 줄로 이뤄져 있습니다. 그에 대한 응답은 단일한 하이퍼텍스트 문서로 헤더도 없고, 다른 메타데이터도 없고, HTML만을 가집니다. 이러한 프로토타입은 요구사항 기능들의 일부를 구현했기에, 비공식적으로 HTTP 0.9라는 라벨이 붙게 되었습니다. 

     

    HTTP는 이러한 비교적 단순한 형태로 1991년에 시작되어, 이후 빠르게 진화하고 발전하게 되었습니다. HTTP 0.9를 요약하면 다음과 같습니다:

     

    • 클라이언트-서버, 요청-응답 프로토콜
    • TCP/IP 링크 위에서 동작하는 ASCII 프로토콜
    • 하이퍼텍스트 문서(HTML)을 전송하기 위해 디자인됨
    • 서버와 클라이언트 간의 연결은 각 요청 이후 닫힘(closed)

     

    HTTP 1.0

    1991년부터 1995년은 HTML의 명세, 웹 브라우저, 인터넷 인프라가 빠르게 진화하고 서로 영향을 주며 발전하던 시기였습니다. 새로이 발전하는 웹과 퍼블릭 웹의 사용례들에서의 다양한 요구사항들은 HTTP 0.9의 한계점을 더욱 부각시켰습니다. 그러한 요구사항들에는 하이퍼텍스트 문서가 아닌 데이터의 전송, 요청과 응답에 대한 더욱 상세한 메타데이터 제공, 컨텐츠 협의를 가능하게 하는 기능 등이 있었습니다. 그 결과 여러 웹 개발자 커뮤니티가 만들어지며 다양한 실험적인 HTTP 서버와 클라이언트를 구현하고, 배포하고, 사용자 피드백을 받아 수정하는 사이클이 돌아가게 되었습니다. 

     

    이러한 빠른 실험 기간 동안 몇 개의 베스트 프랙티스와 패턴이 나타났고, 1996년 HTTP Working Group (HTTP-WG)는 RFC 1945를 내놓았습니다. 거기에는 그러한 여러 실험적 HTTP 1.0 구현체들의 '주요 사용례'를 기술하였습니다. 그렇기에 이것은 단순히 정보를 전달하기 위한 RFC이며, HTTP 1.0은 공식적인 명세나 인터넷 스탠다드가 아닙니다. 

     

    그러므로, HTTP 1.0 요청은 0.9와 매우 비슷합니다:

     

    $> telnet website.org 80
    
    Connected to xxx.xxx.xxx.xxx
    
    GET /rfc/rfc1945.txt HTTP/1.0    - (1)
    User-Agent: CERN-LineMode/2.15 libwww/2.17b3
    Accept: */*
    
    HTTP/1.0 200 OK    - (2)
    Content-Type: text/plain
    Content-Length: 137582
    Expires: Thu, 01 Dec 1997 16:00:00 GMT
    Last-Modified: Wed, 1 May 1996 12:45:26 GMT
    Server: Apache 0.84
    
    (plain-text response)
    (connection closed)

     

    (1) 'GET ~'은 요청이 시작되는 줄로 HTTP 버젼과 이어지는 헤더값을 가집니다. (2) 'HTTP/1.0 200 OK' 이후는 응답 상태로 이어지는 응답 헤더값을 가집니다. 

     

    위 요청-응답은 모든 HTTP 1.0 기능을 포함한 것은 아니지만, 몇 가지 프로토콜 변경사항을 잘 보여주고 있습니다:

     

    • 요청은 헤더 필드로 구분된 여러 줄로 이뤄져 있음
    • 응답 객체는 첫 줄의 응답 상태 줄로 구분됨
    • 응답 객체는 헤더 필드로 구분된 여러 줄로 구성되어 있음
    • 응답 객체는 하이퍼텍스트에만 국한되지 않음
    • 서버와 클라이언트 간의 연결은 각 요청 이후에 닫힘

    요청과 응답 헤더는 모두 ACSII 인코딩되어 있지만, 응답 객체 자체는 텍스트 파일, 이미지 등등의 여러가지 타입이 될 수 있습니다. 그러므로 HTTP 정의의 "hypertext transfer"라는 부분은 초기 버젼 이후 잘못된 표기가 되었습니다. 실제로 HTTP는 빠르게 진화하여 "hypermedia transport"가 되었으나, 그냥 이전의 이름이 사용되고 있습니다.

     

    미디어 타입 조정 기능에 더해서, RFC는 흔히 여러 구현체에서 구현된 기능들을 문서화 해두었습니다. 그러한 기능들에는 컨텐츠 인코딩, 다양한 글자 지원, 멀티파트 타입, 인가, 캐싱, 프록시, 날짜 형식 등이 포함됩니다. 

     

    HTTP 1.1: Internet Standard

    HTTP를 공식적인 IETF 인터넷 스탠다드 반열에 올리기 위한 기반은 HTTP 1.0에서의 개선을 문서화하는 작업과 동시에 4년간 진행되었습니다 (1995 ~ 1999). 공식적인 HTTP 1.1 스탠다드는 RFC 2068에 정의되었고, 1997년 1월에 공식적으로 릴리즈 되었습니다 (HTTP 1.0이 출시된지 6개월 이후). 그리고 2년 반이 지나서, 1999년 6월에 여러 개선과 업데이트가 스탠다드에 편입되어 RFC 2616으로 릴리즈 되었습니다. 

     

    HTTP 1.1 스탠다드는 이전 버젼에 존재하던 여러 프로토콜의 모호함을 제거하고 몇 가지 크리티컬한 성능 개선을 도입했습니다. 그러한 부분들에는 keepalive 코넥션, chunked encoding transfers, byte-range requests, 추가적인 캐싱 메커니즘, transfer encoding, 그리고 request pipelining 등이 있습니다.

     

    이러한 역량들이 합쳐져서, 모던 HTTP 브라우져와 클라이언트가 수행하는 아래와 같은 전형적인 HTTP 1.1를 이루게 되었습니다:

     

    $> telnet website.org 80
    Connected to xxx.xxx.xxx.xxx
    
    GET /index.html HTTP/1.1    - (1)
    Host: website.org
    User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_4)... (snip)
    Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
    Accept-Encoding: gzip,deflate,sdch
    Accept-Language: en-US,en;q=0.8
    Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3
    Cookie: __qca=P0-800083390... (snip)
    
    HTTP/1.1 200 OK    - (2)
    Server: nginx/1.0.11
    Connection: keep-alive
    Content-Type: text/html; charset=utf-8
    Via: HTTP/1.1 GWA
    Date: Wed, 25 Jul 2012 20:23:35 GMT
    Expires: Web, 25 Jul 2021 20:23:35 GMT
    Cache-Control: max-age=0, no-cache
    Transfer-Encoding: chunked
    
    100    - (3)
    <!doctype html>
    (snip)
    
    100
    (snip)
    
    0    - (4)
    
    GET /favicon.ico HTTP/1.1.   - (5)
    Host: www.website.org
    User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_4)... (snip)
    Accept: */*
    Referer: http://website.org/
    Connection: close    - (6)
    Accept-Encoding: gzip,deflate,sdch
    Accept-Language: en-US,en;q=0.8
    Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3
    Cookie: __qca=P0-800083390... (snip)
    
    HTTP/1.1 200 OK    - (7)
    Server: nginx/1.0.11
    Content-Type: image/x-icon
    Content-Length: 3638
    Connection: close
    Last-Modified: Thu, 19 Jul 2012 17:51:44 GMT
    Cache-Control: max-age=315360000
    Accept-Ranges: bytes
    Via: HTTP/1.1 GWA
    Date: Sat, 21 Jul 2012 21:35:22 GMW
    Expires: Thu, 31 Dec 2037 23:55:55 GMT
    Etag: W/PSA-GAu26oXbDi
    
    (icon data)
    (connection closed)
    Expires: Web, 25 Jul 2021 20:23:35 GMT
    
    Transfer-Encoding: chunked

    (1) HTML 파일 요청 (인코딩, charset과 쿠키 메타데이터와 함께)

    (2) HTML 요청에 대한 Chunked 응답

    (3) ASCII 16진수로 표현한 해당 청크의 octets 수

    (4) chunked stream 응답 종료

    (5) 동일한 TCP 연결에 발생한 icon 파일 요청

    (6) 서버에게 해당 연결이 재사용되지 않을 것임을 알림

    (7) Icon 응답과 연결 종료

     

    가장 먼저 살펴볼 수 있는 부분은 2개의 요청 객체가 존재한다는 부분입니다. 하나는 HTML 페이지에 대한 것, 다른 하나는 이미지에 대한 것으로 2가지 모두 한 개의 연결을 통해 전달되었습니다. 이것은 연결 keepalive을 이용한 것으로, 기존에 존재하는 TCP 연결을 동일한 호스트에 대한 여러 요청에 사용할 수 있도록 하며 더욱 빠른 사용자 경험을 제공합니다.

     

    잔존한 연결을 종료하기 위해, 두 번째 클라이언트 요청은 Connection 헤더를 통해 명시적인 close 토큰을 서버에 보냅니다. 유사하게, 서버는 응답이 보내질 때, 현재 TCP 연결을 close한다는 것을 표현하는 데이터를 보냅니다. 기술적으로는 양쪽 모두 그러한 시그널 없이 언제나 연결을 종료할 수 있지만, 양쪽 모두에서 연결 재사용 메커니즘을 가능하기 위해서 그러한 시그널을 제공해야 합니다. 

     

    추가적으로 HTTP 1.1 프로토콜은 각 요청별로 달라질 수 있는 컨텐츠, 인코딩, 캐릭터 세트, 언어, 전송 인코딩, 캐싱, 클라이언트 쿠키 등을 가능하게 합니다. 

     

    HTTP 2.0

    발행되었을 때부터, 이례로 RFC 2616은 엄청나게 성장한 인터넷을 위한 기반을 제공해 왔습니다. 

     

    HTTP는 초기의 하이퍼텍스트를 꺼내기 위한  간단한 한 줄의 프로토콜에서 일반적인 하이퍼미디어 전송을 위한 것으로 진화하고, 10년 후에는 상상할 수 있는 모든 것을 지원할 수 있는 프로토콜이 되었습니다. 어디에나 존재하는 HTTP 서버와 그것을 소비하는 클라이언트는 많은 애플리케이션들이 이제 배타적으로 HTTP를 위해 디자인되고 배포되는 것을 의미합니다. 

     

    이제 많은 임베디드 기기(센서, actuator, 커피 포트 등)들도 HTTP를 통해 데이터를 주고 받습니다. 그러나 이러한 폭증하는 성공 속에서 수많은 연결은 전체 인프라에 스트레스를 주고, 점점 준-실시간 응답성을 요구하며 성능에 대한 문제가 발생하게 되었습니다. 이러한 성능은 기존의 HTTP 1.1 하에서 많은 제약이 있었습니다. 

     

    이러한 문제를 해결하기 위해, HTTP는 계속 진화해야 되었고, HTTPbis 워킹 그룹은 2012년 초에 HTTP 2.0에 대한 초안을 발표했습니다. 

     

    2015년에 정식으로 릴리즈되어, 현재 모든 거의 브라우저가 지원하고 있습니다.

     

    HTTP/2.0 - caniuse.com

     

    HTTP 2.0 주요 목적은 전송 성능을 개선하고 낮은 지연속도와 높은 처리량을 가능하게 하는 것이었습니다. 버젼을 올린다는 점은 인지하기에도 큰 변화이고 실제로 성능과 관련해 매우 많은 개선이 이루졌으나, 하이-레벨의 프로토콜(헤더, 값, 사용방식 등)은 변경되지 않았습니다. 

     

    그렇기에 기존에 존재하는 웹사이트나 애플리케이션도 변경 없이 HTTP 2.0을 통해 전송될 수 있으며, HTTP 2.0을 사용하기 위해 애플리케이션 마크업을 변경할 필요가 없습니다. 

     

    HTTP 3.0

    HTTP 3.0은 HTTP 2.0의 후속 버젼으로 역시 HTTP의 시맨틱은 변경되지 않습니다 [7]. 그 의미는 요청 방법, 상태 코드, 메시지 필드 등은 모든 버젼에서 동일하다는 것입니다. 버젼 간의 차이는 이러한 시맨틱을 내부 전송 방식에 어떻게 매핑하느냐에 존재합니다. 

     

    HTTP/1.1과 HTTP/2는 TCP를 전송에 사용하지만, HTTP/3은 QUIC [4]을 사용합니다. QUIC은 전송-레이어 네트워크 프로토콜로 UDP에 기반한 user space congestion control을 사용합니다. QUIC으로의 변경은 HTTP/2에 존재하는 주요 문제점인 "head-of-line blocking"을 피하기 위함입니다. "head-of-line blocking"은 HTTP/2 멀티플렉싱의 병렬적인 특성이 TCP의 loss recovery 메커니즘에서 인식할 수 없기에 , 잃어버리거나 순서가 재조정된 패킷은 트랜적션이 그러한 패킷에 영향을 받는 것에 상관 없이 모든 active 트랜잭션이 중단을 겪도록 합니다. QUIC에서는 native 멀티플렉싱을 지원하기에, 잃어버린 패킷은 데이터가 소실된 스트림에만 영향을 주게 됩니다.

     

    2021년 7월 기준으로, HTTP/3은 공식적으로 Internal Draft 상태이나 이미 72%의 웹브라우저가 지원하고 있으며, W3Techs에 따르면 탑 1000만개의 웹사이트가 지원하고 있습니다. 

     

    Reference

    [1] High-Performance Browser Networking

    [2] https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol

    [3] https://developer.mozilla.org/en-US/docs/Web/HTTP

    [4] https://en.wikipedia.org/wiki/QUIC

    [5] https://en.wikipedia.org/wiki/HTTP/2

    [6] https://developers.google.com/web/fundamentals/performance/http2

    [7] https://en.wikipedia.org/wiki/HTTP/3

    [8] https://github.com/quicwg/base-drafts

     

     

    반응형
Kaden Sungbin Cho