요약
- RFC 6455는 HTTP/1.1 GET과
Upgrade, 101 응답으로 WebSocket을 열었다. 여러 스트림을 동시에 싣는 HTTP/2의 RFC 7540은 연결 전체를 바꾸는 101 절차를 없앴다. - RFC 8441은 서버의
SETTINGS_ENABLE_CONNECT_PROTOCOL = 1을 받은 뒤 클라이언트가 새 스트림에:protocol = websocket,:scheme,:path를 포함한 확장 CONNECT를 보낼 수 있게 했다. IANA의 설정 번호는0x8, 초기값은0이다. - 열린 스트림이 WebSocket 데이터를 나르는 동안 같은 연결의 다른 스트림은 계속 움직인다. 이전 방식의
Connection,Upgrade,Sec-WebSocket-Key/Accept처리는 새 출발 절차에 쓰이지 않는다.
복도 전체를 바꾸는 스위치는 너무 컸다
2011년 WebSocket 규격은 HTTP/1.1 요청에서 시작했다. 클라이언트는 Upgrade: websocket, Connection: Upgrade를 단 GET을 보내고 서버는 101 Switching Protocols로 응답할 수 있었다. 그 뒤 TCP 연결 전체가 두 방향의 WebSocket 채널이 됐다. 연결 한 개가 요청 한 개를 담당할 때는 통로를 통째로 넘기는 일이 자연스러웠다.
HTTP/2는 통로 하나를 여러 스트림으로 나눠 쓴다. 페이지가 이미지를 받는 동안 다른 기능은 오래 지속되는 대화를 원할 수 있다. RFC 7540은 HTTP/2 안에서 101을 허용하지 않는다. Upgrade와 Connection은 연결 전체에 걸친 지시다. 채팅 스트림 하나가 옆 스트림의 운명까지 정할 수는 없다. 새 공유 구조에 옛 WebSocket 열쇠가 맞지 않았다.
이는 단순히 응답 번호가 달라진 문제가 아니다. 앱은 페이지용 HTTP/2 연결을 이미 쓰면서 실시간 기능을 위해 별도 길을 찾아야 했다. 채팅이 연결 전체를 빼앗으면 나머지 요청이 갈 곳을 잃는다. RFC 8441은 WebSocket이 차지할 수 있는 자원 범위를 연결에서 스트림으로 줄였다.
서버가 작은 문을 먼저 연다
서버는 SETTINGS_ENABLE_CONNECT_PROTOCOL = 1을 보내 지원을 알린다. IANA HTTP/2 설정 등록부는 번호 0x8, 초기값 0을 기록한다. 클라이언트는 값 1을 받은 뒤에야 새 스트림에서 확장 CONNECT를 사용할 수 있다. 허용 전에 새로운 의사 헤더를 보내면 확장을 모르는 서버에는 형식이 잘못된 요청이 된다. 설정은 장식용 기능 표시가 아니라 요청의 뜻을 바꾸기 위한 문지기다.
문이 열리면 클라이언트는 새 HTTP/2 스트림에 :method = CONNECT, :protocol = websocket을 적는다. 대상 URI를 나타내는 :scheme, :path, :authority도 함께 보낸다. 여기서 :authority를 읽는 방법이 달라진다. 일반 CONNECT에서는 터널을 열 호스트를 가리키지만, 확장 CONNECT에서는 대상 URI의 권한 부분이다. RFC 8441은 서버가 CONNECT라는 단어만 보고 그 호스트로 별도의 전통적 터널을 만들지 말라고 명시한다. :protocol이 새 스트림의 내부 프로토콜을 말한다.
보호된 WebSocket URI는 대상 scheme에 https, 보호되지 않은 URI는 http를 쓴다. 나머지 경로는 WebSocket URI에서 온다. HTTP/2 정방향 프록시를 통해 접속한다면 클라이언트는 먼저 전통적 CONNECT로 WebSocket 서버에 이르는 터널을 만들고, 그 터널에서 사용하는 HTTP 버전에 맞춰 이후의 시작 절차를 선택한다. 서버를 향한 확장 요청과 프록시를 향한 터널 요청은 다른 단계다.
연결 전체가 아니라 스트림이 양방향이 된다
확장 CONNECT는 기존 GET 기반 열기를 대신한다. Connection, Upgrade를 보내지 않고 HTTP/1.1의 Sec-WebSocket-Key, Sec-WebSocket-Accept 교환도 처리하지 않는다. 이 경로에서는 :protocol이 그 기능을 대신한다. Origin, WebSocket 버전, 하위 프로토콜과 확장 헤더는 WebSocket 규칙에 따라 남는다. 입장 절차가 바뀌었을 뿐, 들어간 뒤의 프레임 프로토콜은 계속된다.
RFC 8441의 예에서는 서버 설정, 클라이언트의 확장 CONNECT, 서버의 :status = 200이 차례로 나온다. 이어 HTTP/2 DATA 프레임이 두 방향으로 WebSocket 데이터를 운반한다. 선택된 스트림을 RFC 6455가 말하던 TCP 연결처럼 취급한다. 옆 스트림은 보통 요청이나 다른 터널을 계속 나를 수 있다. 우선순위, 취소, 흐름 제어도 HTTP/2 체계에 남고, END_STREAM과 RST_STREAM이 이 스트림의 정상 및 예외 종료를 나타낸다.
채팅은 오래 열려 있어도 이미지 요청을 인질로 잡지 않는다. 서버는 설정을 보내지 않음으로써 새 방식을 거절할 수 있고, 클라이언트는 특별한 요청을 보내기 전에 그 결정을 확인할 수 있다. 둘의 동의가 설정과 헤더에 드러난다. 중간 장비가 다중 스트림 안에서 옛 101의 뜻을 추측할 이유가 없다.
다른 입주자가 연결에 남았다
RFC 8441은 범위를 좁힌 설계였다. WebSocket을 HTTP/2에 더 깊게 결합할 수도 있었지만, 확장 CONNECT는 두 프로토콜을 한 연결에서 함께 돌리는 당면 문제를 풀었다. 2018년에 바뀐 것은 통로에 들어가는 절차다. 이후 WebSocket 프레임과 RFC 6455의 대부분 보안 조건은 남는다. 앞선 프레임 마스킹 이야기가 데이터 형태를 다뤘다면, 여기의 쟁점은 어느 스트림이 그 데이터를 실을 허가를 얻는가다.
네 공식 기록은 절차와 설정 등록을 보여 준다. 특정 서비스의 사용 사실을 입증하려면 날짜가 있는 클라이언트·서버·프록시 릴리스와 실제 SETTINGS, HEADERS 교환이 필요하다. 역사적 변화는 분명하다. HTTP/2는 한 대화에 공유 연결을 넘기지 않았고, WebSocket에는 상대의 허용을 받은 단일 스트림을 내줬다.
회원 브리핑
프로필 심층 컨텍스트
올바른 멤버십 등급으로 로그인하면 전체 브리핑과 출처 노트를 볼 수 있습니다.
전략 서클 전용
전략 서클
모든 독자에게 공개됩니다. 가입 후 로그인하면 프로필 브리핑를 열람할 수 있습니다.
전략 서클 가입Leadership Alliance 전용
Leadership Alliance
자격을 갖춘 IP 자산 소유자 및 운영진을 위한 콘텐츠입니다. 로그인하면 Leadership Alliance 브리핑을 열람할 수 있습니다.
Leadership Alliance 가입하기





