multipartなメールの構造は通常どの程度まで複雑な入れ子になるか
問題
text/plainなメールだけでなくて、htmlメールや添付ファイル付きのメールを解析して処理するのですが、
multipartなメールってパートの入れ子はせいぜい何階層ぐらいを想定しておけばいいですか?
答え
関連RFC 2822, 2045, 2046, 2047, 2557
マルチパートなメールは、単純に「テキストパートですよ」「HTMLパートですよ」「添付画像ですよ」とフラットに並んでいるわけではない。
multipart にもよくあるものでも以下のような種類がある。
multipart/alternative(内容の同じテキストメールとHTMLメールのように、形式は違っても内容は同じものを示す) multipart/mixed(個々のパートはそれぞれ異なるものであることを示す) multipart/related(関連するものを示す)
以下のような状況は普通に発生するので、メールを処理するとしたら想定しておくこと。
・単純なテキストメールなど
- text/plain
メールのヘッダ Content-Type: text/plain; charset=~ メールの本文
・単純な添付ファイル付きメール
- multipart/mixed
- text/plain
- image/jpeg
メールのヘッダ Content-Type: multipart/mixed; boundary="--------xxxxxxxxxx" ----------xxxxxxxxxx このパートのヘッダ Content-Type: text/plain; charset=~~ メールの本文 ----------xxxxxxxxxx このパートのヘッダ Content-Type: image/jpeg; name="sample.png" 画像データ ----------xxxxxxxxxx--
・HTMLメールで、HTMLメールが見えない環境向けのテキストパートを含む場合
- multipart/alternative
- text/plain
- text/html
メールのヘッダ Content-Type: multipart/alternative; boundary="--------xxxxxxxxxx" ----------xxxxxxxxxx このパートのヘッダ Content-Type: text/plain; charset=~~ テキストメールの本文 ----------xxxxxxxxxx このパートのヘッダ Content-Type: text/html; charset=~~ HTMLメールの本文 ----------xxxxxxxxxx--
・HTMLメールで、代替テキストパートを含み、添付ファイルも添付した場合
- multipart/mixed
- multipart/alternative
- text/plain
- text/html
- image/jpeg
- multipart/alternative
メールのヘッダ Content-Type: multipart/mixed; boundary="--------xxxxxxxxxx" ------------xxxxxxxxxx Content-Type: multipart/alternative; boundary="--------yyyyyyyyyy" ------------yyyyyyyyyy このパートのヘッダ Content-Type: text/plain; charset="UTF-8" テキストメールの本文 ------------yyyyyyyyyy このパートのヘッダ Content-Type: text/html; charset="UTF-8" HTMLメールの本文 ------------yyyyyyyyyy-- ------------xxxxxxxxxx このパートのヘッダ Content-Type: image/jpeg; name="Atom-s.jpg" 画像データ ------------xxxxxxxxxx--
・絵文字を使うなどして本文に関連が深い添付ファイルとしてmultipart/relatedで絵文字が含まれ手、添付ファイルもある場合
- multipart/mixed
- multipart/related
- multipart/alternative
- text/plain
- text/html
- image/gif
- multipart/alternative
- application/pdf
- multipart/related
メールのヘッダ Content-Type: multipart/mixed; boundary="--------xxxxxxxxxx" ----------xxxxxxxxxx Content-Type: multipart/related; boundary="--------yyyyyyyyyy" ------------yyyyyyyyyy Content-Type: multipart/alternative; boundary="--------zzzzzzzzzz" ------------zzzzzzzzzz このパートのヘッダ Content-Type: text/plain; charset="UTF-8" テキストメールの本文 ------------zzzzzzzzzz このパートのヘッダ Content-Type: text/html; charset="UTF-8" HTMLメールの本文 ------------zzzzzzzzzz-- ------------yyyyyyyyyy このパートのヘッダ Content-Type: image/gif; name="smile.gif" 絵文字画像データ ------------yyyyyyyyyy-- ----------xxxxxxxxxx このパートのヘッダ Content-Type: application/pdf; name="~~.pdf" 添付ファイルデータ ----------xxxxxxxxxx--
この先マルチパートですよ、関係のあるパートですよ、代替コンテンツですよ、暗号化されてますよ、など、パートの意味やまとまりを示す形でいくらでも入れ子になっていく。
テキストパートが欲しいだけでも、3,4階層入っていかないと取れない場合がありうる。
通常のメールソフト、アプリが作るメールであれば、3,4階層までを想定しておけば、大体内容は取得できるのではないかと思います。
ウイルス対策ソフトのスキャンで100階層までしかチェックしないよとか、あるWebサービスでは2階層以上あると読めないよなど、いろいろな例があり、扱いはみなさん考えるところのようです。
りょう 2020年8月19日 03:06
boundaryに——–を付けないで下さい。
何の意図があって——–を使ってるのか知りませんが、本来の区切り目である–と混じって分かりづらいだけです。