HTTP 개요
HTTP(HyperText Transfer Protocol)는 HTML 문서와 같은 하이퍼텍스트 리소스들을 가져올 수 있도록 해주는 프로토콜입니다. 웹에서 이루어지는 모든 데이터 교환의 기초이며, 클라이언트-서버 프로토콜이기도 합니다. 클라이언트-서버 프로토콜이란 수신자 측에 의해 요청이 초기화되는 프로토콜을 뜻합니다. 하나의 완전한 문서는 텍스트, 레이아웃 설명, 이미지, 비디오, 스크립트 등 불러온 하위 문서들로 재구성됩니다.
HTTP는 애플리케이션 계층의 프로토콜로, TCP 혹은 암호화된 TCP인 TLS를 통해 전송됩니다.
HTTP 흐름
클라이언트가 서버와 통신하고자 할 때, 다음 단계의 과정을 수행합니다.
1. TCP 연결을 엽니다. TCP 연결은 요청을 보내거나(혹은 여러 개의 요청) 응답을 받는데 사용됩니다. 클라이언트는 새 연결을 열거나, 기존 연결을 재사용하거나, 서버에 대한 여러 TCP 연결을 열 수 있습니다.
2. HTTP 메시지를 전송합니다. HTTP 메시지(HTTP/2 이전)는 사람이 읽을 수 있습니다. HTTP/2에서는 이런 간단한 메시지가 프레임 속으로 캡슐화되어 직접 읽는게 불가능하지만 원칙은 동일합니다.
3. 서버에 의해 전송된 응답을 읽어들입니다
4. 연결을 닫거나 다른 요청들을 위해 재사용합니다.
HTTP 파이프라이닝이 활성화되면, 첫번째 응답을 완전히 수신할 때까지 기다리지 않고 여러 요청을 보낼 수 있습니다. HTTP 파이프라이닝은 오래된 소프트웨어와 최신 버전이 공존하고 있는, 기존의 네트워크 상에서 구현하기 어렵다는게 입증되었으며, 프레임안에서 보다 활발한 다중 요청을 보내는 HTTP/2로 교체되고 있습니다.
HTTP 메시지
HTTP 메시지의 두 가지 타입인 요청(requests)과 응답(responses)은 각자의 특성있는 형식을 가지고 있습니다.
요청
- HTTP Method : 클라이언트가 수행하고자 하는 동작을 정의한 GET, POST 같은 동사나 OPTIONS나 HEAD와 같은 명사이다. 일반적으로, 리소스를 가져오는 'GET', HTML 폼 데이터를 전송하는 'POST'를 사용한다.
- Path : 프로토콜, 도메인 또는 TCP포트 요소들을 제거한 리소스의 URL.
- Version of the protocol : HTTP 프로토콜의 버전
- Headers : 서버에 대한 추가 정보를 전달하는 헤더들. POST와 같은 몇 가지 메서드를 위해 전송된 리소스를 포함하는 응답의 본문과 유사한 내용이다.
응답
- Version of the protocol : HTTP 프로토콜의 버전
- Status code : 요청의 성공 여부, 상태코드. 상태코드를 통해 이유를 파악할 수 있다.
- Status message : 상태 코드의 짧은 설명을 나타내는 상태 메시지
- Headers : 요청 헤더와 비슷한 HTTP 헤더들, 선택 사항으로 가져온 리소스가 포함되는 본문이다.
HTTP 발전 과정
HTTP/0.9 - 원-라인 프로토콜
HTTP 초기 버전에는 버전 번호가 없었습니다. HTTP/0.9는 이후에 차후 버전과 구별하기 위해 0.9로 불리게 됐습니다. HTTP/0.9는 극히 단순합니다. 요청은 단일 라인으로 구성되며 리소스에 대한 경로로 가능한 메서드는 'GET'이 유일했습니다.
GET /mypage.html
응답 또한 극도로 단순합니다. 오로지 파일 내용 자체로 구성됩니다
<HTML>
A very simple HTML page
</HTML>
그 이후에 진화와는 다르게, HTTP 헤더가 없었는데 이는 HTML 파일만 전송될 수 있으며 다른 유형의 문서는 전송될 수 없음을 의미합니다. 상태 혹은 오류 코드도 없었습니다. 문제가 발생한 경우, 특정 HTML 파일이 사람이 처리할 수 있도록, 해당 파일 내부에 문제에 대한 설명과 함께 되돌려 보내졌었습니다.
HTTP/1.0 - 확장성 부여
HTTP/0.9는 매우 제한적이었으며 브라우저와 서버 모두 좀 더 융통성을 가지도록 빠르게 확장되었습니다:
- 버전 정보가 각 요청에 추가 되었습니다. (HTTP/1.0 이 GET 라인에 붙은 형태로)
- 상태 코드 라인 또한 응답의 시작 부분에 붙어 전송되어, 브라우저가 요청에 대한 성공과 실패를 알 수 있고 그 결과에 대한 동작을 할 수 있게 되었습니다.
- HTTP 헤더 개념은 요청과 응답을 위해 도입되어, 메타데이터 전송을 허용하고 프로토콜을 유연하고 확장 가능하도록 만들어주었습니다.
- 새로운 HTTP 헤더의 도움(Content-Type 추가)으로, 평이한 HTML 파일들 외에 다른 문서들을 전송하는 기능이 추가되었습니다.
다음은 일반적인 요청과 응답입니다:
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)
이런 새로운 기능들은 1991년부터 1995년까지의 기간 동안 일단 해보자는 접근법으로 이루어졌습니다. 서버와 브라우저에 기능을 추가한 뒤, 상황을 지켜보았습니다. 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년 초에 공개되었습니다.
HTTP/1.1은 모호함을 명확하게 하고 많은 개선 사항들을 도입했습니다:
- HTTP 커넥션이 재사용될 수 있게 하여, 탐색된 단일 원본 문서 내로 임베드된 리소스들을 디스플레이하기 위해 사용된 커넥션을 다시 열어 시간을 절약하게 하였습니다.
이미 TCP 연결이 열려있는 상태라면 또 다시 핸드세이크를 거치는 것이 아니라 바로 요청 응답을 합니다.
- 파이프라이닝을 추가하여, 첫번째 요청에 대한 응답이 완전히 전송되기 이전에 두번째 요청 전송을 가능케 하여, 커뮤니케이션 레이턴시를 낮췄습니다.
- Pipelining : 클라이언트는 요청에 대한 응답을 기다린 후 새로운 요청을 보내는 것이 아닌 여러개의 요청을 바로 보냅니다.
- Multiple : 클라이언트는 많은 양의 objects를 검색하기 위해 TCP 다중 연결을 할 수 있습니다.
- HOLB : pipelining으로 하나의 connection을 통해 다수의 요청을 보낼 수 있지만, 첫 번째 응답이 처리가 완료되기 전까지 다음 응답들이 대기하고 있으므로 발생하는 문제입니다.
- 청크된 응답 또한 지원됩니다.
- 추가적인 캐시 제어 메커니즘이 도입되었습니다.
- 언어, 인코딩 혹은 타입을 포함한 컨텐츠 협상이 도입되어, 클라이언트와 서버로 하여금 가장 적합한 컨텐츠를 전달합니다.
- 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에서 처음 공개되었습니다.
HTTP/2 - 더 나은 성능을 위한 프로토콜
현재 웹 페이지는 매우 복잡해지고 있습니다. 시각적 효과들과 상호작용을 추가하기 위한 스크립트의 양과 크기는 점점 더 많이 증가하고 있습니다. 더 많은 데이터들이 더 많은 요청 너머로 전송되고 있습니다. HTTP/1.1 커넥션은 올바른 순서로 전송되는 요청을 필요로 합니다. 또한, 몇몇 병렬 커넥션이 이론적으로 사용 가능한 경우(일반적으로 5와 8 사이에서), 여전히 많은 양의 오버헤드와 복잡도가 남아 있습니다. 예를 들어, HTTP 파이프라이닝은 디플로이 악몽임이 확실해졌습니다.
2010년 전반기에, Google은 실험적인 SPDY 프로토콜을 구현하여, 클라이언트와 서버 간의 데이터 교환을 대체할 수단을 실증하였습니다. 그것은 브라우저와 서버 측 모두에 있어 많은 관심을 불러일으켰습니다. 응답성 증가 능력을 입증하고 전송된 데이터 중복에 관한 문제를 해결하면서, SPDY는 HTTP/2 프로토콜의 기초로써 기여했습니다.
HTTP/2 프로토콜은 HTTP/1.1 버전과 다른 몇가지 근본적인 차이점을 가지고 있습니다:
- 그것은 텍스트 프로토콜이라기 보다는 이진 프로토콜입니다. 더 이상 읽을 수도 없고 수작업을 만들어낼 수 없습니다.이런 결점에 대한 보상으로, 새로운 최적화 기술이 구현될 수 있습니다.
- 병렬 요청이 동일한 커넥션 상에서 다루어질 수 있는 다중화 프로토콜로, 순서를 제거해주고 HTTP/1.x 프로토콜의 제약사항을 막아줍니다.fi›
- 전송된 데이터의 분명한 중복과 그런 데이터로부터 유발된 불필요한 오버헤드를 제거하면서, 연속된 요청 사이의 매우 유사한 내용으로 존재하는 헤더들을 압축시킵니다.
- 서버로 하여금 사전에 클라이언트 캐시를 서버 푸쉬라고 불리는 메커니즘에 의해, 필요하게 될 데이터로 채워넣도록 허용합니다.
2015년 5월에 공식적으로 표준화된, HTTP/2는 큰 성공을 거두었습니다. 2016년 6월, 모든 웹 사이트 중 8.7%[1]가 이미 사용 중에 있고, 이것은 모든 요청의 68%[2] 이상을 나타냅니다. 인터넷 상에서 전송 오버헤드 감소로 많은 돈을 절약하는 높은 트래픽의 웹 사이트들은 이 프로토콜을 급속히 받아들이고 있습니다.
이러한 급격한 채택은 HTTP/2가 웹 사이트와 애플리케이션의 채택이 필요하지 않았기에 가능했습니다. HTTP/1.1을 사용할지 HTTP/2를 사용할지 고민할 필요가 없어졌습니다. 최신 브라우저와 통신하는 최신의 서버를 갖는 것은 프로토콜 사용을 활성화하는 것만으로 충분합니다.어느 정도의 제한된 액터 세트만이 HTTP/2 채택을 불러일으키는데 필요했으며 브라우저와 서버 버전이 교체됨에 따라, 웹 개발자의 투입없이도 HTTP/2의 사용은 자연스럽게 증가했습니다.
차세대 - HTTP/2로 진화
HTTP 2.0은 HTTP 1.1 프로토콜을 계승해 동일한 API면서 성능 향상에 초점을 맞췄습니다.
기존에 Plain Text(평문)을 사용하고 개행으로 구별되던 HTTP/1.x 프로토콜과 달리 2.0은 바이너리 포맷으로 인코딩된 Message, Frame으로 구성됩니다.
- Stream: 구성된 연결 내에서 전달되는 바이트의 양방향 흐름, 하나 이상의 메시지가 전달 가능합니다.
- Message: 논리적 요청 또는 응답 메시지에 매핑되는 프레임의 전체 시퀀스입니다.
- Frame: Http/2.0에서 통신의 최소 단위, 각 최소 단위에는 하나의 프라임 헤더가 포함됩니다. 이 프라임 헤더는 최소한으로 프레임이 속하는 스트림을 식별합니다. Headers Type Frame, Data Type Frame이 존재합니다.
Multiplexed Streams
- 하나의 Connection으로 동시에 여러 개 메시지를 주고 받을 수 있으며, Response는 순서에 상관없이 stream으로 주고받습니다.
Stream Prioritization
- 리소스간 우선순위를 설정해 클라이언트가 먼저 필요한 리소스부터 보내줍니다.
Server Push
- 서버는 클라이언트의 요청에 대해 요청하지 않은 리소스를 마음대로 보내줄 수 있습니다.
- 즉, 클라이언트가 요청하기 전에 필요하다고 예상되는 리소스를 Server에서 먼저 요청합니다.
예) http만 요청했는데 http와 css, js, image를 함께 전송해주는 등
Header Compression
- Header table과 Huffman Encoding 기법(HPAC 압축방식)을 이용해 압축했습니다.
- 이전 Header의 내용과 중복되는 필드를 재전송하지 않아 데이터를 절약했습니다.

HTTP/3 - HTTP over QUIC
참고
https://developer.mozilla.org/ko/docs/Web/HTTP/Overview
https://developer.mozilla.org/ko/docs/Web/HTTP/Basics_of_HTTP/Evolution_of_HTTP
https://hirlawldo.tistory.com/106
댓글