요약

  • RFC 1867과 RFC 2388은 하나의 폼 필드에서 여러 파일을multipart/form-data안에 중첩된multipart/mixed파트로 표현하는 방식을 기술했습니다.
  • RFC 7578은 이후 그 전송 방식의 구현이 알려진 바 없다고 밝히고, 전송자에 대해서는 파일마다 하나의 최상위 파트를 두는 방식으로 대체하되, 이전 중첩 형식에 대한 수신자 측 지원은 호환성 조치로 유지했습니다.

파일 선택기에는 전송 형식이 필요했다

HTML 폼이 공통 브라우저 메커니즘을 통해 로컬 파일 내용을 제출하기 전에는, 서버가 별도의 사용자 지정 클라이언트를 필요로 하는 경우가 많았습니다. RFC 1867은INPUT TYPE=FILE컨트롤과 일반 필드와 파일 바이트를 모두 담을 수 있는 MIME 표현을 제안했습니다. 이 아이디어에는 중요한 단서가 따라 붙었습니다. 해당 문서는 완성된 인터넷 표준이 아니라 실험적(Experimental) 문서였고, 호환성 계획은 여전히 새로운 업로드를 수행할 수 없는 사용자 에이전트를 상정하고 있었습니다.

단일 파일을 선택한 경우 폼은 하나의 파트를 보낼 수 있었습니다. 하나의 필드에 여러 파일이 선택된 경우, RFC 1867은 첫 번째 멀티파트 본문 안에 두 번째 멀티파트 본문을 그렸습니다. 바깥의multipart/form-data는 폼 필드를 식별했고, 안쪽의multipart/mixed가 파일들을 운반했습니다. 이 컨테이너 구조는 서면으로는 이해하기 쉬웠습니다. 각 중첩 수준에는 각자의 역할이 있었습니다.

1998년에 Standards Track으로 발표된 RFC 2388은 이 미디어 타입을 HTML과 HTTP에서 분리했습니다. 스프레드시트나 다른 애플리케이션도 이를 사용할 수 있게 된 것입니다. 그러나 파일 집합을 담는 필드에 대한 규칙은 중첩된multipart/mixed배열을 그대로 유지했습니다. 1995년 제안이 재사용 가능한 사양이 되었고, 그 예제의 한 세부 사항이 규정된 형태가 되어 버렸습니다.

전송되는 실제 모습은 도식을 따르지 않았다

2015년에 RFC 2388을 폐기(obsolete)한 RFC 7578은 이 불일치를 이례적으로 솔직하게 기록합니다. 이 문서는 중첩 방식이 작성자에게 대해 폐기(deprecated)되었으며, 전송 구현이 알려진 바 없기 때문에 수신자에게 요구되지도 않았다고 명시합니다. 구현에 맞추기 위해 새 규칙은 각 파일에 자신의 최상위 form-data 파트를 부여하고, 하나의 폼 컨트롤에 대한 여러 파트가 동일한name매개변수를 반복하도록 정했습니다.

이는 그룹화가 어디에 존재하는지에 대한 변화입니다. 이전 설계에서는 이름이 지정된 하나의 파트가 중첩된 파일 목록을 담았습니다. 대체 방식에서는 바깥쪽 시퀀스가 동일한 필드 이름을 지닌 여러 파트를 담습니다. 새 사양은 중첩된 MIME이 구문상 불가능해졌다고 주장하지 않았습니다. 폭넓은 용도의 수신자는 이전 형식을 받아들이도록 권고를 유지했습니다. 전송자 권고는 바뀌었지만, 수신 경계의 호환성은 남았습니다.

저자들의 "알려진 구현이 없다(no known implementations)"는 표현은 RFC 7578의 개정 과정이 확인할 수 있었던 것에 대한 근거이지, 어떤 전송자도 이전 구조를 내보낸 적이 없다는 것을 증명하는 전수 조사가 아닙니다. 이는 특정 벤더, 브라우저 점유율, 최초 사용 시점, 실패율 중 어느 것도 제공하지 않습니다. 다만 이는 이전 RFC가 기술한 데이터 형태에 대해 전송 구현을 지목할 수 없었기 때문에 표준 문서가 그 데이터 형태를 개정했다는 사실은 확립합니다.

표준은 시퀀스의 의미도 정해야 했다

이 개정은 두 번째 모호성도 바로잡았습니다. RFC 2388은 폼 순서와 반환되는 파트 순서 사이의 관계를 명시하지 않았고, 필드 이름이 반복될 때 무슨 일이 일어나는지도 정의하지 않았습니다. RFC 7578은 폼이 순서를 정의한 경우 프로세서가 그 순서를 유지해야 하며, 중개자는 결과를 재정렬해서는 안 되고, 이름이 동일한 파트는 병합되어서는 안 된다고 규정합니다. 이 지침들은 반복되는 이름이 우연한 충돌이 아니라 반복되는 값으로 사용될 수 있게 만듭니다.

이 변화를 "MIME 중첩"에서 "평탄한 데이터"로의 이동이라고 요약하고 싶은 유혹이 있습니다. 그것은 너무 광범위합니다. MIME은 여전히 파트 구조를 제공하며, 일부 폼에는 자연스러운 순서가 없습니다. 구체적인 수정은 더 좁았습니다. 다중 파일 폼 컨트롤은 여러 개의 동격 파트로 표현되며, 공유된 필드 이름이 그 연관성을 운반한다는 것입니다. 이를 감싸는 요청, 폼이 의도한 순서, 각 파트의 바이트, 수신 애플리케이션의 해석은 여전히 서로 구별됩니다.

구호가 아니라 근거로서의 동작 코드

Lu Heng의 running-code 우위에 관한 에세이는 인터넷 조율이 텍스트만을 현실로 취급하기보다 구현된 동작을 진지하게 받아들여야 한다고 주장합니다. RFC 2388은 이에 대한 소박하고 이례적으로 명확한 사례를 제공합니다. RFC 7578은 이전의 모든 권고를 그 자체를 위해 보존하지 않았습니다. 저자들은 확인할 수 있었던 전송자 동작에 맞추어 다중 파일 인코딩을 변경하면서, 수신자에 대한 호환 경로는 유지했습니다.

이것이 구현자가 항상 프로토콜을 옳게 만든다는 것이나, 표준이 우연히 소프트웨어가 하는 대로 무조건 추인해야 한다는 것을 보여주지는 않습니다. 이 문서는 누가 먼저 변경했는지, 몇 개의 시스템이 관련되었는지, 어떤 운영상 비용이 이를 이끌었는지에 대한 어떤 서술도 제공하지 않습니다. 기록이 뒷받침하는 것은 양방향의 규범 제정 원칙입니다. 전송 형태를 규정하고, 실제로 그것을 내보내는 주체를 찾고, 배포된 데이터에 이전 형태가 여전히 존재할 수 있을 때 그것을 읽을 방법을 보존하는 것입니다.

출처