본문 바로가기

Network

HTTP 버전별 차이

며칠 전 평소 친하게 지내던 개발자 선배로부터 이런 얘기를 들었다.

 

“근데 너 HTTP 버전이 3.0 까지 나온 거 알고 있어?”

“예?”

 

내가 기억하는 HTTP는 2.0이 마지막 버전인 줄 알았는데 어느새 다음 버전이 나왔다니 다소 당혹스러웠다. 웹 서비스를 다루는 개발자로서 이런 부분을 모르고 있었다니…

하지만 모르는 게 있으면 찾아서 배우고 부족한 부분을 메꿔나가면 될 일.

선배와 통화를 마친 후 부랴부랴 관련 내용을 찾아보았다.

 

오늘은 공부하면서 알아낸 내용을 기반으로 HTTP가 시대를 거치며 어떤 방식으로 변화했는지 알아보고자 한다.

 

 

HTTP란

 

HTTPHypertext Transfer Protocol 의 약자로 하이퍼텍스트를 전송하는 프로토콜이다. 여기서 하이퍼텍스트란 하이퍼링크를 통해 병렬로 연결된 텍스트를 말한다. 보다 간단히 설명하면 httphtml 파일을 주고받는 통신 규약이라고 할 수 있다.

 


HTTP 0.9 – (1991년)

 

초기 버전에는 버전 번호가 없었다. 0.9는 차후에 버전 구별을 하기 위해 따로 붙인 버전 번호이다. 초기 버전이다 보니 극도로 단순한 모습을 가지고 있다. 특징은 아래와 같다.

  • GET 메소드만 존재함
  • HTTP 헤더가 없음

(요청)

GET /mypage.html

(응답)

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

 

HTTP 1.0 – (1996년)

 

매우 제한적이었던 0.9 버전에 비해 훨씬 더 확장되었다.

  • HTTP 버전 정보 추가
  • 응답에 상태 코드 추가
  • HTTP 헤더 추가
  • Content-Type덕에 HTML 뿐만 아니라 다른 타입의 파일(ex. 이미지, 텍스트, JSON, XML 등)도 전송 가능
  • POST, HEAD 메소드 추가

(요청)

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>                                -> 본문

 

(연결 방식)

- 연결 방식에서 TCP 프로토콜을 사용
- 그런데 이 당시 문제점이 커넥션 하나당 요청 1, 응답 1개만 처리가 가능한 방식이었다.
- 이렇기 때문에 요청을 보낼 때 마다 새로운 커넥션을 맺어야 했고 이로 인해 성능 저하 문제가 발생했다.

 


HTTP 1.1 – (1997년)

  • HOST 헤더 추가
  • PUT, OPTIONS, DELETE 등의 메소드 추가
  • 캐시 제어 매커니즘 추가

(요청)

GET /ko/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/ko/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)

 

(연결 방식)

- 연결 방식에서 TCP 프로토콜을 사용

- HTTP 1.0의 성능 저하 문제를 해결하기 위해 다음과 같은 방식 도입
- Persistent Connection :
커넥션을 일정 시간 동안 유지하여 한번의 커넥션에 여러 개의 요청과 응답이 가능함
- Pipelining :
앞 요청의 응답을 기다리지 않고 순차적인 여러 요청을 연속적으로 보내고 그 순서에 맞춰 응답을 받는 방식

- 하지만 TCP의 근본적인 문제인 HOLB는 해결하지 못함

 


 

* HOLB (Head Of Line Blocking)

 

TCP를 사용한 통신에서 패킷은 무조건 정확한 순서대로 처리되어야 한다. 수신 측은 송신 측과 주고받은 시퀀스 번호를 참고하여 패킷을 재조립해야하기 때문이다.

 

그래서 통신 중간에 패킷이 손실되면 완전한 데이터로 다시 조립할 수 없기 때문에 절대로 그냥 넘어가지 않는다. 무조건 송신 측은 수신 측이 패킷을 제대로 다 받았다는 것을 확인한 후, 만약 수신 측이 제대로 패킷을 받지 못했으면 해당 패킷을 다시 보내야 한다.

 

또한 패킷이 처리되는 순서 또한 정해져 있으므로 이전에 받은 패킷을 파싱하기 전까지는 다음 패킷을 처리할 수도 없다. 이렇게 패킷이 중간에 유실되거나 수신 측의 패킷 파싱 속도가 느리다면 통신에 병목이 발생하게 되는 현상을 HOLB라고 한다.

 


SPDY - (2009년)

 

구글에서 개발한 실험용 프로토콜로 HTTP 1.1의 문제를 해결하기 위해 개발되었다. 훗날 HTTP 2.0의 기반이 된다.

SPDY HTTP와는 완전 별개의 프로토콜이 아니라 TLS 위에서 동작하는 프로토콜로, HTTP 요청을 보내면 이를 SPDY 요청으로 변환하여 서버에 날리고, 응답을 다시 HTTP로 변환하는 방식으로 동작한다.

 

 


HTTP 2.0 – (2015년)

 

기존 HTTP 1.X 버전의 성능 향상에 초점을 맞춘 프로토콜. SPDY를 기반으로 만들어졌으며 다음과 같은 특징을 가지고 있다.

  • Binary Framing Layer : 일반 텍스트 형식의 메시지를 전송하던 기존 방식과 달리 메시지를 바이너리 형태로 인코딩 하여 전송(파싱과 전송 속도 향상, 오류 발생 가능성 낮춤)
  • Multiplexing : 하나의 TCP 연결에 하나의 응답이 가능했던 기존 방식과 달리 하나의 TCP 연결내에서 다수의 클라이언트 요청과 서버 응답이 비동기 방식으로 이뤄지는 방식
    - 하지만 여전히 연결 방식으로 TCP를 사용하기 때문에 HOLB 문제는 해결하지 못함
  • Stream Prioritization : 리소스간 우선 순위를 설정하는 기능
  • Server Push : 서버 푸시를 통해 클라이언트가 요청하지 않은 컨텐츠도 서버가 미리 빠르게 전송하여 RTT(Round Trip Time - 왕복시간)를 줄일 수 있다. 예를 들어, 클라이언트가 서버에 index.html 파일을 요청한 경우 서버에서 CSS 파일도 같이 내려주어 클라이언트가 서버로 보내는 CSS 요청만큼의 시간을 절약할 수 있다.
  • Header Compression : 허프만 인코딩을 통해 헤더의 크기를 줄이는 방식

 

HTTP 3.0 – (2019년)

 

UDP기반의 프로토콜인 QUIC을 사용하며 다음과 같은 특징이 있다.

  • 전송 속도 향상 : 핸드 쉐이크 과정이 필요한 TCP와 달리 첫 연결 설정에서 필요한 정보와 함께 데이터를 전송함. 연결이 성공한다면 설정을 캐싱하여 다음 연결 때 바로 데이터 전송이 가능하도록 함
  • Connection UUID 사용 : Connection UUID 라는 고유 식별자로 서버와 연결하기 때문에 ip가 도중에 변경되더라도 커넥션을 재수립 할 필요가 없음
  • TLS 기본 적용 : 보안성 향상
  • 독립 스트림 사용 : 서로 독립된 스트림을 사용해 TCP에서 발생하던 HOLB 문제를 해결함

 


Q&A

크롬에서 http 버전을 확인하는 방법이 어떻게 되나요?

 

 

1) 특정 웹에서 F12로 개발자 툴 열기
2) 네트워크 탭 클릭

3) 헤더 옵션에서 프로토콜 클릭

 

- 이때 나오는 값 중에 H2HTTP 2.0을 의미하고 H3HTTP 3.0을 의미합니다.

 


출처 : 
https://developer.mozilla.org/ko/docs/Web/HTTP/Basics_of_HTTP/Evolution_of_HTTP
https://developer.mozilla.org/ko/docs/Web/HTTP/Connection_management_in_HTTP_1.x
https://developer.mozilla.org/ko/docs/Web/HTTP/Messages
https://developer.mozilla.org/ko/docs/Web/HTTP/Headers/Host
https://www.youtube.com/watch?v=xcrjamphIp4&t=740s
HTTP/3 왜 UDP 선택한 것일까? | Evans Library (evan-moon.github.io)
https://jaehyeon48.github.io/network/history-of-http/

'Network' 카테고리의 다른 글

TLS(Transport Layer Security)  (2) 2024.07.14
TCP와 UDP  (0) 2023.12.10
OSI 모델, TCP/IP 모델  (0) 2023.12.09