要約
- MIME は本文エンティティに Message-ID と同型の
Content-IDを与え、並び順や外部アドレスに頼らず別のパートから参照できるようにした。 multipart/relatedは Content-ID で複合オブジェクトのルートを選び、cid:と長形式のmid:はその値をリンクとして表現した。- 世界的に一意となるよう生成する規則は、内容ハッシュ、認証、全世界からの取得可能性を意味しない。解決結果は親コンテナと受信側の判断に依存する。
URL なのに外へ出ない
Web のリンクは、現在の文書から別の場所へ移動するためのものとして理解されやすい。ところが複合 MIME メッセージのリンクは内向きにも働く。HTML パートが cid: で画像を指し、その画像もすでにメッセージの木の中にある。受信ソフトが行うのはネットワーク取得ではなく、手元の構造から対応するパートを探す処理である。
単なる添付ファイルの連番では足りなかった。メールゲートウェイはパートを並べ替えることがあり、保存システムは添付を切り出すことがあり、multipart の中に別の multipart が入る。三番目のパートという位置やファイル名だけでは、構造を組み替えた後も同じ対象を指す保証がない。
1992 年の RFC 1341 は、平坦なメール本文を型付きで再帰的な MIME エンティティへ拡張し、任意のフィールドとして Content-ID と Content-Description を導入した。Content-Type はデコード後のバイト列の解釈、Content-Transfer-Encoding は輸送時の表現、boundary はパートの境目を担う。それらとは別に、Content-ID は参照先となるエンティティを特定した。
RFC 2045 は 1996 年、その値が Message-ID と同じ構文を使い、世界的に一意となるよう生成されるべきだと定めた。同じ形でも対象は異なる。Message-ID はメッセージ全体を名指しし、Content-ID はトップレベル本文または入れ子になった一つの MIME エンティティを名指す。
仕様が挙げた用途の一つがキャッシュである。外部の取得方法を記述する message/external-body を生成する場合、Content-ID は必須だった。複数のアクセス方法の背後に同じ内容があることをキャッシュが認識できる。しかし値はバイト列から計算されない。同じ ID は生成側による同一性の主張であり、暗号学的な一致証明ではない。正しい ID があっても、DNS、HTTP オリジン、公開索引、アクセス権が自動的に生まれるわけでもない。
重複を許す条件が、識別子の限界を示した
一つの値を一つのシリアライズ済みパートに強制すると、実装は簡単に見える。RFC 2046 の multipart/alternative は、その前提を崩す。同じ情報をプレーンテキストや HTML など複数の表現で収め、受信側が扱えるものを選ぶためのコンテナだからだ。
変換によって情報が失われる表現同士には異なる Content-ID を付けるべきだが、同一データへの別々のアクセス方法を示す複数の message/external-body は同じ値を使える。キャッシュには一つの内容として見せ、どの表現を採るかは囲んでいる multipart の規則に任せる。
つまり Content-ID は、boundary で区切られたノードのデータベース主キーではない。意図された内容の同一性について、構造の中で解釈される証拠である。重複を常にエラーにすれば正当な alternative を壊す。どこでも無条件に許せば、曖昧なメッセージが参照をすり替えられる。値だけでなく親コンテナが不可欠となる。
複合オブジェクトには入口が要る
画像を含む HTML 文書は、無関係な添付の集合ではない。HTML が画像やスタイルを組織し、一体として表示される。1997 年の RFC 2110 は、Content-ID、CID URL、Content-Location を使って HTML 集合文書をメールへ封入する初期の MHTML 方式を標準化した。
翌年の RFC 2387 は、より一般的な multipart/related を定めた。type パラメーターはルートのメディア型を示し、任意の start パラメーターは Content-ID によって最初に処理するパートを選ぶ。start がなければ、先頭の本文パートがルートになる。
順序が既定値を持ち、識別子がそれを上書きする。ゲートウェイがルートを移動して start の関係を保存しなければ、すべてのバイトが残っていても意味は変わる。一方、start はどこにあるパートでも選べる権限ではなく、正しい related オブジェクト内で解決されなければならない。宣言された type と実際のルートの Content-Type が異なる場合、RFC 2387 はユーザーエージェントの動作を未定義としている。
添付の表示指定より related の関係が優先される場合もある。ファイル名は保存方法のヒントにはなるが、その画像が独立した添付なのか、文書を成立させる部品なのかは複合アプリケーションの規則で決まる。内容だけを抽出して関係を捨てれば、元の文書を完全には保存していない。
cid: はネットワーク命令ではなかった
RFC 2392 は Message-ID と Content-ID の URL 表現を定義した。CID URL は cid: に URL エンコードされた addr-spec を続ける。接頭辞を外し、パーセントエンコードを戻し、山括弧を補えば、復元した値を MIME 木の Content-ID ヘッダーと直接照合できる。
URL の形を取っても、ソケットを開く指示にはならない。この scheme が示すのは MIME ヘッダーを用いる解決手順である。メールストアはメッセージを索引しても、すべての内部パートを索引するとは限らない。そのため RFC 2392 は mid:message-id/content-id という長形式を設け、準拠実装に対応を求めた。前半でメッセージ、後半で内部エンティティを指定する。短い cid: は通常、同じメッセージの別パートを指す。ストアが一意性を利用して範囲を広げることはできるが、それは実装の機能であって世界共通の取得サービスではない。
同じメッセージ内に同一 Content-ID のパートが存在し得る限定的な場合も、RFC 2392 は認めている。どの候補をリンクが意味するかは親エンティティの選択規則が決める。世界的な一意性を目指したラベルでさえ、ローカルな構文木なしには解決できない。
場所を示す値は別の主張だった
1999 年の RFC 2557 は RFC 2110 を置き換え、Content-ID、Content-Location、Message-ID を別種のラベルとして整理した。Content-Location は絶対 URI にも相対 URI にもなれるが、その URI を受信者が実際に取得できる必要はない。閉じた領域だけで有効なことも、封入文書の参照解決用に仮想的に与えられることもある。
Content-Location は、包まれたパートと文書内の参照を対応させ、表現が概念上どこから来たかを示せる。しかし外部取得に成功したという証明ではない。
さらに RFC 2557 は、MHTML 集合体の URI と、そのルート文書の URI を区別する。集合体を取得すればパッケージが返る。ルート URI を直接取得すれば、ルートだけが届き、依存物は別々に取得されるかもしれない。時刻が違えば両者のスナップショットも異なる。パッケージ、ルート、構成要素の位置、実際に受け取ったバイト列は同じ事実ではない。
Content-ID が長く役立ったのは、多くを約束しなかったからだ。内部関係を順序や外部位置から切り離す一方、受信側にはメッセージ文脈の確定、コンテナ解析、代替表現の選択、デコード、セキュリティ判断、表示という仕事が残った。
会員向け解説
プロフィールの詳細
適切な会員レベルでログインすると、解説全文と出典メモをご覧いただけます。
Strategic Circle 限定
Strategic Circle
すべての読者に公開されています。参加してログインすると プロフィール解説 を閲覧できます。
Strategic Circle に参加Leadership Alliance 会員限定
Leadership Alliance
対象となる IP 資産の所有者・管理者向けです。ログインすると Leadership Alliance の解説を閲覧できます。
Leadership Alliance に参加
