1. 1달 전

    18장 웹 호스팅

    HTTP 완벽 가이드 18장 정리

  2. 2달 전

    17장 내용 협상과 트랜스코딩

    HTTP 완벽 가이드 17장 정리

  3. 5달 전

    16장 국제화

    HTTP 완벽 가이드 16장 정리

  4. 5달 전

    15장 엔터티와 인코딩

    HTTP 완벽 가이드 15장 정리

  5. 6달 전

    14장 보안

    HTTP 완벽 가이드 14장 정리

  6. 7달 전

    12장 기본 인증

    HTTP 완벽 가이드 12장 정리

  7. 7달 전

    11장 클라이언트 식별과 쿠키

    HTTP 완벽 가이드 11장 정리

  8. 7달 전

    10장 HTTP 2.0

    HTTP 완벽 가이드 10장 정리

  9. 7달 전

    9장 웹 로봇

    HTTP 완벽 가이드 9장 정리

  10. 7달 전

    8장 통합점 게이트웨이, 터널, 릴레이

    HTTP 완벽 가이드 8장 정리

  11. 7달 전

    7장 캐시

    HTTP 완벽 가이드 7장 정리

  12. 7달 전

    6장 프락시

    HTTP 완벽 가이드 6장 정리

  13. 7달 전

    5장 웹서버

    HTTP 완벽 가이드 5장 정리

  14. 7달 전

    4장 HTTP 커넥션 관리

    HTTP 완벽 가이드 4장 정리

  15. 7달 전

    3장 HTTP 메시지

    HTTP 완벽 가이드 3장 정리

  16. 7달 전

    2장 URL과 리소스

    HTTP 완벽 가이드 2장 정리

  17. 7달 전

    1장 HTTP 개관

    HTTP 완벽 가이드 1장 정리

Tamm자바스크립트 웹 개발 환경을 좋아하고 사람들에게 재미를 주는 것에 관심이 많은 개발자 입니다.

10장 HTTP 2.0

HTTP 완벽 가이드 10장 정리

featured image thumbnail for post 10장 HTTP 2.0

1997년에 HTTP/1.1이 표준이 된 이후 HTTP/2.0에 대한 초안 작성이 진행되었고, 그 사이 웹 기술이 많이 성숙 되었다. HTTP/2.0은 여러 초안이 검토 되었고 그 중 구글의 SPDY 프로토콜이 draft로 채택 되었다. 2015년에 HTTP/2 스펙이 공개되었다. 이 책은 2013년 11월에 draft된 기점으로 설명하고 있다.

10.1 HTTP/2.0의 등장 배경

HTTP/1.1의 메세지 포맷은 성능 보다는 단순성, 접근성에 주안점을 두고 개발되었다. 특히, 응답을 받아야만 그 다음 요청을 보낼 수 있기 때문에 심각한 회전 지연(latency)를 피할 수 없었다. 이 문제를 피하고자 병렬 커넥션을 도입하였지만 근본적인 해결책이 되지 못했다.

성능 개선을 위한 여러 아이디어들이 제시가 됐고, 그 중 구글의 SPDY를 기초로 HTTP/2.0이 설계되었다.

10.2 개요

HTTP/2.0도 TCP 커넥션 위에서 동작한다. 기존에 요청과 응답을 위해 다수의 커넥션을 사용했다면, HTTP/2.0에서는 하나의 커넥션에 여러 스트림을 사용한다. 이 스트림은 요청과 응답의 쌍으로 되어 있기 때문에 동시에 여러 요청을 보내고 받을 수 있게 되었다. 그외에 흐름 제어, 우선순위 부여, 서버 푸시 등이 추가되었다.

서버 푸시는 클라이언트가 명확히 요청을 하지 않았어도 서버가 능동적으로 클라이언트에게 데이터를 보낼 수 있게 한다.

HTTP/2.0은 기본적으로 HTTP/1.1 과의 호환이 된다. 404 status나 Content-Length등의 개념은 호환된다. 그러나 그것을 표현하는 방식이 조금 바뀌었다.

Content-Length 헤더의 이름은 ':content-length' 가, status는 ':status' 헤더로 표현한다.

10.3 HTTP/1.1과의 차이점

프레임의 구조가 책에 나와있는 버전과 지금 버전이 다른 것 같다.

스펙 문서

Untitled 5e600c5b 723e 41ae ac20 8092c5790fb6

Length: 페이로드의 길이를 나타내는 24비트 정수로, 프레임 헤더는 포함 되지 않음

Type: 프레임의 종류. 타입이 명확하지 않으면 무시될 수 있다.

Flags: 8비트로 되어 있고, 타입 마다 각 비트가 의미하는 것이 다르다.

R: 예약된 1비트로 반드시 0(unset)이야 하고, 받는 쪽은 무시

Stream Identifier: 한 커넥션 안에서 스트림을 식별하는 값. 특히, 0은 커넥션 전체와 연관된 프레임을 의미

HTTP/2.0에서 스트림의 타입은 DATA, HEADERS, PRIORITY, RSTSTREAM, SETTINGS, PUSHPROMISE, PING, GOAWAY, WINDOW_UPDATE, CONTINUATION이 있다.

10.3.2 스트림과 멀티플렉싱

스트림은 HTTP/2.0 커넥션을 통해 클라이언트와 서버 사이에 교환되는 프레임들의 독립된 양방향 시퀀스다. 스트림은 한 쌍의 요청과 응답으로 되어 있고, 응답이 되면 스트림이 닫힌다. 하나의 커넥션에서는 다수의 스트림을 동시에 사용하기 때문에 식별자를 만들었다.

스트림으 식별자에는 몇가지 규칙이 있다. 스트림은 클라이언트든 서버든 요청하는 쪽에서 만들어 낸다. 이때 클라이언트가 만든 식별자는 홀수이고 서버가 만든 스트림은 짝수여야 한다. 또 새로 만들어지는 스트림은 이전에 만들어졌거나 예약된 스트림의 식별자보다 커야 한다. 이 규칙을 어기게 되면 PROTOCOL_ERROR를 마주할 것이다.

한 번 사용한 스트림은 다시 사용할 수 없으며, 사용할 수 있는 식별자 값은 고갈될 수 있는데, 그 때는 커넥션을 다시 만들면 된다. (스트림 식별자는 같은 커넥션 안에서만 식별한다.)

10.3.3 헤더 압축

HTTP/1.1 시절에 헤더는 아무런 압축 없이 그대로 전송되었다. 예전과 다르게 하나의 웹 페이지는 수백개의 리소스를 사용하는데 이때마다 헤더의 크기가 문제가 되었다. 이를 개선하기 위해 HTTP/2.0에서는 헤더를 압축하여 전송한다. 참고 HPACK 명세

10.3.4 서버 푸시

HTTP/2.0은 요청을 하나만 보내도 응답으로 여러 개의 리소스를 보낼 수 있게 한다. 기존에 서버에서 HTML을 내려주면 클라이언트에서 받아서 필요한 리소스를 재 요청 했는데, 이런 지연을 줄여준다.

서버 푸시를 사용하려면 서버가 먼저 클라이언트에게 PUSHPROMISE 프레임을 보내서 알려야 한다. (책에서도 자세한 설명을 자세히 하지 않는다.) 또 서버 푸시를 종료하기 위해서는 클라이언트에서 RSTSTREAM 프레임을 보내면 된다. 서버에서 푸시를 종료하려면 SETTINGSENABLEPUSH을 0으로 하며 된다.

서버 푸시를 사용할 때 주의할 점

  • 프락시가 서버푸시를 적절히 처리하지 않을 수 있다.
  • 서버는 안전하고, 캐시 가능하고, 본문을 포함하지 않은 요청에 대해서만 푸시를 할 수 있다.
  • 푸시할 리소스는 명시적으로 보낸 요청에 관련된 것이어야 한다.
  • 푸시한 리소스도 동일 출처 정책을 따른다.

10.4 알려진 보안 이슈

10.4.1 중개자 캡슐화 공격

HTTP/2.0 중개자(프락시)가 HTTP/1.1 로 변환할 때 문제가 될 여지가 있다. HTTP/2.0은 헤더 필드를 이름과 같은 바이너리 값으로 인코딩하게 되는데 이때 줄바꿈 문자조차 허용된다. 이는 문제의 소지가 될 수 있다.

다양히 HTTP/1.1 → HTTP/2.0 인 상황에서는 이런 문제가 발생하지 않는다고 한다.

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

커넥션을 오래 사용하기 때문에 개인 정보를 악용할 여지가 높아진다.