Perlでメール受信
Perlでメール受信するスクリプトで、SubjectがUTF-8のメールで文字化け発生する不具合があった。
前にもこれで修正した記憶があるんだが・・・
まあ、そういうわけでちょいいじったんだが、
どうも最近はMIME::ParserじゃなくてEmail::MIMEでパースするのが人気みたいだね。
まず、元々MIME::Parserだったわけだが、
MIME::HeadでSubjectを取り出す際に、
decode->get('Subject')
とすると、Base64がデコードされて文字コードは変換されない。
MIME::Tools系にはヘッダの文字コードを取り出す機能は無さそう。
Encode::MIME::Headerの機能を使うと、
$subject=Encode::decode('MIME-Header',$subject);
みたいな感じにすると、手元のPerl 5.20ではutf8フラグがつくみたいだったんだが、リモートのPerl 5.18ではutf8フラグがつかないぽかった。
コアモジュールみたいなんだが、Perl 5.20で変わったのか?
で、手元ではUTF-8もISO_2022_JPもdecodeした後にencodeすれば良かったんだが、
リモートだとUTF-8なメールはdecodeした後にencodeしなければ正常に抽出できたんだが、
ISO_2022_JPなメールだとそもそも文字コードの変換が行われないぽかった・・・
Perl 5.20ならこの方法で正常に出来そうではあった。
というわけで、Perl 5.18+MIME::Parser(MIME::Tools系)を使ってパースする場合は、
decodeせずに生ヘッダ取り出して自力デコードするか、decode->get('Subject')した後に決め打ちでUTF-8にデコードする必要がある。
Email::MIMEの方は、
どうもEmail::MIME自体にはヘッダを抽出する機能が無いようで、Email::Simpleのheaderを利用する。
use Email::MIMEすればEmail::Simpleの機能も利用できるんだが、
Simple系のモジュールは勝手にutf8フラグつけるんだよね。これもそうだった・・・
というか、フラグ判別してもutf8フラグ自体はついてないぽかったんだが、UTF-8にencodeしないと「Wide character in print at」なる。
ほんとutf8フラグのせいでPerlが使いにくくなったわ。
外人様は1byteと1文字が同一だと思ってんだよな。
マルチバイト圏の人間は1文字と1byte分けて処理したいから困るわ・・・