id:kizashi1122 です。 メールの話です。
メールってとてもややこしいんですよね。 マルチパートと言って、パート部分を複数持つこともできますし、マルチパートを入れ子にすることもできます。
- メール本体
- 本文(テキスト)
- 本文(HTML)
- 添付ファイル1
みたいなのが典型的なマルチパートメールです。
添付ファイルであれば、Content-Type が image/png
だったり application/pdf
だったりするわけです。
たまに Content-Type が message/rfc822
の場合もあります。
よくあるのがメールの不達で返ってきたメール(バウンスメール)です。 @ より前のユーザが存在しない場合は、Unknown User で返ってくる例のあのメールです。
メールサーバーによりますがバウンスメールにはそもそも届けたかったメールが添付されていることがあります。 つまりメールにメールが添付されてるということになります。
そのときに使う Content-Typeが message/rfc822
なのです。
こんなイメージです。
Date: Mon, 19 Apr 2021 08:38:03 +0900 (JST) From: MAILER-DAEMON@example.com (Mail Delivery System) Subject: Undelivered Mail Returned to Sender To: system@example.com MIME-Version: 1.0 Content-Type: multipart/report; report-type=delivery-status; boundary="aaaaaa" Message-Id: <20210418233803@example.com> This is a MIME-encapsulated message. --aaaaaa Content-Description: Notification Content-Type: text/plain; charset=us-ascii Unknown User ですよ的なメッセージ --aaaaaa Content-Description: Undelivered Message Content-Type: message/rfc822 Content-Transfer-Encoding: 7bit Content-Type: text/plain; charset=iso-2022-jp Mime-Version: 1.0 To: example@example.jp From: example@example.co.jp Subject: foo 元メールの本分 --aaaaaa--
みたいな感じです。
タイトルで「謎」と書きましたが、何が謎なのか。
最近こういうバウンスメールをみるのです。
Content-Type: message/rfc822; charset=utf-8 Content-Transfer-Encoding: base64 WyRyO3Ikajh8JC84Zk5pPz0kNz5lJDIkXiQ5ISMbKEINCg0KGyRCQWFCLiRHJE8kNCQ2JCQkXiQ5 JCwhIhsoQg0KGyRCQGhITCEiJSshPCVJMnEwd01NJCskaSROJDRNeE1RSF1HJyROPz1AQSRLSDwk : :
ふーん、 元のメッセージが base64 エンコードされてるのね、というメールなのですが、うちのサービスではこのバウンスメールの扱いに失敗します。
なんでだろう?
と思って、RFCのドキュメントを読むことにしました。
RFC 2046: Multipurpose Internet Mail Extensions (MIME) Part Two: Media Types
の Page 29 に
No encoding other than "7bit", "8bit", or "binary" is permitted for the body of a "message/rfc822" entity
とあります。つまり RFC 違反のメールであり、うちが使っているライブラリでは RFC に則って作られていたため、 Content-Transfer-Encoding: base64
が指定してあってもそれを無視して本文をそのまま扱っていたということになります。
フォーマットの違うCSVをインポートしようとしたらエラーで弾けばいいでしょう。 ただメールの世界ではルール違反(RFC違反)はもはや当たり前です。どこまでをサポートすればよいのかは悩みどころです。
うちでは今回は Content-Transfer-Encoding: base64
が指定してあれば、明示的に base64 でデコードしてあげることにしました。
以上です。
インゲージではエンジニアを募集しています!
ではまた。