ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • HTTP/2.0이란 무엇인가
    CS지식/네트워크 2021. 7. 16. 21:54

    우리는 현재 HTTP의 버전으로 1.1을 보편적으로 사용하고 있다.

    그렇지만 HTTP를 개발하는 그룹에서는 HTTP의 성능 문제를 개선하기 위해 HTTP/2.0을 만든 중에 있다.

    그러면 HTTP/2.0은 HTTP/1.1과 어떠한 차이점이 있는지 현재까지 알려진 보안 이슈는 무엇인지에 대해 알아보자.

     

     

    HTTP/2.0의 등장 배경

    기존의 HTTP 메시지 교환 방신은 하나의 커넥션을 통해 클라이언트가 요청 하나를 보내면 서버는 그에 대한 응답 하나만을 보내는 방식이였다.

    이러한 방식은 응답을 받아야만 다음 요청을 보낼 수 있기에 심각한 지연을 야기할 수 있는 문제가 있다.

    이 문제를 회피하기 위해 병렬 커넥션이나 파이프라인 커넥션을 도입했지만 성능 개선에 대한 근본적인 해결책은 되지 못했다.

    이제는 근본적인 해결을 위해 많은 곳에서 개발을 하기 시작했다.

    그 중, 구글에서 발표한 SPDY 프로토콜은 기존 HTTP의 지연을 줄여 성능을 개선한 좋은 프로토콜이 되었다.

    HTTP 작업 그룹은 SPDY를 기반으로 HTTP/2.0 프로토콜을 설계하기 시작한 것이다.

    HTTP/2.0의 기반인 SPDY 프로토콜의 기능 개선점을 더 자세히 얘기해보면 다음과 같다.

    - 헤더를 압축하여 대역폭 절약

    - 하나의 TCP커넥션에 여러 요청을 동시에 보내 지연을 줄임

    - 클라이언트가 요청을 보내지 않아도 서버가 능동적으로 리소스를 푸시하는 기능 추가

     

     

    HTTP/2.0은 무엇일까

    HTTP/2.0은 서버와 클라이언트 사이의 TCP 커넥션 위에서 동작하는 것으로 요청과 응답은 HTTP 헤더가 압축되어 한 개 이상의 프레임(최대 16383바이트)에 담겨 통신이 이루어진다.

    프레임에 담긴 요청과 응답은 스트림을 통해 이동한다. 하나의 커넥션 위에 여러 개의 스트림이 동시에 만들어질 수 있어 여러 개의 응답과 응답을 동시에 처리하는 것이 가능해졌다.

    또한, 스트림에 대한 흐름 제어와 우선순위 부여 기능도 제공한다.

     

    HTTP/2.0에서 새로 도입된 기능 중 하나는 서버 푸시(server push)이다.

    서버 푸시는 클라이언트가 요청을 보내지 않았어도 서버가 이 리소스는 클라이언트에게 필요하다고 생각되면 능동적으로 클라이언트에게 보내는 것이다.

     

    HTTP/2.0에서는 기존 웹 애플리케이션들과의 호환성에도 신경을 썼다.

    요청과 응답 메시지의 의미를 HTTP/1.1과 같도록 유지하여 HTTP/1.1을 사용하는 기존 웹 애플리케이션들과의 통신에 문제가 없도록 한다.

    예를 들어, HTTP/1.1에서 Content-length 헤더는 본문의 길이를 의미하고 404 Not Found 응답은 해당 요청에 대한 리소스를 찾을 수 없다는 의미로 쓰였다.

    HTTP/2.0에서도 이러한 의미를 그대로 사용했고 형태만 달라졌다.

    Content-length라는 이름은 .content-length로 404 Not Found는 404값을 갖고 있는 .status헤더로 형태를 바꿨다.

     

     

     

    HTTP/1.1과의 차이점은 무엇일까

    1) HTTP/2.0에서는 프레임을 사용한다.

    HTTP/1.1에서 응답과 요청 메시지는 단순한 줄 단위의 문자열로 이진 형식이 아닌 일반 텍스트를 사용한 것으로 단순한 데이터의 구조화된 블록이였다.

    하지만 HTTP/2.0에서는 모든 메시지가 프레임에 담겨 전송된다.

    출처: https://httpwg.org/specs/rfc7540.html#FrameHeader

     

    HTTP/2.0에서 모든 프레임은 9-octet 크기의 헤더로 시작하며 뒤에 최대 16777215바이트 크기의 페이로드가 붙는다.

    (내가 읽고 있는 HTTP 완벽가이드는 2013년에 나온 draft를 참고하여 쓴 책으로 최근 draft를 보면 프레임의 레이아웃이 달라져 달라진 것을 바탕으로 정리하려고 한다.)

    12바이트를 차지하는 헤더에 명시된 필드의 의미는 다음과 같다.

    - 길이(length)

    페이로드의 길이를 나타내는 24비트 무부호 정수(unsigned integer)로 해당 길이에는 헤더는 포함되지 않는다.

    기존에는 14비트를 사용하여 페이로드의 최대 길이인 16383바이트를 표현했다.

    하지만 개정된  draft에는 24비트를 사용하였는데 draft에 나온 설명에 의하면

    길이(length)에는 수신자가 SETTINGS_MAX_FRAME_SIZE(페이로드가 16383바이트보다 클 때 쓰는 값)에 값을 주지 않는 이상 16384보다 큰 값을 주면 않된다고 한다.

     

    - 종류(type)

    8비트를 이용하여 프레임의 종류를 알려준다.

    미리 정의되어 있지 않은 unknown type이 프레임의 type필드에 써있다면 그 프레임은 무시하거나 버려야한다.

    프레임의 종류에는 DATA, HEADERS, PRIORTY, RST_STREAM, SETTINGS, PUSH_PROMISE, PING, GOAWAY,

    WINDOW_UPDATE, CONTINUATIONS 총 10가지가 있다.

     

    - 플래그(Flags)

    플래그 값의 의미는 프레임의 종류에 따라 다르다.

     

    - R(Reserved)

    예약된 1비트 필드로 값의 의미가 미리 정의되어 있지 않으면 반드시 0이여야한다.

     

    - 스트림 식별자(Stream Identifier)

    31비트로 표현되는 것으로 특별히 0은 커넥션 전체와 연관된 프레임을 의미한다.

     

     

    2) 스트림과 멀티플렉싱

    스트림은 HTTP/2.0 커넥션을 통해 클라이언트와 서버 사이에서 교환되는 프레임들의 독립된 양방향 시퀀스이다.

    한 쌍의 HTTP 요청과 응답은 하나의 스르밍을 통해 이루어진다.

    HTTP/1.1에서는 하나의 TCP 커넥션을 통해 요청을 보냈을 때 그에 대한 응답이 도착하고 난 후에 같은 TCP 커넥션으로 다시 요청을 보낼 수 있었다.

    하지만 HTTP/2.0에서는 하나의 커넥션에 여러 개의 스트림이 동시에 열려 커넥션을 통해 여러 개의 요청이 동시에 보내질 수 있다.

    HTTP/2.0에서 사용하는 스트림은 아래와 같은 특징을 가진다.

     

    ① 모든 스트림은 31비트의 무부호 정수로 된 고유한 식별자를 갖는다.

    스트림이 클라이언트에 의해 초기화됐으면 해당 스트림의 식별자는 반드시 홀수여야 하며 서버에 의해 초기화됐으면 반드시 짝수여야한다.

    또한, 새로 만들어지는 스트림의 식별자는 기존에 있는 스트림이나 예약된 스트림의 식별자보다 커야한다.

     

    ② 서버와 클라이언트는 스트림을 상대방과 협상 없이 일방적으로 만든다.

    이러한 점은 스트림을 만들기 위한 협상과정에서 TCP 패킷을 주고받는 것을 생략하여 시간 낭비를 하지 않을 수 있는 장점을 가져온다.

     

    ③ HTTP/2.0 커넥션에서 한번 사용한 스트림 식별자는 다시 사용할 수 없다.

    이렇게 재사용이 불가능하면 커넥션이 오래 유지될수록 스트림 식별자는 14비트로 제한되었으므로 언젠가는 고갈될 수 있다.

    하지만, 스트림 식별자로 사용될 값이 고갈된 경우에는 그냥 커넥션을 다시 맺으면 된다.

     

    ④ HTTP/2.0은 스트림 흐름 제어를 제공한다.

    동시에 여러 개의 스트림을 사용하면 스트림이 블록될 우려가 있는데 HTTP/2.0에서는 WINDOW_UPDATE프레임을 이용해서 흐름 제어를 통해 스트림들이 서로 간섭해서 망가지는 것을 방지한다.

     

    ⑤ HTTP/2.0에서 스트림은 우선순위를 가질 수 있다.

    네트워크 대역폭이 충분하지 않아서 프레임의 전송이 느린 경우에 웹브라우저는 요청을 대기하는 리소스 중에 보다 중요한 리소스를 요청하는 스트림에 더 높은 우선순위를 부여할 수 있다.

    하지만 이 우선순위에 따르는 것은 의무가 아니여서 우선순위에 따라 처리된다는 보장이 없다.

     

     

    3) 헤더 압축

    HTTP/1.1에서는 헤더 압축없이 그대로 보내졌다.

    요즘에는 웹 페이지 하나를 보여줄 때에도 정말 많은 요청을 보내야하기 때문에 기존에 헤더 압축없이 보내는 방식은 지연을 발생시키고 대역폭을 잡아먹는 악영향을 끼치는 요소가 될 수 있다.

    그래서 HTTP/2.0은 HTTP 메시지의 헤더를 압축하여 전송한다.

    헤더는 HPACK 명세에 의해 정의된 헤더 압축 방법으로 압축한 뒤 헤더 블록 조작들로 쪼개져서 전송된다.

    헤더를 받는 이는 조각들을 이은 뒤에 압축을 풀어 원래의 헤더로 복원한다.

     

    'CS지식 > 네트워크' 카테고리의 다른 글

    로그(log)란 무엇인가  (0) 2021.07.18
    내용 협상(content negotiation)이란 무엇인가  (0) 2021.07.12
    HTTPS란 무엇인가  (0) 2021.06.23
    다이제스트 인증이란 무엇인가  (0) 2021.06.20
    HTTP 인증이란 무엇인가  (0) 2021.06.17

    댓글

Designed by Tistory.