SOFTELメモ Developer's blog

会社概要 ブログ 調査依頼 採用情報 ...
てるてる動画

multipartなメールの構造は通常どの程度まで複雑な入れ子になるか

問題

text/plainなメールだけでなくて、htmlメールや添付ファイル付きのメールを解析して処理するのですが、

multipartなメールってパートの入れ子はせいぜい何階層ぐらいを想定しておけばいいですか?

mail

答え

関連RFC 2822, 2045, 2046, 2047, 2557

マルチパートなメールは、単純に「テキストパートですよ」「HTMLパートですよ」「添付画像ですよ」とフラットに並んでいるわけではない。

multipart にもよくあるものでも以下のような種類がある。

multipart/alternative(内容の同じテキストメールとHTMLメールのように、形式は違っても内容は同じものを示す)
multipart/mixed(個々のパートはそれぞれ異なるものであることを示す)
multipart/related(関連するものを示す)

以下のような状況は普通に発生するので、メールを処理するとしたら想定しておくこと。

・単純なテキストメールなど

メールのヘッダ
Content-Type: text/plain; charset=~

メールの本文

・単純な添付ファイル付きメール

メールのヘッダ
Content-Type: multipart/mixed; boundary="--------xxxxxxxxxx"

----------xxxxxxxxxx
このパートのヘッダ
Content-Type: text/plain; charset=~~

メールの本文
----------xxxxxxxxxx
このパートのヘッダ
Content-Type: image/jpeg; name="sample.png"

画像データ
----------xxxxxxxxxx--

・HTMLメールで、HTMLメールが見えない環境向けのテキストパートを含む場合

メールのヘッダ
Content-Type: multipart/alternative; boundary="--------xxxxxxxxxx"

----------xxxxxxxxxx
このパートのヘッダ
Content-Type: text/plain; charset=~~

テキストメールの本文
----------xxxxxxxxxx
このパートのヘッダ
Content-Type: text/html; charset=~~

HTMLメールの本文
----------xxxxxxxxxx--

・HTMLメールで、代替テキストパートを含み、添付ファイルも添付した場合

メールのヘッダ
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で絵文字が含まれ手、添付ファイルもある場合

メールのヘッダ
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階層以上あると読めないよなど、いろいろな例があり、扱いはみなさん考えるところのようです。

関連するメモ

コメント(1)

りょう 2020年8月19日 03:06

boundaryに——–を付けないで下さい。
何の意図があって——–を使ってるのか知りませんが、本来の区切り目である–と混じって分かりづらいだけです。