信頼はずっと、挑戦はもっと。

お問い合わせ
TEL:03-3496-3888

BLOG コアテックの社員ブログ (毎週月曜~金曜更新中)

2012

16

10月

受信メールの解析について1

テクログ

こんにちわ。パグ(▼・(エ)・▼)です。 技術ブログ自分回以外での更新ですが、 鬼ぶちょうのOKが出たので、きまぐれに更新します。 最近業務でメールの解析業務があったので、忘れそうなとこを備忘録として残そう!と思いました。 技術で分からない点があるときは、私としても、ネットをウロウロして 近い事象を探したりするものですが、今回はこの例はバグる!!って話をします。 所々間違いがある場合は「間違ってやがる・・・うぷぷ」とか心の中で思うなり、 弊社お問い合わせ(https://core-tech.jp/)にご連絡いただけると嬉しいです。 解析はPEARのMimeDecodeで行いました。 使用したモジュールは ・Mail/mimeDecode.phpです。 今回検証した媒体は ・WEBメールだと  google  msn  yahoo ・PCのメーラー ・ガラケー(au,docomo,softbank) ・スマホ(iphone,アンドロイド)です。 簡単に検証した内容についてですが、 上記の媒体のうちどれかからメールが送られてきて、受信したメールを 解析し、保存するってとこまでです。 まずはメールを解析するところなんですが、メールというのは大きく分けて (大多数の)添付なしメールのシングルパート (大多数の)添付ありメールのマルチパートに分かれています。 サーバーに送られてきたメールデータをメモ帳やvmで開いてみると、興味深いことが分かります。

(上部省略)
From: XXXXXX@XXXX.ne.jp         (送り元)
To:   XXXXXX@XXXX.ne.jp         (送り先)
Subject: =?iso-2022-jp?B?GyRCJCIbKEI=?= =?iso-2022-jp?B?GyRCJCsbKEI=?= 
 =?iso-2022-jp?B?GyRCJDUbKEI=?= =?iso-2022-jp?B?GyRCJD8bKEI=?= 
 =?iso-2022-jp?B?GyRCJEolIhsoQg==?=   
 =?iso-2022-jp?B?GyRCJSsbKEI=?=   =?iso-2022-jp?B?GyRCJTUbKEI=?=
Message-ID: 
MIME-Version: 1.0
Content-Type: text/plain; charset="iso-2022-jp"
Content-Transfer-Encoding: 7bit

メール本文

これはシングルパートのメールになります。 見ればすぐに分かると思いますが、構造がすごく単純になってます。 次はマルチパートのメールについてです。

(上部省略)
From: XXXXXX@XXXX.ne.jp         (送り元)
To:   XXXXXX@XXXX.ne.jp         (送り先)
Subject: =?iso-2022-jp?B?GyRCJCsbKEI=?=
Message-ID: 
Date: Thu, 4 Oct 2012 15:39:15 +0900
Mime-Version: 1.0
Content-Type: multipart/mixed; boundary="-----=_NextPart_39325_15894_57999"


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

メール本文

-------=_NextPart_39325_15894_57999
Content-Type: video/3gpp; name="121003_2001~01.3gp"
Content-Transfer-Encoding: base64
Content-Disposition: attachment; filename="121003_2001~01.3gp"

AAAAIGZ0eXBrZGRpAAAAAGtkZGkzZzJhM2dwNTNncDQAAAAkdXVpZG12bWyojBHUgZcAkCcIdwMA
AAAA///oBcyRy4QAAAA8dXVpZGVuY2mojBHUgZcAkCcIdwMAAAAAS0RESS1TTgBXNjRTAAAAAFNO
(以下省略)

マルチパートメールは添付ファイルもこの文字列に凝縮されています。 添付したファイルはバイナリ型で保存されています。 「Content-Type: video/3gpp; name="121003_2001~01.3gp"」 が添付ファイルです。 添付ファイルが複数添付されている場合はその分

-------=_NextPart_39325_15894_57999
Content-Type: video/3gpp; name="121003_2001~01.3gp"

AAAAIGZ0eXBrZGRpAAAAAGtkZGkzZzJhM2dwNTNncDQAAAAkdXVpZG12bWyojBHUgZcAkCcIdwMA(以下略)

-------=_NextPart_39325_15894_57999
Content-Type: video/3gpp; name="121003_2001~02.3gp"

AAAAIGZ0eXBrZGRpAAAAAGtkZGkzZzJhM2dwNTNncDQAAAAkdXVpZG12bWyojBHUgZcAkCcIdwMA(以下略)

こんな感じで区切られています。 このうちこの部分が

Content-Type: video/3gpp

content-type の「ctype_primary/ctype_secondary」って言います。 添付ファイルの解析方法について検証をかさねた結果、あちこちのサイトでありがちな こんな書き方だとプログラムがバグるということがわかりました。

switch(strtolower($this->structure->ctype_primary)) {
	case "text": // シングルパート(テキストのみ)
		処理
		break;

	case "multipart":  // マルチパート(画像付き)
		処理
		break;

これです!!調べた3サイトのうち2サイトがこんな検証方法を使用していました。 ctype_primary に入ってる値が必ずしもtext 、multipartとは限らないのです。 画像つきでもmultipartじゃなくてtextのほうに入ってるときがあるんですよ。ガラケーの特定機種なんですが、 textしかないからって「これはシングルパートメールなんだね☆」って判定しちゃうのは危ないことです。 次にこんな書き方を良く見ます。

	//添付ファイルの拡張子を取得する
	$type = strtolower($part->ctype_secondary);
	//ファイルネームを作成する。
	$file_name = date("YmdHis") . "." . $type;

ctype_secondaryで拡張子付けちゃう人が多いですけどね・・・\(^o^)/これは大きな間違いです。 必ずしもctype_secondaryが拡張子になるとは限らないからです。WEBメールから送信した場合なんかは octet-streamやx-msvideo、alternativeになったり、iphone から送信した場合3gppなんかが ctype_secondaryに入ってきたりしますので、そのまま出来たものとして嬉々として公開するとバグります。 改修を行ったプログラムがまさにこの状態で( ՞ਊ ՞)コノヤローってなりました。 なら、どうしたら判断できるのか? まず、シングルパートなのかマルチパートなのかって判定方法はあきらめることです。 シングルパートなのか、マルチパートなのかってことよりも、添付ファイルがあるのかないのか? ってことを考えましょう。もちろん、添付ファイルが更にデコレーション系絵文字なのかどうか、 なんてことも判定可能です。 そんでもって、拡張子なんて元のファイル名の「.」以降からとっちゃえばいいですね。 ワザワザ別枠からとる必要がないってことです。 ちなみにこのサイトのコードは非常に秀逸でしたので、参考にして作りましたあ。 http://d.hatena.ne.jp/ya--mada/20080415/1208318475 マルチパートだとここにalternativeなどの意味が書いてあってよかったです。 http://www.atmarkit.co.jp/fnetwork/rensai/netpro04/netpro01.html 今回ネット情報は結構あてにならない!と思いました。内容はあくまで、とっかかりや参考程度に考えて、ちゃーんと検証して、修正してからリリースしましょう。次回もメールの解析を行います☆ 次回ブログアップはいつになることやら~。 ではでは、パグでしたぁ~ヽ(・∀・)ノばいばいぷぅ☆ミ

この記事を書いた人

マスオさん

パグ

所 属:
WEBインテグレーション事業部
出身地:
田舎
仕事内容:
システム開発