要約

  • RFC 934 では、ハイフンで始まる行が内包メッセージの境界になり得る。本文の同じ形を境界と誤認しないよう、転送側が を足し、展開側がそれを取り除く。
  • この対は層ごとには可逆である。だが同じ行は外側の層を一つ通るごとにさらに接頭辞を受け、途中の表現は成長する。
  • MIME は境界の必要を捨てず、部品の中に現れない値を宣言する方式を採った。RFC 2046 は、RFC 934 型の引用ではネストごとに行が伸びるため深い multipart に適さないと明記する。

記号は単独では命令にならない

RFC 822 は、最初の空行でヘッダと本文を分け、構造化されたヘッダの中では引用符、括弧、バックスラッシュを構文上のものとして扱った。ここで重要なのは、文字がどこでも同じ権限を持つという話ではない。読取り手が、どのフィールドを、どの状態で解析しているかによって、文字が区切りにもデータにもなるという話である。

RFC 934 はこの問題を転送メールへ持ち込んだ。forwarding agent が外側の草稿を作り、bursting agent が配達後にそれを分解する。外側の本文には前置き、内包メッセージ、末尾の文章を置ける。初期の encapsulation boundary は、 で始まる行である。

境界が一通の終わりと次の始まりを兼ねられるので、展開の規則は単純になる。だが内側の本文にも偶然 - 注意 のような行はある。作者が単なる箇条書きとして書いたこの行を、外側の展開者が自分の境界として読めば、データが制御に化ける。見た目の一致だけでは、二つを区別できない。

外側が足したものだけを外側が返す

RFC 934 の character stuffing は、衝突を隠さず印を付ける。転送者は内側の行が境界のように始まるとき、元の行の前に を出力する。- 注意 は外側では - - 注意 になる。展開者が行頭の を見たとき、それを本物の境界として扱わず、残りを出力する。本当の境界を見たときだけ、現在のメッセージを閉じる。

この仕組みは、元の行の意味を奪わない。転送者は内側の文の作者にも、宛先にも、全体の意味を決める者にもならない。自分のパーサがその行を誤って制御行にしないための、一時的で検証可能な印を足すだけである。展開者は自分が理解する範囲でその印を戻す。

RFC 822 が異種ネットワークを越える際に、離れるネットワークの特殊な変換をいったん外し、正規形を経て次のネットワークの慣行を付けると説明したことにも、近い節度がある。二つの規則は同一ではない。それでも、局所的な変換には所有者、適用範囲、逆変換の地点が要るという原則は共通する。

戻せることと、途中で保てることは別である

RFC 934 はこの方式が再帰的転送を可能にすると述べる。第一の層で - 注意 は - - 注意 になる。第二の転送者はその行もハイフンで始まると見るので、さらに自分の を加える。外側では - - - 注意 になる。各 bursting agent は自分の層が加えた一組だけを外すべきであり、内側の似た痕跡まで消す権限はない。

すべてを逆順に展開すれば元の文は回復する。しかし輸送中の形は長くなる。ここに、往復試験と運用上の成立の差がある。エンコーダとデコーダが一度一致しても、中継が伸びた行を許すとは限らない。長さ制限、行折り返し、空白や改行の正規化、途中でどの層が何を加えたかを失う記録が、実際の失敗地点になり得る。

中間表現は捨ててよい副産物ではない。リレーはそれを運び、フィルタはそれを検査し、長さ制限はそれに作用する。最終的に復元された本文だけを残しても、その復元を可能にした経路を証明できない。

RFC 934 自身も、公布された文法が既存の動作を一掃するとは考えていなかった。既存の転送者への変更を小さくすることを狙い、古い展開者との互換性のために境界の周囲の空行を考慮するよう勧めつつ、厳密な実装はその空行を生成すべきでないともいう。実装された互換性は、文書の題名ではなく実行中の組合せにある。

MIME は衝突回避を境界の選択へ移した

RFC 2045 は MIME が RFC 934、RFC 822、RFC 1049 などの先行作業に基づくと記す。MIME は内容を記述するフィールド、entity、multipart の本文を導入する。過去のメールすべてを後から書き換える宣言ではなく、採用する送信者と受信者が共有する構文である。

RFC 2046 では、multipart entity が boundary パラメータを宣言する。区切り行は二つのハイフンとその値で作られ、その値は内包部品の中に単独でも行頭接頭辞としても現れてはならない。ネストした multipart は別の値を使う。衝突を避ける負担は、データの各行を書き換えるのでなく、構成者が衝突しない境界を選ぶところに置かれた。

同 RFC は RFC 934 との違いも隠さない。二つのハイフンには大まかな旧方式との互換性がある一方、multipart は RFC 934 の内包ハイフン行のクオーティングには従わない。層ごとに行が成長し、SMTP 実装が時に長行を折り返すからである。RFC 934 は現実の曖昧さを小さな状態機械で処理した。MIME は別の規模のネストと型を扱うため、曖昧さの帳尻を別の場所へ移したのである。

構造の権限には失効点が要る

この比較から得られる問いは単純だ。印が構造として読まれるのはいつか。そして、いつデータへ返されるのか。RFC 934 では が外側だけの保護であり、展開時に外される。MIME では宣言された entity の boundary だけがその範囲で効く。

一時的な印を正典データとして保存したり、誰が入れたかを知らずに印を消したり、封筒を確認する前に本文を命令として読んだりすると、層の境界は壊れる。必要なのは大きな宣言ではない。局所検証できる最小の規則、可視の変換、そして自分が加えたものを戻す経路である。加えて、繰返し合成でどれほど増えるかを、設計時に測らなければならない。

出典と証拠の限界

証拠集合は RFC 822、RFC 934、RFC 2045、RFC 2046 に限る。これらは歴史的な規則と MIME が記した対比を支えるが、現代製品の挙動、普遍的な採用、特定パーサの安全性、深いネストの実測頻度を示すものではない。