要約

  • RFC 1867 と RFC 2388 は、一つのフォーム欄から送る複数ファイルを、multipart/form-data の内側にある multipart/mixed パートとして表した。
  • RFC 7578 は、その形で送る実装を確認できなかったと記録し、一ファイル一パート、同じ欄名という構造に変更した。一方、古い入れ子を受け取る互換性は残した。

ファイル選択欄の先にあった課題

ブラウザーのフォームがローカルファイルを共通の仕組みで送信できる前は、受信側サービスが専用クライアントを用意することもあった。1995 年の RFC 1867 は HTML の INPUT TYPE=FILE と、フォーム値やファイル内容を運ぶ MIME 形式を提案した。ただし文書の分類は Experimental であり、完成したインターネット標準ではない。新機能を扱えないユーザーエージェントとの移行方法も検討されていた。

形式には二つの階層があった。外側の multipart/form-data がフォーム欄の名前を示す。同じ欄で複数のファイルが選ばれた場合は、その中に multipart/mixed をもう一段置き、ファイル群を包む。紙上では、欄とその値の集合を別の層に割り当てる設計だった。

1998 年の RFC 2388 は Standards Track 文書として multipart/form-data を HTML や HTTP に限らない形式にした。表計算ソフトなど、別のアプリケーションもフォームの値を返すために使える。それでも一欄の複数ファイルについては、内側の multipart/mixed を引き継いだ。実験的提案の構造が、再利用可能な仕様に移ったのである。

後継仕様が記録したずれ

RFC 2388 を置き換えた 2015 年の RFC 7578 は、送信方法について珍しく明快な説明を残した。入れ子方式は生成側への推奨から外され、受信側にも必須とはされなかった。理由は、その方式を送る実装が知られていなかったからだ。記録できた実装に合わせ、各ファイルには独立した外側の form-data パートを与え、同じフォーム欄に属するパートは同じ name を持つ。

グループ化の場所は変わった。以前は一つの名前付きパートが、その中に複数ファイルの一覧を抱えた。修正後は外側に複数パートが並び、欄名の反復で関連づける。RFC 7578 は旧形式を不正と宣言したのではない。広く使われる受信実装には、従来の入れ子も引き続き扱うよう勧めている。新しい送信規則と旧データの読み取りは、別々に扱われた。

「既知の実装がない」は RFC 7578 の著者が把握した範囲を示す。歴史上一度も送信されなかったことや、どのブラウザーにも採用されなかったことを証明する数値ではない。ベンダー名、普及率、切り替わった時期、障害率も記されていない。それでも、前の RFC が記述した形式を送る実装を次の標準の著者が見つけられず、記述を改めた事実は残る。

同じ欄名をどう保つか

RFC 2388 は、フォーム内の順序が返却パートにも引き継がれるか、同じ名前の欄が複数ある場合どう処理するかも定義していなかった。RFC 7578 は、フォーム側に定まった順序があるならそれを保ち、中間者は結果を並べ替えず、同名パートを一つにまとめないよう定める。繰り返しは衝突ではなく、ひとつの欄に属する複数の値として扱える。

これは MIME の構造全体を捨てた変更ではない。パートの境界は引き続きあり、フォームによっては自然な順序がない。直されたのは、一つの複数ファイル欄を同じ名前の兄弟パートとして表すという具体的な部分だ。フォーム、意図された順序、各パートのバイト列、受信アプリケーションの判断は、なお別の段階にある。

実装を証拠として読む

Heng Lu の Running-Code Primacy は、仕様書の文言と実行されるインターネットの間にある差を重視する。RFC 2388 の修正は、その点を狭い範囲で見せる。RFC 7578 は古い文面を保存すること自体を目的にせず、確認できた送信側の動作に合わせて複数ファイルの形を変えた。同時に、受信側には旧構造との互換性を残した。

誰が変更を始めたか、何種類のソフトウェアが関わったか、どの運用コストが決定を促したかは、記録から分からない。実装者が常に正しい、あるいは標準は何でも既成事実に従うべきだという証拠でもない。言えるのはもっと限定的だ。形式を記述したら、実際に送るシステムを確かめる。ルールを変えるなら、古いデータの読み取り方も残す。

出典