HTTP에 대해서
HTTP/1.1
HTTP/1.0 과 HTTP/1.1의 차이
몇 가지 차이점이 있지만 가장 큰 차이점은 socket connection 재사용 옵션 부분이다.
- HTTP/1.0 : Connectionless
Connection: close
가 default
- HTTP/1.1 : Connection 유지
Connection: keep-alive
가 default
HTTP 패킷의 시작과 끝
- 기본적으로
Content-Length
헤더를 보고 인식한다.- Content-Length가 없으면, connection이 끊어질 때 까지 계속 읽는다.
- 그렇다면 항상 전체 패킷에 대한 Content-Length를 미리 계산해야 할까? => chunked encoding을 사용하면 아래와 같이 길이를 모르는 패킷도 요청/응답으로 보낼 수 있다.
- 길이가 0인 chunk를 받으면 끝이라고 인식하는 방식.
- 마지막 chunk의 trailer 영역에 checksum 같은 것들을 실어 보낼 수 있다.
1 2 3 4 5 6 7 8 9 10 11 12 13
HTTP/1.1 200 OK Content-Type: text/plain Transfer-Encoding: chunked Trailer: Expires 7\r\n <--- 길이 Mozilla\r\n <--- 내용 9\r\n Developer\r\n 7\r\n Network\r\n 0\r\n Expires: Wed, 21 Oct 2015 07:28:00 GMT\r\n \r\n
HTTP/2
- 많은 곳에서 이미 사용중이다. (google은 http/2+quic/46 를 사용한다. gRPC는 HTTP/2를 기반으로 전송한다.)
- HTTP/1.1 과의 주요한 차이점은, 요청/응답 cycle을 기다리지 않고 하나의 connection에서 multiplexing 전송 이 가능하다는 점이다.
binary frame과 multiplexing
HTTP body 부분이 1.1에서는 text로 전송되었던 것과 달리
2.0에서는 binary frame 단위로 전송 된다.
기존에는 http header와 body가 \r\n으로 구분되었으나… HTTP/2.0에서 부터는 header와 body가 layer로 구분된다. (이를 binary framing layer라고 부르고 있다.)
동시에 이전에는 header-body를 묶은 http message가 전송 최소 단위였다면, 2.0에서는 전송 최소 단위가 binary frame 이 된다. 우측 그림의 프레임 하나 하나가 전송 최소 단위가 될 수 있다.
왜 binary로 해야 하는가? 기존 HTTP/1.x는 다음과 같은 단점을 가지고 있다.
- 본문은 압축이 되지만 헤더는 압축이 되지 않는다.
- 연속된 메시지들은 비슷한 헤더 구조를 가지고 있는 경우가 많은데, 그럼에도 불구하고 메시지마다 매번 전송되어야 한다.
- 다중전송(multiplexing)이 불가능하다. 다중 전송이라는건, 하나의 connection에 여러 요청/응답을 병렬적으로 실어 보내는 것을 의미한다. 이게 불가능하니 connection을 여러 개 열어야 한다.
물론 HTTP/1.1에서도 Keep-Alive 를 사용하면 socket connection을 유지하기 때문에 TCP 연결을 재사용할 수는 있지만, [요청-응답]으로 이루어진 한 HTTP 연결이 끝난 다음에 다음 HTTP 연결이 가능한 식이다. 따라서 HTTP layer에서는 [요청-응답] [요청-응답]을 반복해야만 한다. [요청-요청-요청 && 응답-응답-응답]이 병렬적으로 실행되는 것은 불가능하다.
병렬로 동시에 여러 요청/응답을 주고 받으려면 connection을 여러 개 열어야 한다. multiplexing은 불가능하다.
- 2.0에서는 이렇게 binary frame 단위로 쪼개서 보내는 방식이기 때문에, 하나의 connection을 여러 stream이 이용할 수 있어 다중 전송(multiplexing)이 가능하다.
- (한 칸의 단위는 binary frame이다.)
- *** 새로운 TCP connection을 여는 것을 cold request, 기존의 connection을 재사용 하는 것을 warm request라고 부르며 대체로 후자가 더 효율적이다. connection을 생성하는데 드는 비용을 아낄 수 있기 때문.
서버 푸시
-
h2와 h2c
h2 is HTTP/2 over TLS (protocol negotiation via ALPN). h2c is HTTP/2 over TCP.
참고
https://developer.mozilla.org/ko/docs/Web/HTTP/Messages
https://developers.google.com/web/fundamentals/performance/http2/?hl=ko