久々に仕事ネタ。CentOS6系+PHP5.6&ZendFramework2。

 Zendframework2ベースの開発で、でもZend::Mailだと日本語のあれこれに難があるっぽいので旧来通りのmb_send_mailを用いた添付可能メール配信クラスを作成。
 とりあえず正常に配信されるようになって一安心、でも色々試してみるかと確認してたところ
 「Thunderbirdで保存したemlファイルをOutlookで開くと、添付ファイルの中身がNullで埋まってる」
 とゆー現象に遭遇。試しに直接Outlookで取得するアカウントを作って送付してみたところ、そのシステムから送付した全ての添付ファイルが同じようになっている。ファイル名は正しい。ファイルサイズも正しい。でも中身が空っぽ。いやNullで埋まってるので空っぽではないのだが。
 Thunderbirdでは問題なし。Beckyでも問題なし。Gmailでも問題なし。Web版Outlookでも問題なし。・・・にも関わらずアプリ版Outlookではそうなる。

 色々調査&実験。emlファイルをテキストエディタで開き、添付ファイルのContent-Typeを別のものに書き換えたらうまく読めるようになった、という事があったのでメール送信側を変えてみたがダメなまま。じゃあなんで書き換えたらうまく行ったんだ?と疑問に思い、試しに「開く→何もせず保存」したところ読めるようになった(苦笑)。ここで何かしらの自動変換が影響してるものと推察。まあきっと改行コードだろう。

 元ファイル、及び元ファイルを開いて保存しただけのファイルをテキストエディタで比較してみると「違いはない」と言われる。改行コードも変わってないように見える。
 次に同じ比較をバイナリエディタでやってみる。すると「添付ファイルをbase64化した部分」の各改行コードが「\r\r\n」となっていることが判明。なるほどコレか。メールのCRLF問題っちゃ久しぶりだ。

 改めて添付ファイル部のコードを見る。やり方はネットでよく見かける手法で、ファイル添付部は以下のようにしていた。

  (この前で別のbody部を設定しつつ)
  $body .= chunk_split(base64_encode($attach))."\n";

 ここで改めて「chunk_split」について関数定義を見てみると

  string chunk_split ( string $body [, int $chunklen = 76 [, string $end = "\r\n" ]] )

 であり、非必須の第3パラメータが分割された各行の改行コードとなる。なるほど、他のところは全て「\n」、すなわちLFだけで指定してるのに対し、添付部はここで\rが余計に入っちゃったのか。

 第2パラメータは標準の76として、第3パラメータを「\n」のみ指定に変更。結果、無事Outlookでも添付ファイルが取れるようになりました、とさ。


 しかし世の中見てるとchunk_splitをそのまま使う記述例ばっかで、かつOutlookで添付ファイルに問題が発生したなんて話はほとんど見かけない。他の人はこーいったトラブルに遭遇してないのかなぁ。
 この手法そのものが今となってはあまり使われてないということなのか、それとも実行環境がWindowsベースで改行コードの問題が発生しにくいということなのか。あ、今回MTAはPostfix使ってるんでその辺が影響してるのかもしれない。今時MTAを自分のシステム上に持つなって話なのか?

 つか大抵のメールクライアントで対応できる事柄をいつまでも放置してんじゃないよ>MS、といういつものテンプレがオチなんだろう。
 





 

2015-12-25 [技術・作業]