HTTP/1.1
은 구현의 단순성과 접근성
에 주안점을 둠
-> 성능이 희생됨 (ex. 응답을 받아야만 그 다음 요청을 보낼 수 있음)
-> 이런 문제를 해결하기 위해 병렬 커넥션(커넥션을 동시에 여러개 맺는건데, 근본적인 해결책은 아님), 파이프라인 커넥션(사용되지 않음) 등이 도입되었지만 해결되지 않음
이런 이유로 등장한 것이 구글의 SPDY(스피디) 프로토콜
-> 하나의 TCP 커넥션에서 여러 요청을 동시에 보낼 수 있음(멀티플렉싱 가능) & 서버 푸시 가능
-> 2012년 10월 3일, HTTP 작업 그룹은 SPDY를 기반으로 HTTP/2.0 프로토콜을 설계하기로 결정함
HTTP/2.0은 모든 메시지를 프레임에 담아 전송
스트림
은 HTTP/2.0 커넥션을 통해 클라이언트와 서버 사이에서 교환되는 프레임들의 독립된 양방향 시퀀스
이다.
한쌍의 HTTP 요청과 응답은 하나의 스트림을 통해 이루어진다.
HTTP/1.1의 특징
하나의 TCP 커넥션을 통해 요청을 보냈을 때, 그에 대한 응답이 도착하고 나서야 같은 TCP 커넥션으로 다시 요청을 보낼 수 있다
-> 그래서 보통 한번에 여러개의 TCP 커넥션을 만들어 동시에 여러 개의 요청을 보낸다.
-> 그렇지만 TCP 커넥션을 무한정 만들 수는 없고, 오늘날의 웹 페이지는 한번에 수십 수백건의 요청을을 보내야한다.
(-> 파이프라인 커넥션이 있지만, 이건 단점이 있어 널리 사용되지 않는다.)
HTTP/2.0의 특징
멀티 플렉싱
) 스트림은 우선순위를 가질 수도 있다
(보다 중요한 리소스, 예를 들어 이미지보다는 html 파일에 더 높은 우선순위를 줄 수 있다. 그러나 우선순위에 따르는 것은 의무사항은 아님
)모든 스트림은 31비트의 무부호 정수로 된 고유한 식별자
를 갖는다 (스트림이 클라이언트에 의해 초기화되었다면 이 식별자는 반드시 홀수, 서버라면 반드시 짝수 / 새로 생성되는 스트림의 식별자는 이전 스트림 혹은 예약된 스트림보다 커야함 -> 규칙을 어기는 식별자를 받으면 PROTOCOL_ERROR라는 응답 코드의 커넥션 에러로 응답)협상 없이 스트림을 만듦
(ACK 필요 없음) 한번 사용된 스트림 식별자는 다시 사용될 수 없음
-> 식별자가 고갈될 때에는 커넥션을 다시 맺으면 됨동시에 여러개의 스트림을 이용하면 스트림이 블록될 우려
가 있음 -> WINDOW_UPDATE 프레임을 이용한 흐름제어를 통해 스트림이 서로 간섭해서 망가지는 것을 막아줌HTTP/2.0은 1.1과 달리 헤더를 압축
-> 예전과 달리 하나의 웹페이지가 요청을 수십 수백개 보내기 때문에 헤더의 크기가 크면 회전 지연, 대역폭에 영향
HAPCK 명세에 정의된 헤더 압축 방법으로 압축한 후 헤더 블록 조각들로 쪼개져서 전송됨 -> 받는 쪽에서 복원 (헤더를 쓰지 않는 경우라도 무조건 압축 해제를 수행해야함. 그럴 수 없다면 COMPRESSION_ERROR와 함께 커넥션을 끊어야함)
PUSH_PROMISE 프레임을 보내 푸시할 것임을 알려야 한다
(클라이언트가 해당 자원을 별도로 요청하는 상황을 막기 위해) -> 클라이언트가 이를 받으면 해당 프레임의 스트림은 클라이언트 입장에서 'reserved(remote)' 상태가 된다. -> 클라이언트는 RST_STREAM 프레임을 보내 푸시를 거절
할 수 있다.오직 안전하고, 캐시 가능하고, 본문을 포함하지 않는 요청에 대해서만 푸시를 할 수 있다
HTTP/2.0은 헤더 필드로 어떤 문자열이든 허용한다. -> 따라서 HTTP/2.0 메시지를 중간의 프록시가 HTTP/1.1로 변환할 때 메시지가 위조될 가능성이 있다 (반대로 HTTP/1.1 -> 2.0으로 변환할 때는 이런 문제가 없음)
HTTP/2.0은 1.1보다 훨씬 긴 시간 커넥션을 유지한다. 어떤 사용자가 브라우저를 사용할 때 그 사용자는 이전에 브라우저를 사용했던 사용자가 무엇을 했는지 알아낼 가능성이 있음