HTTP 버전별 특징

윤석주·2022년 9월 19일
0

네트워크

목록 보기
13/13

Overview

Http는 Tim Berners-Lee가 HTML을 통신하기 위해 만들어진 프로토콜이 시초입니다.

단순한 0.9를 제외한 각각의 버전의 기본적인 특징은 다음과 같습니다.

  • HTTP1.0 - 나온지 얼마 되지 않아 1.1로 넘어갔다. 1.0 당시에는 request마다 TCP 연결을 다시 수립해야 한다. html, css, js등의 파일을 받는 경우 각각의 리소스마다 TCP연결의 재수립이 필요하다.
  • HTTP1.1 - TCP를 1회 연결한 뒤, 필요한 리소스를 다 받은 후 TCP 연결을 종료한다(특정 설정으로 1번만 연결하고 필요한 파일을 계속 요청도 가능). -> TCP 커넥션이 재사용 될 수 있도록 한다.
  • HTTP2.0 - I/O 멀티 플랙싱이 가능하다. 여러 리소스에 대한 병렬 response가 가능하다.
  • HTTP3.0 - TCP/TLS가 아니라 UDP기반의 QUIC을 사용한다.

월드 와이드 웹의 발명

1989년 제네바의 CERN에서 일하고 있던 Tim Berners-Lee는 인터넷 상의 하이퍼텍스트 시스템을 만들기 위한 제안을 작성했습니다. 초기에 Mesh라 불리던 것은 구현 과정에서 월드 와이드 웹으로 이름을 바꿨습니다. 기존의 TCP/IP 프로토콜 상에서 만들어지면서 4개의 빌딩 블록으로 구성되었습니다.

  • 하이퍼텍스트 마크업 언어 (HTML)
  • 하이퍼텍스트 전송 프로토콜 (HTTP)
  • 문서를 디스플레이하기 위한 클라이언트인 월드 와이드 웹이라 불리는 첫 번째 브라우저
  • 문서에 접근하도록 해주는 httpd의 초기 버전

이 네 개의 빌드 블록은 1990년 말에 완료되었으며, 첫번째 서버는 1991년 초 CERN 외부에서 가동을 시작했습니다.

이렇게 초기 단계에서 사용되던 HTTP 프로토콜은 매우 간단했으며 이후 HTTP/0.9 버전을 부여했으며 원-라인 프로토콜로 불리기도 했습니다.

버전별 특징

HTTP0.9

HTTP 초기 버전에는 버전 번호가 없었습니다. HTTP/0.9는 이후에 차후 버전과 구별하기 위해 0.9로 불리게 됐습니다. HTTP/0.9는 극히 단순합니다. 요청은 단일 라인으로 구성되며 리소스에 대한 경로로 사용 가능한 메서드는 GET이 유일했습니다.

GET /mypage.html

응답 또한 극도로 단순합니다. 오로지 파일 내용 자체로 구성됩니다.

<HTML>
A very simple HTML page
</HTML>

이후 버전들과 다르게 HTTP 헤더가 없었는데 이는 HTML 파일만 전송될 수 있으며 다른 유형의 문서는 전송될 수 없음을 의미합니다. 상태 혹은 오류 코드도 없었습니다. 문제가 발생한 경우, 특정 HTML 파일이 해당 파일 내부에 문제에 대한 설명과 함께 사람이 처리할 수 있도록 되돌려 보내졌었습니다.

HTTP1.0

매우 제한적인 0.9에 비해 브라우저와 서버 모두 좀 더 융통성을 가지도록 빠르게 확장되었습니다.

  • 버전 정보가 각 요청 사이내로 전송되기 시작 (HTTP/1.0이 GET 라인에 붙은 형태로)
  • 상태 코드 라인 또한 응답의 시작 부분에 붙어 전송되어, 브라우저가 요청에 대한 성공과 실패를 알 수 있고 그 결과에 대한 동작을 할 수 있게 됨
  • HTTP 헤더 개념은 요청과 응답 모두를 위해 도입되어, 메타데이터 전송을 허용하고 프로토콜을 극도로 유연하고 확장 가능하도록 만듬.
  • 새로운 HTTP 헤더의 도움으로, 평이한 HTML 파일들 외에 다른 문서들을 전송하는 기능이 추가됨.(Content-Type 덕분에)

일반적인 요청과 응답 예시입니다.

GET /mypage.html HTTP/1.0
User-Agent: NCSA_Mosaic/2.0 (Windows 3.1)

200 OK
Date: Tue, 15 Nov 1994 08:12:31 GMT
Server: CERN/3.0 libwww/2.17
Content-Type: text/html
<HTML>
A page with an image
   <IMG SRC="/myimage.gif">
</HTML>

두 번째 커넥션에 의한 이미지를 내려받기 위한 요청과 그에 대한 응답입니다.

GET /myimage.gif HTTP/1.0
User-Agent: NCSA_Mosaic/2.0 (Windows 3.1)

200 OK
Date: Tue, 15 Nov 1994 08:12:32 GMT
Server: CERN/3.0 libwww/2.17
Content-Type: text/gif
(image content)

HTTP1.1 - 표준 프로토콜

1995년 부터 다양한 HTTP/1.0 구현이 동시에 진행되어, 그 이듬해 HTTP/1.0 문서 출간 전까지, 합당한 표준화가 진행 중에 있었습니다. HTTP의 첫번째 표준 버전인 HTTP/1.1은 HTTP/1.0이 나온지 몇 달 안되서 1997년 초에 공개되었습니다.

HTTP/1.1은 모호함을 명확하게 하고 많은 개선 사항들을 도입했습니다.

  • 커넥션 재사용을 도입, 단일 우너본 문서 내로 임베드된 리소스들을 디스플레이하기 위해 사용된 커넥션을 다시 열어 시간을 절약.
  • 파이프라이닝을 추가하여, 첫번째 요청에 대한 응답이 완전히 전송되기 전에 두번째 요청 전송을 가능케 하여, 커뮤니케이션 레이턴시를 낮춤.
  • 청크된 응답 지원.
  • 추가적인 캐시 제어 메커니즘 도입.
  • 언어, 인코딩 혹은 타입을 포함한 커텐츠 협상이 도입되어, 클라이언트와 서버로 하여금 교환하려는 가장 적합한 콘텐츠에 대한 동의를 가능하도록 함.
  • Host 헤더 덕분에, 동일 IP 주소에 다른 도메인을 호스트하는 기능이 서버 코로케이션을 가능하도록 함.

다음은 하나의 단일 커넥션을 통한 요청의 전형적인 흐름 예시입니다.

GET /en-US/docs/Glossary/Simple_header HTTP/1.1
Host: developer.mozilla.org
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:50.0)
Gecko/20100101 Firefox/50.0
Accept:
text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US, en;q=0.5
Accept-Encoding: gzip, deflate, br
Referer: https://developer.mozilla.org/en-US/docs/Glossary/Simple_header

200 OK
Connection: Keep-Alive
Content-Encoding: gzip
Content-Type: text/html; charset=utf-8
Date: Wed, 20 Jul 2016 10:55:30 GMT
Etag: "547fa7e369ef56031dd3bff2ace9fc0832eb251a"
Keep-Alive: timeout=5, max=1000
Last-Modified: Tue, 19 Jul 2016 00:59:33 GMT
Server: Apache
Transfer-Encoding: chunked
Vary: Cookie, Accept-Encoding

(content)

GET /static/img/header-background.png HTTP/1.1
Host: developer.mozilla.org
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:50.0) Gecko/20100101 Firefox/50.0
Accept: */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Referer: https://developer.mozilla.org/en-US/docs/Glossary/Simple_header

200 OK
Age: 9578461
Cache-Control: public, max-age=315360000
Connection: keep-alive
Content-Length: 3077
Content-Type: image/png
Date: Thu, 31 Mar 2016 13:34:46 GMT
Last-Modified: Wed, 21 Oct 2015 18:27:50 GMT
Server: Apache

(image content of 3077 bytes)

HTTP/1.1은 1997년 1월에 RFC 2068에서 처음 공개되었습니다.

15년 넘게 진행된 확장

(새로운 헤더 혹은 메서드를 생성하기 쉬운) 확장성 덕분에, 1999년 6월에 공개된 RFC 2616과 HTTP/2 릴리즈의 예건 속에서 2014년 6월에 공개된 RFC 7230-RFC 7235 시리즈, 두 번에 걸친 리비전을 통한 정재에도, 이 프로토콜은 15년 넘도록 극도로 안정성을 유지해왔습니다.

보안 전송을 위한 HTTP 사용

HTTP에 일어났던 가장 큰 변화는 1994년 말에 이미 완료되었습니다. 기본적인 TCP/IP 스택을 통해 HTTP를 전송하는 대신, 넷스케이프 커뮤니케이션은 그것의 토대 위에 추가적인 암호화된 전송 계층인 SSL을 만들어 냈습니다. SSL 1.0은 회사 외부로 릴리즈된 적이 없으며, SSL 2.0과 그것의 후계자인 SSL 3.0과 SSL 3.1은 서버와 클라이언트 간에 교환된 메시지 인증을 암호화하고 보장하여 e-커머스 웹 사이트를 만들어내도록 했습니다. SSL은 표준 트랙 상에 놓여져 있었고 마침내 TLS가 되어, 성공적으로 취약성을 종식시키는 1.0, 1.1 그리고 1.2 버전이 나와있습니다. TLS 1.3은 현재 진행 중에 있습니다.

같은 시간 동안, 암호화된 전송 계층에 대한 필요성이 대두되었습니다. 웹은 광고주, 불특정 개인, 혹은 범죄자가 다른 사람인척 가장하거나 전송된 데이터를 수정된 데이터로 대치시키고자, 개인 정보를 빼내려고 경쟁하는 정글속에, 거의 학문적인 네트워크의 상대적인 신뢰를 남겨두었습니다. HTTP 상에서 만들어진 어플리케이션들이 주소록, 이메일, 사용자의 지리적 위치와 같은 수 많은 개인 정보에 접근하는 등 점점 강력해짐에 따라, TLS의 필요성은 e-커머스 사용 케이스 외에 여기 저기서 나타나게 되었습니다.

복잡한 어플리케이션을 위한 HTTP 사용

웹에 대한 Tim Berners-Lee의 본래 비전은 읽기 전용의 매체는 아니었습니다. 그는 사람들이 문서를 원격으로 추가하거나 이동시킬 수 있는, 분산된 파일 시스템의 한 종류로 웹을 상상했었습니다. 1996년 쯤, HTTP는 저작을 허용하도록 확장되었으며 WebDAV라고 불리는 표준이 만들어졌습니다. 이런 모든 *DAV 확장들은 한 가지 결점이 있었는데요. 꽤 복잡한, 사용하고 있는 서버에 의해 구현되어야만 한다는 것이었습니다.

그러다 2000년에, HTTP 사용에 대한 새로운 패턴이 고안되었습니다. 우리가 잘 아는 representational state transfer(REST) API에 의해 유도되는 액션들은 새로운 HTTP 메서드 뿐만 아니라, 기초적인 HTTP/1.1 메서드를 이용한 특정 URI 접근에 의해서도 더 이상 전달되지 않았습니다. 이는 모든 웹 어플리케이션으로 하여금 브라우저나 서버의 갱신없이 데이터 탐색과 수정을 허용하는 API 제공을 가능케했습니다. 필요로 하는 모든 것은 표준 HTTP/1.1을 통해 웹 사이트에 의해 서브되는 파일 내로 임베드 되는 것이었습니다.

2005년부터, 웹 페이지에서 사용 가능한 API 집합들이 급격히 늘어나게 되었고 이들 API 중 몇몇은, 거의 새로운 특성화된 HTTP 헤더로, 특정한 목적을 위해 HTTP 프로토콜에 확장을 만들어냈습니다.

  • 서버 전송 이벤트, 서버가 브라우저로 이따금씩 보내는 메시지를 푸쉬할 수 있는 곳.
  • 웹소켓, 기존 HTTP 커넥션을 업그레이드하여 만들 수 있는 새로운 프로토콜

웹의 보안 모델 완화

HTTP는 웹의보안 모델인 same-origin정책에서 독립되어 있습니다. 몇 년에 걸쳐, 이 정책의 몇 가지 정책을 고무시키기 위해 확실한 제약사항 아래 허용함으로써, 좀 더 관대해지도록 하는 것이 유용하다는 것을 증명해왔습니다. 제약사항이 얼마나 그리고 언제 리프트될지는 HTTP 헤더의 새로운 묶음들을 사용하는 서버부터 클라이언트에 의해 전도됩니다. 이러한 내용들은 Cross-Origin 리소스 공유 (CORS) 혹은 컨텐츠 보안 정책 (CSP)과 같은 스펙 내에 정의되어 있습니다.

이런 커다란 확장에 덧붙여, 다른 많은 헤더들이 추가되어 오고 있습니다. 프라이버시를 제어하기 위한 Do Not Track (DNT)헤더, X-Frame-Options, 혹은 Upgrade-Insecure-Request 등이 있고, 그 외에도 수많은 헤더들이 존재합니다.

HTTP2.0 - 더 나은 성능을 위한 프로토콜

몇 년에 걸쳐, 웹 페이지는 매우 복잡해졌습니다. 디스플레이되는 시각적 미디어의 양에 덧붙여 상호작용을 추가하기 위한 스크립트의 양과 크기는 점점 더 많이 증가하고 있습니다. 더 많은 데이터들이 더 많은 요청 너머로 전송되고 있죠. HTTP/1.1 커넥션은 올바른 순서로 전송되는 요청을 필요로 합니다. 또한, 몇몇 병렬 커넥션이 이론적으로 사용 가능한 경우 여전히 많은 양의 오버헤드와 복잡도가 남아 있습니다.

2010년 전반기에, Google은 실험적인 SPDY 프로토콜을 구현하여, 클라이언트와 서버 간의 데이터 교환을 대체할 수단을 실증하였습니다. 응답성 증가 능력을 입증하고 전송된 데이터 중복에 관한 문제를 해결하면서, SPDY는 HTTP/2 프로토콜의 기초로써 기여했습니다.

HTTP/2 프로토콜은 1.1 버전과 다른 몇가지 근본적인 차이점을 가지고 있습니다.

  • 텍스트 프로토콜이라기 보다 이진 프로토콜입니다. 더 이상 읽을 수도 없고 수작업을 만들어낼 수 없습니다. 이런 결점에 대한 보상으로 새로운 최적화 기술이 구현될 수 있습니다.
  • 병렬 요청이 동일한 커넥션 상에서 다루어질 수 있는 다중화 프로토콜로, 순서를 제거해주고 HTTP/1.x 프로토콜의 제약사항을 막아줍니다.
  • 전송된 데이터의 분명한 중복과 불필요한 오버헤드를 제거하면서, 연속된 요청 사이의 매우 유사한 내용으로 존재하는 헤더들을 압축시킵니다.
  • 서버로 하여금 사전에 클라이언트 캐시를 서버 푸쉬라고 불리는 메커니즘에 의해, 필요하게 될 데이터로 채워넣도록 허용합니다.

HTTP2는 HTTP/1의 확장으로 기존의 호환성을 유지하며 성능에 초점을 맞춘 프로토콜입니다.

1. Multiplexed Stream

HTTP/2는 하나의 TCP 연결을 통해 여러 데이터 요청을 병렬로 전송할 수 있습니다.

HTTP/2는 Multiplexed Streams를 이용하여 Connection 한 개로 동시에 여러 개의 메시지를 주고 받을 수 있으며 응답은 순서에 상관없이 Stream으로 주고 받습니다. RTT 시간이 줄어들어 별도의 최적화 과정이나 도메인 샤딩없이 웹 사이트 로드 속도가 빨라집니다. HTTP/1.1의 Connection Keep-Alive, Pipelining의 개선된 것을 알 수 있습니다.

2. Header Compression

HTTP/2는 중복 헤더 프레임을 압축해서 전송합니다. HPACK 규격을 사용해 클라이언트와 서버에서 모두 이전 요청에 사용된 헤더 목록을 유지관리합니다. HPACK은 서버로 전송되기 전에 각 헤더의 개별 값을 압축한 다음 이전에 전송된 헤더 값 목록에서 인코딩된 정보를 조회하여 전체 헤더 정보를 재구성합니다.

모바일과 같이 업로드 대역폭이 상대적으로 작은 경우 이런 HTTP 헤더 압축 방법이 특히 유용합니다. 오늘날의 HTTP 헤더는 평균 2KB 가량이고, 점점 더 커지는 추세이기 때문에 HTTP 헤더 압축의 가치는 앞으로 더 커질 것이라고 합니다.

3. Binary protocol

텍스트 프로토콜에서 바이너리 프로토콜로 변화했습니다. 기존 HTTP/1에서 사용된 frame의 복잡성을 편리하게 해주고, 텍스트와 공백들이 섞여 혼동이 발생하던 명령들보다 명령어를 단순하게 구현할 수 있습니다. HTTP/2 구현을 사용하는 브라우저는 네트워크를 통해 전송하기 전에 동일한 텍스트 명령을 바이너리로 변환합니다.

바이너리 프로토콜을 사용하는 장점은 다음과 같습니다.

  • 데이터 파싱이 더 빠르고, 오류 발생 가능성이 낮음
  • 네트워크 리소스의 효과적 사용
    • 네트워크 지연 시간을 줄이고 처리량 개선
  • 텍스트 특성과 관련된 보안 문제 해결 가능 (EX. Response Splitting Attacks)
  • HTTP/2의 다른 기능을 활성화
    • 압축, 멀티플렉싱, 우선 순위 지정, 흐름 제어 및 TLS의 효과적인 처리 등

차세대-HTTP/2로의 진화

2016년에 나타난 주목할만한 HTTP의 새로운 확장들은 다음과 같습니다.

  • Alt-Svc (en-US) 지원은 좀 더 영리한 CDN (en-US) 메커니즘을 따라, 신분 증명의 개념과 주어진 자원의 위치를 분리하도록 해줍니다.
  • Client-Hints의 도입으로 브라우저, 클라이언트가 요구사항이나 서버의 하드웨어 제약사항에 관한 정보를 사전에 미리 주고 받을 수 있게 되었습니다.
  • Cookie 내에 보안 관련 접두사 도입은 보안 쿠키가 변경되지 않았다는 것을 보장하는데 도움을 줍니다.

Server Push

서버는 요청되지 않았지만 향후 요청에서 예상되는 추가 정보를 클라이언트에 전송할 수 있습니다. 예를 들어, 클라이언트가 리소스 X에 대해 요청하고 리소스 Y가 요청된 X파일에서 참조되는 경우, 서버는 클라이언트 요청을 기다리는 대신 X와 함께 Y를 푸시하도록 선택할 수 있습니다.

Server Push는 다음과 같은 장점을 갖고 있습니다.

  • 클라이언트는 푸시된 리소스를 캐시에 저장
    • 캐시된 리소스를 여러 페이지에 걸쳐 재사용 가능
  • 서버는 멀티플렉싱으로 요청한 정보와 함께 푸시된 리소스를 전송 가능
  • 서버는 푸시되는 리소스의 우선 순위를 지정할 수 있음
  • 클라이언트의 선택적 리소스 관리
    • 푸시된 리소스를 거부하거나 서버 푸시를 비활성화할 수 있음
  • 클라이언트가 멀티플렉싱되는 푸시 스트림 수 제한 가능

Stream Prioritization

클라이언트가 선호하는 응답 수신 방식을 지정해서 응답을 받을 수 있습니다. 문서 내에 CSS 파일 1개와 이미지 파일 2개가 존재하고 이를 클라이언트가 요청한다고 가정해봅시다. 이미지 파일보다 CSS 파일의 수신이 늦어진다면 브라우저 렌더링에 문제가 생길 수 있는데, HTTP/2에서는 이러한 상황을 고려하여 리소스 간의 의존관계에 따른 우선순위를 설정하여 리소스 로드 문제를 해결할 수 있습니다.

HTTP3.0 - HTTP over QUIC

Experimental: HTTP 3.0은 실험적 기술입니다.

HTTP/3 에서는 전송 계층 부분에 TCP/TLS 대신 QUIC가 사용됩니다. Firefox 에서의 구현 상태는 bug 1158011을 참조해주세요.

QUIC

Quick UDP Internet Connection은 UDP 상에 구현된 실험적인 다중 전송 프로토콜로 TCP 및 웹 어플리케이션 전송을 개선하기 위한 방법을 위해 Google에서 실험적으로 개발했습니다.

TCP는 많은 운영 체제 커널에 내장되어 있기 때문에 변경사항을 실험하고 수정을 구현하는 것에 시간이 많이 드는 과정이기에, QUIC을 만들어 개발자는 더 빠르게 실험할 수 있고, 새로운 것을 시도할 수 있습니다.

QUIC은 HTTP/2의 의미론적 지원을 위해 설계되었습니다. 멀티플랙싱, 흐름 제어, 보안 및 혼잡 제어를 제공해줍니다.

다음은 QUIC의 중요한 기능입니다.

  • 연결 설정 시간 단축
  • 혼잡 제어 개선
  • Head of Line Blocking 없는 멀티플렉싱
  • 전달 오류 수정
  • 연결 마이그레이션

현재는 QUIC을 지원하는 브라우저와 서버가 그리 많지 않습니다.

출처

profile
웹 개발을 공부하고 있는 윤석주입니다.

0개의 댓글