まだ重たいCMSをお使いですか?
毎秒1000リクエスト を捌く超高速CMS「adiary

2009/07/01(水)メールの添付ファイル名とMIME文字コードと色々メモ

メールの添付ファイルやMIMEに関するメモ。実装サンプルは adiary を落として lib/Satsuki/Base/Mail.pm でも開いてみてください。

関連記事:2行に渡るメールヘッダの正しい処理

MIMEのパターン

Subject: =?iso-2022-jp?B?YWRpYXJ5IGlQaG9uZRskQiQrJGkkTkVqOUYkTjdvGyhC?=
Subject: =?ISO-2022-JP?B?YWRpYXJ5IGlQaG9uZRskQiQrJGkkTkVqOUYkTjdvGyhC?=
From: =?UTF-8?B?44Gq44G5?= <nabe@xxxx.yy>
Subject: =?utf-8?B?44K/44Kk44OI44Or44Gr5pel5pys6Kqe?=

メールのMIMEは、JISのほかにUTF-8など他の文字コードもありえる。

マルチパート本文のヘッダ

JISの例

Content-Type: text/plain;
	charset=iso-2022-jp;
	format=flowed
Content-Transfer-Encoding: 7bit

UTF-8の例

Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: 8bit

charsetがダブルクオート(")で囲まれていることもあるため注意する。

添付ファイルでのファイル名

iPhoneの例。

Content-Disposition: inline;
	filename=photo.jpg
Content-Type: image/jpeg;
	name="photo.jpg"
Content-Transfer-Encoding: base64

Softbank携帯の例。

Content-Location:20090621.jpg
Content-Type:image/jpeg;name=20090621.jpg
Content-Transfer-Encoding:base64

日本語。

Content-Type: application/octet-stream;
 name="=?ISO-2022-JP?B?GyRCJF4kJCRhGyhCLnR4dA==?="
Content-Disposition: attachment;
 filename="=?ISO-2022-JP?B?GyRCJF4kJCRhGyhCLnR4dA==?="
Content-Transfer-Encoding: base64

RFC2231準拠の記述

最近増えてきたRFC2231表記。MIMEより新しい仕様になります。

新iPhoneの例。

Content-Disposition: inline;
	filename*=iso-2022-jp''%1B%24B%3CL%3F%3F%1B%28B.jpg
Content-Type: image/jpeg;
	name="??.jpg"
Content-Transfer-Encoding: base64

utf8の例。

Content-Disposition: attachment; filename*0*=utf-8''%E3%81%82%E3%81%84%E3%81%86%E3%81;
	filename*1*=%88%E3%81%8A.doc
Content-Type: application/msword; name*0*=utf-8''%E3%81%82%E3%81%84%E3%81%86%E3%81;
	name*1*=%88%E3%81%8A.doc
Content-Transfer-Encoding: Base64
Content-Type: text/plain;
 name="=?UTF-8?B?44GC44GE44GG44GI44GKVVRGOOOBquODleOCoeOCpOODq+WQjS50eHQ=?="
Content-Transfer-Encoding: base64
Content-Disposition: inline;
 filename*0*=UTF-8''%E3%81%82%E3%81%84%E3%81%86%E3%81%88%E3%81%8A%55%54%46;
 filename*1*=%38%E3%81%AA%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E5%90%8D%2E;
 filename*2*=%74%78%74

アスタリック表記はこのように分割可能なため結構厄介です。

format=flowedなテキスト 2011/06/17

この項は iPhone のメール等を正しく処理するときに必要です。

Content-Type に「format=flowed」が指定されている場合、半角スペースに続く改行がある場合、単純に改行を除去する必要があります(flowed処理)。

Content-Type: text/plain;
	format=flowed;
	charset="iso-2022-jp";
	reply-type=original
Content-Transfer-Encoding: 7bit

Content-Type に更に「delsp=yes」も指定されている場合は、改行を除きその手前の空白1つも除去する必要があります。

Content-Type: text/plain;
	format=flowed;
	delsp=yes;
	charset="iso-2022-jp";
	reply-type=original
Content-Transfer-Encoding: 7bit

delspに何も指定がなかったり無効な値が指定されている場合は空白の除去は行いません

しかしRFC3676の4.3に例外規定があり、 行末が"-- "の場合はflowed処理を行ってはいけません。

資料

multipartの入れ子構造

multipartメールは入れ子構造にすることができます。詳細は検索してください。

携帯デコメ等で使用されます。

参考

サンプルファイル

プログラム試験用のサンプルファイルを置いておきます。

20110617_test-mails.zip

こちらのサイトのサンプルも凶悪でお勧め。