요약

  • RFC 3391은 MIME 메시지를 번호가 매겨진 길이 구분 청크로 나누어 인터리빙함으로써, 참조된 이미지가 그 이미지를 부르는 루트 문서 구절 바로 앞이나 뒤에 도착하도록 했다.
  • 근접성은 소비자에 대한 지식이 아니라 생산자의 일정이었다. 이 형식은 레이아웃, 메모리 용량, 파싱 순서, 폐기 시점을 알려 줄 수 없었고, 잘못된 일정은 유용한 상한 없이 저장 공간을 계속 늘릴 수 있었다.

스캐너가 멀리 있는 프린터로 페이지를 공급하는 장면을 상상해 보자. 스캐너는 그 페이지에 도달해야만 각 이미지를 발견한다. 기존의 복합 MIME 객체는 어색한 선택지를 제시한다. 모든 첨부물을 본문 앞에 두어 수신자가 그것들을 들고 있게 하거나, 모든 첨부물을 본문 뒤에 두어 수신자가 기다리게 하는 것이다. 어느 쪽 순서도 종이 위에서는 정갈하지만 시간이 지나며 알려지는 문서와는 잘 맞지 않는다.

2002년 12월에 Informational 문서로 발표된 RFC 3391은 세 번째 순서를 제시했다. 미디어 타입application/vnd.pwg-multiplexed는 생산자가 여러 MIME 메시지를 조각으로 나누어 그 조각들을 하나의 바이트 스트림에 엮어 넣을 수 있게 했다. 루트 문서는 어떤 이미지를 참조하기 직전까지 진행할 수 있고, 그 이미지는 그 지점 바로 앞이나 뒤에 나타날 수 있다. 요청과 재료 사이의 거리가 생산자가 관리할 수 있는 객체가 된 것이다.

이 제안은 새로운 종류의 복합 문서를 발명하지 않았다. 복합 객체와 그 표현을 신중히 분리했다. 객체는 루트 구성 요소와 그것으로부터 참조되는 다른 구성 요소를 가진다.multipart/related는 이 구성 요소들을 경계 문자열로 나뉜 순차적 본문 부분으로 표현한다. RFC 3391은 이것들을 번호가 매겨진 청크 안에 담긴 MIME 메시지로 표현한다. 재조립된 각 메시지는 옥텟 단위까지multipart/related에서 같은 구성 요소를 표현했을 본문 부분과 일치하도록 의도되었다.

차이는 일정에 있었다. 청크는CHK로 시작하고, 메시지 번호, 페이로드 길이,MORE또는LAST가 뒤따른다. 길이가 페이로드를 자체 구분 가능하게 만들고, CRLF가 다음 헤더와의 시각적 분리를 제공했다.MORE는 같은 메시지의 또 다른 조각을 약속하고,LAST는 그것을 닫는다. 서로 다른 메시지에 속한 청크들이 번갈아 나올 수 있지만, 하나의 메시지 조각들은 원래 순서를 유지해야 했다.

두 개의 경계가 스트림을 이해 가능하게 유지했다. 첫 청크는 루트 메시지의 전부 또는 일부를 담아야 했다. 이 규칙조차 빈 페이로드를 허용했는데, 이는 실제 루트 바이트를 나중에 시작할 수 있게 하는 편의 장치였다. 반대쪽 끝에서는CHK 0 0 LAST가 엔티티를 닫았다. 메시지 번호 0은 이 센티널에 속한다. 너무 일찍 그것을 보는 것이 빠진 마무리를 마법처럼 고쳐 주지는 않는다. RFC는 모든 메시지가 마지막 청크를 받기 전에 최종 청크가 나타나면 소비자의 동작이 정의되지 않는다고 말한다.

메시지 번호는 보통 하나의 메시지를 식별하지만, 이 형식은 재사용을 절대적으로 금지하지 않았다. 번호를 재사용한다면 그 번호를 가진 이전의 각 메시지가 다음 메시지가 시작되기 전에LAST에 도달해야 했다. 이 세부 사항은 설계의 기질을 보여 준다. 같은 번호와 길이 0 페이로드를 가진 인접 청크 같은 구현 편의를 허용하면서도 정밀한 재구성 규칙을 유지했다.

필수type매개변수는 루트 메시지의 미디어 타입을 선언했다. 소비자가 둘러싸인 루트를 검사하기 전에 복합 객체의 타입을 알 수 있는 방법이었다. 선언과 루트가 불일치하면 동작은 정의되지 않았다. Content-ID와 Content-Location은 확립된 MHTML 패턴을 사용해 참조를 구성 요소에 연결할 수 있었다. RFC 3391은 그 관계 언어 자체에 대한 권위를 주장하지 않았다.

인쇄 예제는 이 모든 장치가 왜 존재했는지 설명한다. 긴 인쇄 스트림이 페이지가 생성될 때마다 이미지를 이름짓는다고 하자.multipart/related에서는 루트 뒤에 놓인 이미지가 루트가 끝나기 전까지는 도움이 되지 못하고, 루트 앞에 놓인 이미지는 생산자가 미리 발견하고 수신자가 미리 저장하도록 강요한다. 멀티플렉스된 스트림은 루트를 잠시 멈추고 관련 이미지를 보낸 뒤 루트를 계속할 수 있다. 고속 프린터는 첫 페이지의 재료가 도착했는지 알기 위해 문서 전체를 기다릴 필요가 없다.

스캐닝 예제는 몇 가지 압박을 뒤집는다. 각 스캔 페이지는 이미지 하나와 루트 참조 하나를 가질 수 있다. 이미지를 참조 바로 앞이나 뒤에 보내면 생산자가 작업 전체를 버퍼링하는 대신 점진적으로 일할 수 있다. 이것은 문자 그대로의 의미에서 국소성이다. 이름과 그 이름이 가리키는 바이트 사이에 더 적은 옥텟만 놓인다.

그러나 세 번째 예제는 이 매력적인 다이어그램을 뒤집는다. 레이아웃을 소유하는 쪽은 생산자가 아니라 소비자일 수 있다. 두 이미지가 나란히 놓일 수 있다. 텍스트가 이미지 주위를 감쌀 수 있다. 생산자는 참조를 어디에 두었는지는 알지만, 소비자가 한 줄을 어디서 마칠지, 얼마나 많은 텍스트를 유지할지, 이미지를 언제 놓을 수 있는지는 알지 못한다.

생산자가 나란히 놓인 이미지들의 밴드를 인터리브하다가 메모리가 부족해지면, 수신자는 불완전한 그림들이 번갈아 남겨진 상태가 될 수 있다. RFC 3391은 그러한 일정을 권하지 않는다. 텍스트가 이미지 주위를 감쌀 때 텍스트 청크를 너무 일찍 자르면 소비자가 이미지 전체를 버퍼링하거나 감쌈을 조기에 끝내도록 강요될 수 있다. 너무 늦게 자르면 수신자가 과잉 텍스트를 들고 있거나 이미지가 의도보다 늦게 놓일 수 있다. 텍스트가 보통 이미지 데이터보다 저장 비용이 적게 들기 때문에 문서는 이미지 앞에 더 많은 텍스트를 두는 쪽으로 여유를 두라고 권한다. 이것은 보편적 최적이 아니다. 불확실성 아래의 전략이다.

IESG는 그 불확실성을 RFC의 맨 앞에 놓았다. 미디어 타입은 생산자가 소비자의 능력과 제약을 완전히 이해할 때만 적절했다. 서로 다른 소비자는 서로 다른 시점에 서로 다른 구성 요소를 필요로 할 수 있었고, 그 표현은 물어볼 방법을 제공하지 않았다. 수신자를 알 수 없을 때는 BEEP 같은 양방향 프로토콜을 고려하라고 그 문서는 권했다.

이 대조는 아키텍처적이다. 멀티플렉싱은 생산자에게 더 나은 일방향 일정을 준다. 양방향성은 소비자가 수요를 표현하거나 제어를 행사할 수 있게 해 준다. RFC 3391의 예제에서 BEEP 채널은 프린터가 참조를 만났을 때 이미지를 요청하거나 자신의 레이아웃에 맞는 밴드를 요청할 수 있게 해 줄 수 있었다. 그 유연성은 고속 프린터가 피하려 했던 대기를 초래할 수 있었다. 선택은 '새 형식이 좋고 옛 프로토콜이 나쁘다'는 것이 아니었다. 예측적 배치와 관찰 가능한 수요 사이의 절충이었다.

소비자의 권위는 표시 규칙에서도 나타났다. 애플리케이션이 멀티플렉스 타입과 루트 타입을 모두 이해할 때는 구성 요소를 복합 객체의 일부로 제시했다. 내장된 Content-Disposition 제안은 중복되거나 오해를 낳을 수 있으므로 표시를 위해 무시해야 했다. 컨테이너는 이해하지만 루트를 이해하지 못하는 소비자는 객체를 숨기거나 메시지를 섞인 첨부물로 노출할 수 있었다. 둘 다 이해하지 못하는 소비자는 엔티티를 불투명하게 다뤘다. 같은 바이트가 최종 제시를 스스로 소유하지는 않았던 것이다.

보안은 일정 권한에서 직접 뒤따랐다. 결함이 있거나 적대적인 생산자는 메시지들을 시작해 놓고 그 마지막 청크를 막대한 수의 옥텟에 걸쳐 미룰 수 있었다. 많은 메시지를 동시에 열어 둘 수 있었다. 절대 도착하지 않을 메시지에 대한 참조를 놓거나, 수신자가 폐기할 수 있음을 알기 전에 많은 참조된 메시지를 배달할 수 있었다. 개별 청크마다 유효한 길이와 그럴듯한 계속 플래그가 있으면서도 전체 저장 의무는 계속 커질 수 있었다.

이것이 프레이밍의 증거적 한계다. 파서는 헤더의 문자를 검증하고, 선언된 페이로드를 세고, 같은 메시지 번호를 가진 청크들을 이을 수 있다. 그러나 그런 국소적 성공으로부터 메모리 상한을 도출할 수는 없다. 참조된 모든 구성 요소가 결국 나타날 것, 루트 타입이 진실일 것, 레이아웃이 성공할 것, 수신자가 송신자가 상상한 소비자일 것을 추론할 수 없다.

Lu Heng의 최소 초기 명세(Minimum Initial Specification) 원칙은 이 강점과 절제를 모두 설명하는 데 도움이 된다. RFC 3391은 독립적 구현들이 표현을 재구성하는 데 필요한 것만을 표준화했다. 번호, 길이, 계속 상태, 루트 식별, 마감이다. 레이아웃이나 저장 정책을 국유화하지 않았다. 미래의 소비자는 미디어 타입에게 허락을 구하지 않고 다른 결정을 내릴 수 있었다.

Running-Code Primacy는 그에 상응하는 부담을 제공한다. 등록된 미디어 타입과 유효한 테스트 벡터가 실제 프린터가 계속 움직였는지, 스캐너가 버퍼링을 피했는지, 적대적 입력이 우아하게 처리되었는지를 증명하지 못했다. 그런 주장은 관찰된 구현에 속했다. RFC는 문법과 경고를 제공했다. 실행 중인 시스템이 영수증을 제공했거나, 그러지 못했다.

따라서 RFC 3391은 천리안의 역사가 아니라 거리의 역사다. 송신자가 바이트들을 유용해 보이는 순간 가까이로 옮길 수 있게 했다. 그러나 그 순간을 수신자의 눈으로 볼 수 있게 하지는 않았다. 이미지는 참조 옆에 도착하면서도 여전히 잘못된 선반을 차지하고, 잘못된 레이아웃을 기다리고, 메모리 속에서 미완성으로 남을 수 있었다. 근접성은 순서 문제를 해결했다. 피드백은 여전히 다른 능력이었다.

출처