RFC 2231: MIMEパラメータ値拡張
これが存在する理由
MIMEパラメータはContent-TypeやContent-Dispositionなどのヘッダに現れます。最も一般的な用途は、添付ファイルのfilenameパラメータです:
Content-Disposition: attachment; filename="report.pdf"
これはASCIIファイル名では問題なく機能します。しかし報告書.pdf(「報告書」という意味の日本語)という名前のファイルや、200文字のファイル名の場合はどうでしょうか?元のMIME仕様(RFC 2045)にはこれに対するメカニズムがありませんでした。RFC 2231は3つの問題を解決します:
- 文字セット:パラメータ値に非ASCII文字をエンコードする
- 言語タグ:パラメータ値に言語識別子を注釈として付ける
- 継続:長いパラメータ値を複数行に分割する
仕組み
文字セットと言語のエンコーディング
非ASCII文字を含めるには、パラメータ名にアスタリスクを付けてcharset'language'encoded-value形式を使用します:
Content-Disposition: attachment; filename*=UTF-8''%E5%A0%B1%E5%91%8A%E6%9B%B8.pdf ^^^^^^^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^ charset lang パーセントエンコード値 (空 = 言語タグなし)
値%E5%A0%B1%E5%91%8A%E6%9B%B8は「報告書」のUTF-8バイトをパーセントエンコードしたものです。単引用符の間の言語タグはオプション(多くの場合、空のままにされます)。
長い値の継続
パラメータ値が1つのヘッダ行に収まらない場合は、番号付き継続を使用して分割します:
Content-Type: application/pdf; filename*0="very-long-document-name-that-exceeds-the"; filename*1="-reasonable-line-length-limit-for-headers.pdf"
パーツは数値順に再度統合されます:*0、*1、*2など。
組み合わせ:文字セットを使用した継続
長い非ASCII値の場合、両方の機能を組み合わせます。最初のセグメントのみが文字セットと言語を含みます。その後のセグメントはエンコード値のみです:
Content-Disposition: attachment; filename*0*=UTF-8''%E3%81%93%E3%82%8C%E3%81%AF%E9%95%B7; filename*1*=%E3%81%84%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB; filename*2*=%E5%90%8D.pdf ^^^^ 番号 + アスタリスク = エンコード継続
重要な技術詳細
パラメータ名構文
| 形式 | 意味 | 例 |
|---|---|---|
filename |
プレーンASCII値 | filename="report.pdf" |
filename* |
エンコード値(charset'lang'value) | filename*=UTF-8''%E5%A0%B1.pdf |
filename*0 |
継続パーツ0、プレーンASCII | filename*0="very-long-" |
filename*0* |
継続パーツ0、エンコード | filename*0*=UTF-8''%E5%A0%B1 |
エンコーディング規則
- 非ASCIIバイトにはパーセントエンコーディング(URLエンコーディングのような)を使用する
- MIMEトークンで安全なASCII文字(文字、数字、ハイフン、ピリオド)はエンコードする必要がない
- 文字セットはほぼ常に現代的な
UTF-8である - 言語タグはBCP 47に従います(例:
en、ja、zh-CN)が、多くの場合省略されます
RFC 2047との相互作用
RFC 2047はヘッダ内の非ASCIーテキストのためにエンコード語(=?UTF-8?B?...?=)を提供します。しかしながら、RFC 2047はエンコード語が引用符で囲まれた文字列またはパラメータ値の内部に出現してはいけないと明示的に述べています。RFC 2231はMIMEパラメータの正しいメカニズムです。このルールにもかかわらず、多くのメールクライアントはfilenameパラメータにRFC 2047を使用しているため、堅牢なパーサーは両方を処理する必要があります。
一般的な間違い
-
パラメータ値でRFC 2047エンコーディングを使用する。
filename="=?UTF-8?B?...?="と書くのは技術的には無効ですが、広く使用されています。最大の互換性のために、両方を送信します:ASCII フォールバック付きのプレーンfilenameとRFC 2231エンコード値付きのfilename*。 -
エンコード継続の二重アスタリスクを忘れる。
filename*1はプレーンテキスト継続です。filename*1*はエンコード継続です。末尾のアスタリスクを忘れると、値はリテラルテキストとして扱われ、デコードされません。 - 継続順序が間違っている。パーツは0から始まる順序で番号付けされる必要があります。番号付けに間隔がある場合(0、1、3)または1から始まる場合、厳密な実装でパース失敗が発生します。
- UTF-8以外の文字セットを使用する。RFC 2231はあらゆるIANA文字セットを許可していますが、現代の実践ではUTF-8のみです。ISO-8859-1またはWindows-1252を使用すると、国際的な受信者との相互運用性が低下します。
-
ASCIIフォールバックを提供していない。一部の古いメールクライアントはRFC 2231をサポートしていません。常にASCII近似を使用したプレーン
filenameパラメータとfilename*パラメータを含めます。
配信可能性への影響
- 添付ファイルファイル名表示。不正なエンコーディングにより、受信者のメールクライアントで添付ファイルファイル名が文字化けまたはクエスチョンマークとして表示されます。これは混乱させ、プロフェッショナルではありませんが、メッセージの配信に直接影響しません。
- スパムフィルターのトリガー。奇形のMIMEパラメータはスパムフィルターをトリガーすることができます。一部のフィルターはエンコーディングの異常があるメッセージを疑わしいものとしてフラグを立てます。これは、マルウェアキャンペーンがときに奇形ヘッダを使用してパーサーの脆弱性を悪用するためです。
-
クライアント間の相互運用性。RFC 2231サポートの実世界の状態は異なります。Gmail、Apple Mail、Thunderbirdはそれをよく処理します。一部の古いエンタープライズクライアントはそうしません。最も安全なアプローチは、常に両方の
filename(ASCII)とfilename*(RFC 2231)パラメータを含めることです。 -
Content-Typeパラメータもあります。
filenameが最も見やすい用途ですが、RFC 2231はContent-Typeパラメータ(nameやcharsetなど)および他のあらゆるMIMEヘッダパラメータにも適用されます。