Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[2부 10장] HTTP/2.0 #10

Open
ruthetum opened this issue Sep 4, 2022 · 2 comments
Open

[2부 10장] HTTP/2.0 #10

ruthetum opened this issue Sep 4, 2022 · 2 comments

Comments

@ruthetum
Copy link
Member

ruthetum commented Sep 4, 2022

HTTP/2.0

Overview

  • 지금 HTTP/1.1을 대부분 쓰고 있고, 회사 별로 HTTP/2.0을 쓰는 곳도 있는 상황
  • 그래서 HTTP/2.0과 관련해서 HTTP/1.1과 주요 차이, 보안 이슈에 대해서 내용을 다룰 예정

Why HTTP/2.0?

HTTP/1.1에서 개선 노력

  • HTTP/1.1의 메시지 포맷은 구현의 단순성과 접근성에 주안점을 두고 최적화
  • 커넥션 하나를 통해 요청 하나를 보내고 그에 대한 응답 하나만을 받는 방식
    • 응답을 받아야만 다음 요청을 보낼 수 있기 때문에 회전 지연 발생(latency)
  • 이를 해결하기 위해서 병렬 커넥션, 파이프라인 커넥션이 도입되었지만 성능 개선에 대한 해결책이 되지는 못 함

SPDY

  • 결국 성능 개선을 위해 WAKA, S+M 같은 프로토콜 등이 제안되었고, 구글에서 SPDY(스피디) 프로토콜을 개발
    • SPDY 는 기존 HTTP t속도를 개선하기 위해 여러 기능이 추가된 것이고, HTTP를 대체하는 프로토콜이 아니라 HTTP가 전송 계층을 통해 전송되는 방식을 재정의하는 프로토콜
    • 현재는 HTTP/2.0의 이점이 더 크기 때문에 크롬에서는 2016년에 SPDY 지원 기능을 제거
    • HTTP/2.0 은 SPDY를 기반으로 설계
    • cf. SPDY - 위키백과, 우리 모두의백과사전

HTTP/2.0

image

  • HTTP/2.0은 TCP 커넥션 위에서 동작
  • 요청과 응답은 길이가 정의된(최대 16383바이트) 한 개 이상의 프레임에 담기고, 헤더는 압축되어 담겨짐
  • 프레임들에 담긴 요청과 응답은 스트림을 통해 보내지며, 한 개의 스트림이 한 쌍의 요청과 응답을 처리
  • 하나의 커넥션 위에 여러 개의 스트림이 동시에 만들어 질 수 있으므로, 여러 개의 요청과 응답을 동시에 처리하는 것이 가능
  • 서버 푸시 도입 (후술)
  • 하위 호환을 지원하기 위해 요청/응답 메시지의 의미를 HTTP/1.1과 같도록 유지
    • ‘Content-Length’ 헤더는 HTTP/2.0에서 ‘:content-length’

HTTP/1.1과 차이점

프레임

  • HTTP/2.0에서 모든 메시지는 프레임에 담겨 전송

스크린샷 2022-09-04 오후 6 56 48

  • 프레임은 8바이트 크기의 헤더로 시작하고, 뒤이어 최대 16383바이트 크기의 페이로드가 옴

    • R : 예약된 2비트 필드, 값의 의미가 정의되어 있지 않으며, 반드시 0이어야 함. 받는 쪽에서는 이 값을 무시
    • 길이 : 페이로드의 길이를 나타내는 14비트, 길이에는 프레임 헤더는 포함되지 않음
    • 종류 : 프레임의 종류를 나타내는 8비트
    • 플래그 : 8비트 플래그
    • R : 예약된 1비트 필드, 값의 의미가 정의되어 있지 않으며, 반드시 0이어야 함. 받는 쪽에서는 이 값을 무시
    • 스트림 식별자 : 31비트 스트림 식별자, 0은 커넥션 전체와 연관된 프레임을 의미
  • HTTP/2.0은 DATA, HEADERS, PRIORITY, RST_STREAM, SETTINGS, PISH_PROMISE, PING, GOAWAY, WINDOW_UPDATE, CONTINUATION라는 10가지 프레임을 정의


스트림, 멀티플렉싱

  • 스트림은 HTTP/2.0 커넥션을 통해 클라이언트와 서버 사이에서 교환되는 프레임들의 양방향 시퀀스 (하나 이상의 메시지 전달될 수 있음)

    • 한 쌍의 HTTP 요청과 응답은 하나의 스트림을 통해 이루어짐
    // HTTP/1.1 여러 요청을 보내는 flow
    1. 한 TCP 커넥션을 통해 요청 전송
    2. 응답이 도착할 때까지 대기
    3. 응답 도착 후 다시 요청
    
    • 응답이 도착할 때까지 대기하기 때문에 지연 발생
      • 이를 해결하기 위해서 여러 개의 TCP 커넥션 생성 -> 병렬
      • 무작정 여러 커넥션을 만들 수 없기 때문에 파이프라인 커넥션 사용
        • 다만 그다지 널리 구현되어 있지 않음
  • HTTP/2.0에서는 하나의 커넥션에서 여러 개의 스트림을 동시에 열 수 있음

  • 스트림에 우선순위를 부여할 수 있기 때문에 대역폭 제한이 있는 경우 중요한 리소스를 요청하는 스트림에 더 높은 우선순위를 부여

    • 다만 우선순위를 따르는 것이 의무사항이 아니기 때문에 요청이 우선순위대로 처리된다는 보장은 없음
  • HTTP/2.0 커넥션에서 한번 사용한 스트림 식별자는 다시 사용할 수 없음

    • 커넥션을 오래 사용하다보면 스트림에 할당할 수 있는 식별자가 고갈되는 경우가 발생 -> 이 경우에는 다시 커넥션을 맺으면 됨

헤더 압축

  • HTTP/1.1에서는 헤더는 아무런 압축 없이 그대로 전송
  • 예전에는 헤더의 크기가 작았기 때문에 문제가 되지 않았지만 요즘은 하나의 웹페이지에서 많은 요청이 일어나기 때문에 헤더의 크기가 지연, 대역폭에 영향을 끼침
  • 그래서 HTTP/2.0에서는 헤더를 압축하여 전송
    • HPACK 명세에 정의된 헤더 압축 방법으로 압축

서버 푸시

  • HTTP/2.0은 서버가 하나의 요청에 대해 응답으로 여러 개의 리소스를 보낼 수 있음
  • 예를 들어 HTML을 요청 받은 서버는 함께 내려줘야 할 이미지, css, js 등의 리소스를 클라이언트에게 푸시할 수 있음
  • 리소스를 푸시하려는 서버는 먼저 클라이언트에게 자원을 푸시할 것임을 PUSH_PROMISE 프레임을 보내어 미리 알려주어야 함
    • 클라이언트가 별도로 요청하여 중복 요청되는 상황을 방지하기 위함
  • 클라이언트가 PUSH_PROMISE 프레임을 받게 되면 해당 프레임의 스트림은 클라이언트 입장에서 예약 상태가 되고, 이 상태에서 클라이언트는 RST_STREAM 프레임을 전송해서 푸시를 거절할 수 있음

cf. https://freecontent.manning.com/animation-http-1-1-vs-http-2-vs-http-2-with-push/


보안 이슈 (Known issue)

중개자 캡슐화 공격

  • HTTP/2.0 메시지를 프락시가 HTTP/1.1로 변환할 때 메시지의 의미가 변질될 수 있음
  • HTTP/1.1과 달리 HTTP/2.0는 헤더 필드의 이름과 값을 바이너리로 인코딩
    • 따라서 HTTP/2.0 헤더 필드는 어떤 문자열이든 사용할 수 있음
  • 따라서 위조된 필드를 사용하여 공격할 수 있음

긴 커넥션 유지로 인한 개인정보 누출 우려

  • HTTP/2.0은 회전 지연을 줄이기 위해 오랫동안 커넥션을 지속
  • 예를 들어 어떤 사용자가 브라우저를 사용할 때, 이전에 그 브라우저를 사용했던 사용자가 어떤 데이터를 주고 받았는지 알아낼 수 있음
  • 현재 HTTP 커넥션도 동일한 문제를 가지고 있지만, 커넥션의 지속 기간이 짧기 때문에 상대적으로 위험이 덜함
@ruthetum
Copy link
Member Author

ruthetum commented Sep 4, 2022

@ruthetum
Copy link
Member Author

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant