My Photo

« LaravelでHello World とか諸々 | Main | PHPからPDOでPostgreSQLに接続する »

May 31, 2015

PHPでメールを送信したら一部のOutlookで受信したメールでヘッダがおかしくなった

PHPから送信しているメールで
「件名が途中で切れて、本文の先頭にメールヘッダらしきものが付く」
という不具合が起きた。
この不具合、毎回必ず起きるわけではなく、また発生した場合もすべてのメール受信者のところで起きているわけではなかった(ほぼ同じ内容のメールを複数の人に送信している)。
現象を報告してきた人はOutlook2013を使っているとのことなので、自分のPCにOutlook2007と2013をインストールして同じ件名・本文のメールを受信した見たが、問題なく受信できた。ThunderbirdやGmailでも問題なし。

調査の結果として
「まあサーバ側の処理もよろしくなかったかもしれないけど、Outlookもちょっとおかしいんじゃね?」
という結論に^^;

まず、サーバ側でまずかったのは、改行コードとしてCRLFとLFが混在していたこと。
Subject以外のヘッダは

$content_type = "Content-Type: text/plain; charset=ISO-2022-JP\n";

のようにしている。改行コードはLF。
しかし、Subjectヘッダは

$subject = mb_encode_mimeheader($subject, 'ISO-2022-JP-MS');

としていた。mb_encode_mimeheader() を第3,4引数が省略可で、その場合、第4引数$linefeed のデフォルト値は "\r\n" 。
つまり、Subjectヘッダだけ改行コードがCRLFになっていたと思われる。
これを

$subject = mb_encode_mimeheader($subject, 'ISO-2022-JP-MS', 'B', "\r\n");

としたところ、問題は発生しなくなった。

もう少し詳しく調査をしてみた。
問題発生した環境でメールをファイルに保存してもらい、それをテキストファイルで開いてみると、Subjectヘッダ付近は以下のようになっていた。

Subject: =?iso-2022-jp?B?*******************************************************=?=
MIME-Version: 1.0
Content-Type: text/plain;
charset="iso-2022-jp"
Content-Transfer-Encoding: 7bit
X-Mailer: Microsoft Outlook 15.0
Thread-Index: AdCXa30bcJOZvjFWQ+GQbisiXjOi/Q==

=?ISO-2022-JP?B?***************************=?=

1行目の値をデコードするとメーラーに件名として表示されいる内容(途中でちょん切られた件名)と一致した。
Thred-Indexというヘッダの下に空行があり、その下の行はメーラーで本文の1行目として表示されているものと一致した。

あー、たぶんこういうことだ。

なぜ問題が発生する場合と発生しない場合があるかというと、問題の発生条件が件名の長さによるからだ。
mb_encode_mimeheader() はエンコードした結果が74文字より長いと改行を入れて分割する。これはメールの仕様上問題はない。
件名が短くて分割されない場合、メールの改行コードはすべてLFで問題が発生しない。
しかし、件名が長くてSubjectヘッダが分割されると、mb_encode_mimeheader() の引数$linefeed をデフォルトのままにしていたせいで、その分割のところだけ改行コードがCRLFになる。そしてそのヘッダをOutlookがうまく処理できなくて今回の問題が発生した。

根本的な原因は自分のコーディングにあったのだが、それでも問題が発生したのはOutlookだけだ。それにOutlookでも必ず発生するわけではない。
テキストファイルで開いたメールのヘッダでThread-IndexというヘッダはOutlookが付加する非標準のヘッダだそうだ。
そしてその下に空行が入って、さらに分割されたSubjectヘッダの後半がある。
Outlookでも現象が起きたり起きなかったりするのは、設定とか環境(Exchangeのメール以外のサービスを何か使っているとか)によってこのThread-Indexというヘッダを使う/使わないが変わって、それで使う場合にのみこの現象が発生するんじゃないかと。
実際、現象が発生しなかった自分のOutlook2013で受信したメールを見ると、Thread-Indexはなかった。

という訳で、原因は「Outlookが非標準のヘッダを使っていて、その処理がなんかおかしい」ということで。
#責任回避。

参考ページ:
【php】mail関数の改行コード注意点 at softelメモ
PHP: mb_encode_mimeheader - Manual
メールヘッダ一覧
メールのヘッダフィールド・マニアックス: 非標準 - 鳥さんの落書き帳

« LaravelでHello World とか諸々 | Main | PHPからPDOでPostgreSQLに接続する »

PHP」カテゴリの記事

Comments

Post a comment

(Not displayed with comment.)

TrackBack

TrackBack URL for this entry:
http://app.cocolog-nifty.com/t/trackback/26461/61673637

Listed below are links to weblogs that reference PHPでメールを送信したら一部のOutlookで受信したメールでヘッダがおかしくなった:

« LaravelでHello World とか諸々 | Main | PHPからPDOでPostgreSQLに接続する »

March 2017
Sun Mon Tue Wed Thu Fri Sat
      1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31  
無料ブログはココログ

日本blog村

  • にほんブログ村 IT技術ブログへ
  • にほんブログ村 アニメブログへ
  • にほんブログ村 サッカーブログ アルビレックス新潟へ

好きな音楽家

メモ

XI-Prof