요약

  • 2000년 10월 RFC 2965는 신구 쿠키 규칙의 협상을 설계했다. 두 방식을 모두 이해하는 클라이언트는 해당하는 옛 Cookie를 계속 보내면서 Cookie2: $Version="1"로 새 방식 지원을 알리도록 했다. 새 서버는 Set-Cookie2로 이어가고 오래된 서버는 알림을 무시할 수 있었다.
  • 새 응답의 Port 속성은 쿠키가 돌아갈 포트를 제한하고, CommentURL은 사용자에게 설명을 제공할 주소를 둘 수 있었다. 지원 선언, 서버의 응답, 사람이 설명을 읽고 내리는 결정은 서로 다른 단계다.
  • 2011년 4월 RFC 6265는 RFC 2965를 대체하고 역사적 문서로 옮기도록 요청했으며 Cookie2와 Set-Cookie2를 폐기했다. 실제 인터넷에서 쓰이는 Cookie/Set-Cookie를 규정하고, 같은 호스트의 쿠키가 서로 다른 포트에 걸쳐 공유된다고 적었다.

브라우저가 새 언어의 신분증을 내밀다

쇼핑몰은 HTTP 요청 한 번이 끝나도 장바구니를 기억해야 한다. 서버가 브라우저에 상태 값을 주고, 브라우저가 알맞은 다음 요청에서 그 값을 돌려준다. 1997년 2월 RFC 2109은 이 교환을 이른 시기에 문서화했다. 규칙을 바꾸려면 이미 설치된 브라우저와 서버를 상대해야 했다. 웹 전체의 소프트웨어를 같은 날 한꺼번에 업데이트할 중앙 관리자는 없었다.

2000년 10월 RFC 2965는 협상으로 업그레이드를 시도했다. 서버가 보내는 새 응답은 Set-Cookie2, 클라이언트가 보내는 능력 알림은 Cookie2였다. 새 규칙과 옛 쿠키를 모두 아는 브라우저는 옛 Set-Cookie로 받았던 값에 대해 알맞은 기존 Cookie를 계속 보낸다. 그 옆에 Cookie2: $Version="1"을 붙여 자신은 새 규칙도 이해한다고 알린다.

서버 역시 새 방식을 이해한다면 이후 Set-Cookie2로 세션을 이어가도록 했다. 모르는 서버는 그 추가 필드를 무시하면 그만이다. 기존 대화는 유지된다. 새로운 브라우저가 자기 능력을 밝힌다고 해서 오래된 서버가 다음 요청 전에 새 코드를 설치해야 하는 것은 아니었다.

세 필드는 맡은 일이 다르다. Cookie2는 브라우저의 지원 버전을 알리는 표지다. 세션 값을 전부 담아 보내는 새로운 상자가 아니다. Set-Cookie2는 서버에서 브라우저로 전달하는 새 쿠키와 속성이다. 저장한 값 중 해당하는 것들은 나중에 요청의 Cookie로 돌아간다. 통신 기록에서 표지만 봤다면, 서버가 새 방식으로 답했는지와 그 값이 다시 왔는지는 별도로 찾아야 한다.

프로토콜의 이런 단계 구분은 실제 결과를 읽는 데 중요하다. 신분증을 보여줬다는 사실은 서버가 문을 열었다는 사실과 다르다. 새 쿠키가 저장됐다는 사실도 쇼핑몰에서 주문이 끝났다는 기록을 대신하지 않는다. 규격은 기계 사이에 어떤 메시지를 주고받는지 정했고, 각 사이트의 행동은 그 뒤에 이어졌다.

새 통로의 물건들

Set-Cookie2에는 이름 끝의 숫자보다 의미 있는 변화가 있었다. Port 속성은 쿠키가 돌아갈 곳을 좁힐 수 있었다. 속성이 없으면 같은 호스트의 관련 포트 어디로든 보내질 수 있다. 값 없이 Port만 쓰면 처음 받은 포트로만 돌아가야 한다. 목록을 쓰면 열거된 포트에만 전송한다. 한 컴퓨터에서 서로 다른 서비스를 운영할 때는 상태 값의 행선지를 구분할 수 있는 선택지였다.

CommentURL은 사용자에게 설명할 통로였다. 2000년 문서는 서버가 쿠키의 목적을 알리도록 권했고, 짧은 문장보다 풍부한 내용과 여러 언어를 담을 수 있는 페이지 주소를 선호했다. 쿠키라는 기계적인 저장 절차에 읽어볼 자리를 만든 셈이다. 주소를 내놓는 일과 사람이 실제로 그 페이지를 읽고 선택하는 일은 각기 다른 사건이다.

새 헤더들은 따라서 단순히 낡은 이름을 교체하려는 시도가 아니었다. 더 세밀한 포트 범위, 설명 페이지, 상대방의 지원 여부를 알아보는 신호가 한 묶음이었다. 다만 브라우저와 서버가 모두 그 묶음을 실행해야 효력이 생긴다. 한쪽에 새 기계가 있어도 상대방이 옛 통로를 쓰면 그 기능은 통신에 나타나지 않는다.

호환 규칙이 길어진 이유도 여기에 있다. Set-Cookie2를 모르는 브라우저는 익숙한 쿠키 동작을 계속한다. 양쪽 방식을 모두 아는 브라우저는 각 값이 어느 응답 필드에서 왔는지 구별해야 한다. 같은 쿠키에 관해 한 응답에 옛 필드와 새 필드가 함께 있을 때는, 새 방식을 아는 클라이언트가 새 값을 우선하게 했다. 오래된 세션을 살리는 일은 새 프로그램에 두 갈래 규칙을 동시에 다루는 숙제를 안겼다.

공식 문서에는 얼마나 많은 브라우저가 Cookie2를 보냈고 얼마나 많은 서버가 Set-Cookie2로 응답했는지 집계가 없다. 날짜가 남은 소프트웨어 출시 기록과 실제 요청·응답이 그 보급사를 밝힐 수 있다. 두 RFC만으로 확실히 알 수 있는 것은 업그레이드의 설계와 이후 표준의 판단이다.

2011년 규격이 돌아선 곳

2011년 4월 RFC 6265는 출발점을 바꿨다. 인터넷에서 실제로 쓰이는 Cookie와 Set-Cookie를 정의한다고 밝혔다. 서문은 Netscape의 설명, RFC 2109, RFC 2965가 그 실제 사용을 제대로 설명하지 못했다고 적었다. 서버에는 질서 있는 발행 형태를 권하고, 클라이언트에는 이미 가동 중인 다양한 서버와 맞물릴 수 있도록 더 관대한 해석 규칙을 요구했다. 도로 위 차를 보고 도로 규칙을 다시 쓴 것이다.

같은 서문은 RFC 2109와 RFC 2965를 역사적 상태로 옮기자고 요청하고, RFC 2965를 대체하며, Cookie2와 Set-Cookie2를 명시적으로 폐기했다. 헤더 등록 부분에서도 두 이름은 폐기 상태다. 능력 명찰과 그에 맞춘 새 발급구가 중심 계약에서 빠졌다. 사이트가 계속 쓰던 Cookie와 Set-Cookie가 남았다.

2011년 문서는 남은 방식의 약점도 숨기지 않았다. 같은 호스트의 쿠키는 포트를 가로질러 공유되지만, 브라우저의 동일 출처 정책은 보통 서로 다른 포트에서 가져온 콘텐츠를 구분한다고 지적했다. 2000년의 Port 속성이 좁히려던 바로 그 경계다. 뒤의 표준은 버전 있는 포트 제한을 새 중심으로 되살리는 대신, 실제로 유지된 교환을 기술했다.

이 갈림길은 헤더 이름을 고르는 취향 문제가 아니다. 서버는 자기 응답을 고를 수 있지만 브라우저에 능력 알림을 강제할 수 없다. 브라우저는 자기 요청을 고를 수 있지만 오래된 서버에 새 규칙을 설치할 수 없다. 2000년 문서는 이 분산된 힘을 호환 절차로 연결했다. 2011년 문서는 분산된 프로그램들이 실제로 함께 쓰고 있던 언어를 기준으로 돌아왔다.

문서상의 결말은 분명하다. RFC 2965는 대체됐고 두 헤더는 폐기됐다. 어느 브라우저가 정확히 언제 이 필드를 구현하거나 제거했는지는 별도의 날짜 있는 구현 자료가 필요하다. 그러나 표준의 방향 전환은 2000년과 2011년의 원문에 그대로 적혀 있다.

비상 통로가 본관이 되다

Cookie2의 제안은 온건했다. 새 브라우저가 먼저 알리고, 새 서버가 받아주며, 옛 프로그램은 익숙한 길을 계속 걷는다. 호환을 지켰다는 장점이 있었다. 반대로 새 기능의 이익은 매번 양쪽이 함께 움직여야만 나타났다. 서버는 브라우저의 도입을 기다리고 브라우저는 서버의 도입을 기다릴 수 있었다.

그 선택의 흔적은 구체적이다. Port의 세밀한 범위와 CommentURL의 설명 통로는 폐기된 가지에 남았다. 실제 쿠키 교환에는 포트를 넘나드는 공유가 남았고, 2011년 문서도 이를 기록했다. 기능을 문서에 적는 일과 그 기능을 가동하는 프로그램을 널리 배포하는 일 사이에는 간격이 있다.

옛 방식을 남겨두는 호환성은 당장의 서비스를 살리지만, 새 방식으로 가야 할 긴급함도 덜어준다. Cookie2는 새 입구에서 정중하게 명찰을 들어 보였다. 11년 뒤 HTTP는 명찰을 서랍에 넣고 사람들이 계속 드나들던 입구를 정식으로 기록했다.