개요

HTTP는 HyperText Transfer Protocol의 약자이며, WWW 상에서 정보를 주고받을 수 있는 프로토콜이다.
주로 HTML 문서를 주고받는 데에 쓰인다.
HTTP 통신을 위해서 기본적으로 쓰이는 포트는 80 이다.
HTTP는 클라이언트와 서버 사이에서 이루어지는 응답과 요청으로 이루어진 프로토콜이다.

1989년 '버너스 리'에 의해 WWW 탄생했고, 이때 사용한 최초의 프로토콜이 HTTP이다.
최초의 HTTP는 페이지를 요청하는 GET이라는 메소드만 존재했다.
그렇게 클라이언트가 GET 메소드로 서버에 요청을 보내면 서버에서는 HTML만 보내줬다.

1991년에 HTTP(RFC 1945) 최초 문서가 올려졌고 당시의 버전을 HTTP V0.9라고 한다.
1996년 HTTP V1.0은 확장된 조작, 확장된 협상, 더 보강된 메타 정보, 추가 메소드와 헤더 필드를 통한 더 효율적인 보안 프로토콜을 갖춘 프로토콜로 확장되길바라며 도입되었다.

HTTP WG(Working Group)은 1995년 12월 새로운 표준을 출간하기로 계획하였으며
당시 개발 중인 RFC 2068(HTTP-NG)에 기반한 이전 표준 HTTP/1.1에 대한 지원이
1996년 초에 주요 브라우저 개발자들에 의해 빠르게 채택되었다.
1996년 3월, 이전 표준 HTTP/1.1을 지원한 웹 브라우저로 넷스케이프 2.0 IE 2.0 등이 있다.
HTTP/1.1 표준은 공식적으로 1997년 1월에 출시되었다.

2007년에 부분적으로 HTTP/1.1 사양을 개정하고 분명히 하기 위해 HTTPbis WG이 창설되었다.
2014년 6월, WG은 RFC 2616을 Obsolete 처리하는 업데이트 된 6 파트 사양을 출시했다.

  • RFC 7230 : HTTP/1.1 - Message Syntax and Routin
  • RFC 7231 : HTTP/1.1 - Semantics and Content
  • RFC 7232 : HTTP/1.1 - Conditional Requests
  • RFC 7233 : HTTP/1.1 - Range Requests
  • RFC 7234 : HTTP/1.1 - Caching
  • RFC 7235 : HTTP/1.1 - Authentication

HTTP/2는 2015년 5월 RFC 7540으로 출판되었다.

HTTP 상태 코드

HTTP 상태 코드

HTTP / 0.9 원-라인 프로토콜

HTTP 초기 보전에는 버전 번호가 없었다.
HTTP/0.9는 이후에 차후 버전과 구별하기 위해 0.9로 불리게 되었다.
HTTP/0.9는 매우 단순하다.
요청은 단일 라인으로 구성되며 리소스에 대한 (프로토콜, 서버, 그리고 포트는 서버가 연결되고 나면 불필요로 하므로 URL은 아닌) 경로로 가능한 메소드는 GET이 유일했다.

GET /index.html

응답 또한 매우 단순하다. 오로지 파일 내용 자체로 구성되어 있다.

<HTML>
Hello World!
</HTML>

HTTP/1.0 - 확장성

HTTP/0.9는 매우 제한적이었으며 브라우저와 서버 모두 좀 더 융통성을 가지도록 빠르게 확장했다.

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

200 OK
Date: Wes, 2 Nov 2020 18:49:30 GMT
Server: CERN/3.0 libwwww/2.17
<HTML>
    Hello World!
    <IMG SRC="/apple.gif">
</HTML>

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

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

200 OK
Date: Wes, 2 Nov 2020 18:49:35 GMT
Server: CERN/3.0 libwwww/2.17
Content-Type: text/gif
(image content)

서버와 브라우저에 기능을 추가한 뒤, 그것이 관심을 끄는지 지켜봤다.
수많은 상호작용의 문제가 일반적이었다.
1996년 11월에, 이런 문제를 해결하기 위해,
일반적인 실제 내용을 설명하는 정보 문서는 RFC 1945에 공개되어있다.
이것이 HTTP/1.0의 정의이며, 용어의 좁은 의미에서 공식적인 표준이 아니라는 것은 주목할 점이다.

HTTP/1.1 - 표준 프로토콜

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

1997년 1월 RFC 2068에서 처음 공개.

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

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

HTTP는 TCP 연결 기반 위에서 동작하는 프로토콜이다.
신뢰성 확보를 위해 연결을 맺고 끊는 데 있어서 핸드 쉐이크가 이루어진다.
게다가 HTTP는 비연결성 프로토콜이기 때문에 한 번 연결로 한번의 요청과 응답을 하고
응답이 끝나면 연결을 끊어 버린다. 연결을 맺고 끊을 때마다 핸드 쉐이크를 하기 때문에
비연결성 프로토콜에선 오버헤드가 생긴다.

최근 웹 서비스들은 하이퍼 택스트라기보다는 많은 정적 데이터로 이루어진 하이퍼 미디어로
발전했기 때문에 오버헤드가 더 크게 생겼다고 할 수 있다.
그래서 HTTP/1.1 에서는 Keep-alive 기능이 추가되어 한 번 맺어졌던 연결을 끊지 않고
지속적으로 유지하여 불필요한 핸드 쉐이크를 줄여 성능을 개선할 수 있다.

현재의 웹 서비스는 예전의 텍스트 위주와는 다르게 점점 미디어들이 추가되고
상태(쿠키, 세션 등)를 유지하려는 기술들이 요구되다 보니 성능 개선이 반드시 필요하게 되었고
이를 위해 부가적인 기능들이 추가되다 H2(HTTP/2)가 탄생하게 되었다.

HTTP/1.1에서 성능 개선을 위해 파이프라이닝이라는 기술이 도입되었다.
파이프라이이닝은 하나의 커넥션에서 한 번에 순차적인 여러 요청을 연송적으로 하고
그 순서에 맞춰 응답을 받는 방식으로 지연 시간을 줄이는 방법이다.
순차적으로 데이터를 요청하고 받아야 하다 보니 먼저 받은 요청이 끝나지 않으면
그 뒤에 있는 요청의 처리가 아무리 빨리 끝나도 먼저 온 요청이 끝날 때 까지 기다려야 한다.
이를 HTTP의 HOL(Head Of Line) Blocking 문제라고 하고 파이프라이닝이 큰 문제이다.
그래서 모던 브라우저들의 대부분은 파이프라이닝을 사용하지 못하도록 막아 놓았다.
그래서 H1으로 통신을 하면 클라이언트가 요청을 병렬로 하기 위해서
6~8개의 커넥션을 이용해 데이터를 가져오는 방식으로 성능을 개선하고 있다.

HTTP /1.1 - 15년간의 확장

보안 전송을 위한 HTTP 사용

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

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

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

웹에 대한 Time Berners-Lee의 본래 비전은 읽기 전용의 매체는 아니었다.
그는 사람들이 문서를 원격으로 추가하거나 이동시킬 수 있는, 분산된 파일 시스템의 한 종류로 웹을 상상했었다. 1996년 쯤, HTTP는 저작을 허용하도록 확장되었으며 WebDAV라고 불리는 표준이 만들어졌다. 그것은 주소록 개체들을 다루기 위한 CardDAV 그리고 달력을 다루기 위한 CalDAV와 같은 특정 애플리케이션들 더 확장되었다.
그러나 이런 모든 DAV 확장들은 한가지 결점을 갖고 있다. 꽤 복잡한 사용하고 있는 서버에 의해 구현되어야만 한다는 것이었다. 웹 영역에서 그것들을 사용하는 것은 극비로 남겨져 있다.

2000년에, HTTP 사용에 대한 새로운 패턴이 고안되었다.
API에 의해 유도되는 액션들은 새로운 HTTP 메소드 뿐만 아니라, 기초적인 HTTP/1.1 메소드를
이용한 특정 URI 접근에 의해서도 더 이상 전달되지 않았다.
이것은 모든 웹 애플리케이션으로 하여금 브라우저나 서버의 갱신없이 데이터 탐색과 수정을 허용하는 API 제공을 가능케했다.
필요로 하는 모든 것은 표준 HTTP/1.1을 통해 웹 사이트에 의해 서브되는 파일 내로 임베디드 되는 것이었다. REST 모델의 단점은 각각의 웹사이트가 자신의 비표준 RESTfull API를 정의하고 그에 대한 전권을 가진다는 사실에 있다.
DAV 확장과는 다르게 클라이언트와 서버들은 상호작용이 가능하다. RESTful API들은 2010년에 들어 매우 일반적인게 되었다.

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

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

웹의 보안 모델 완화

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

이러한 커다란 확장에 덧붙여, 다른 많은 헤더들이, 때로는 실험적으로만, 추가되어 오고 있다.
주목 할 만한 헤더들은 프라이버시를 제어하기 위한 Do Not Track 헤더, X-Frame-Options 혹은 Upgrade-Insecure-Request가 있고, 그외에도 수많은 헤더들이 존재한다.

HTTP/2 - 더 나은 성능을 위한 프로토콜

몇 년에 걸쳐, 웹 페이지는 매우 복잡해지면서, 종종 진정한 애플리케이션이 된다.
디스플레이되는 시각적 미디어의 양에 덧붙여 상호작용을 추가하기 위한 스크립트의 양과 크기는
점점 더 많이 증가하고 있다. 더 많은 데이터들이 더 많은 요청 너머로 전송되고 있다.
HTTP/1.1 커넥션은 올바른 순서로 전송되는 요청을 필요로 한다.
또한, 몇몇 병렬 커넥션이 이론적으로 사용 가능한 경우(일반적으로 5와 8 사이에서),
여전히 많은 양의 오버헤드와 복잡도가 남아 있다.
예를 들면, HTTP 파이프라이닝...

2010년 전반기에, Google은 실험적인 SPDY 프로토콜을 구현하여, 클라이언트와 서버 간의 데이터 교환을 대체할 수단을 실증하였다. 그것은 브라우저와 서버 측 모두에 있어 많은 관심을 불러일으켰다. 응답성 증가 능력을 입증하고 전송된 데이터 중복에 관한 문제를 해결하면서,
SPDY는 HTTP/2 프로토콜의 기초로써 기여했다.

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

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

HTTP/2의 바이너리 프레임과 멀티플렉싱

H2의 핵심은 바이너리 프레이밍 계층을 사용해 요청과 응답의 멀티플렉싱을 지원한다는 것이다.
HTTP 메세지를 바이너리 형태의 프레임으로 나누고 이를 전송 후 받은 쪽에서 다시 조립한다.
요청과 응답이 동시에 이루어지니 하나의 연결에 여러 요청과 응답이 뒤섞여 있다.
프레이밍 작업은 서버와 클라이언트에서 해주기 때문에 큰 변경사항을 고려하지 않아도 된다.
바이너리 프레이밍과 멀티플레싱을 이용해 여러 개의 연결 없이 병렬 처리도 할 수 있고
파이프라이닝과 달리 HOL를 해결한 것이다.

또한 요청 우선수위를 지정할 수 있고 헤더를 압축하여 헤더 오버헤드를 줄이고 클라이언트가 명시적 요청을 하지 않아도 필요한 리소스를 미리 푸시하여 응답 시간을 줄이는 서버 푸시 기능이 추가되었다.

차세대 - HTTP/2로의 진화

HTTP는 HTTP/2(H2)의 릴리즈와 함께 진화를 멈추지 않았다.
HTTP/1.x처럼 확장성은 여전히 새로운 기능들을 추가하는데 사용되고 있다.

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

HTTP의 진화는 그것의 확장성과 단순함이 예측 불가능한 애플리케이션과 프로토콜 채택을 만들어내고 있다는 것을 보여준다.
오늘날 HTTP가 사용되는 환경은 1990년 초에 상상하던 것과는 완전히 다르다.
HTTP 본래의 설계가 걸작이 되었음을 지난 25년 넘게 호환되지 않는 진화의 요구없이 웹을 진화시킴으로 증명했다. 25년 넘게 HTTP의 성공을 만들어 온 유연함과 확장성을 유지하는 동시에 수년 넘게 밝혀진 많은 결함들을 수정한 덕택에, H2의 등장은 프로토콜에 대한 밝은 미래를 암시하는 것처럼 보인다.

  • 스트림 : 구성된 연결 내에서 전달되는 바이트의 양방향 흐름이며, 하나 이상의 메시지가 전달될 수 있다.
  • 메시지 : 논리적 요청 또는 응답 메시지에 매핑되는 프레임의 전체 시퀀스
  • 프레임 : H2에서 통신의 최소 단위이며 각 최소 단위에는 하나의 프레임 헤더가 포함된다. 이 프레임 헤더는 최소한으로 프레임이 속하는 스트림을 식별한다.

좌측 : HTTP/2 | 우측 : HTTP/1.1

출처

https://ko.wikipedia.org/wiki/HTTP
https://developer.mozilla.org/ko/docs/Web/HTTP/Basics_of_HTTP/Evolution_of_HTTP
https://www.whatap.io/ko/blog/38/

profile
Daily Coding

0개의 댓글