thunderbirdのメールはMIME::Parser->parse_data()できるのにBecky! ver.2.52はできないので調べてみたら、MIME::Parser がcontent headerのparseに失敗しているようでした。
thunderbirdとBecky! ver.2.52のcontent header
まず、thunderbirdとBecky! ver.2.52のそれぞれのcontent headerは次の通りです。
thunderbirdのcontent header
Content-Type: application/vnd.ms-excel; name="=?ISO-2022-JP?B?My0xLTEzXxskQkdeQk4+cEpzRn5OT01RJVUlKSE8JV4lQyVIGyhCKHRvcA==?= =?ISO-2022-JP?B?aWNzKS54bHM=?=" Content-Transfer-Encoding: base64 Content-Disposition: attachment; filename*0*=ISO-2022-JP''%33%2D%31%2D%31%33%5F%1B%24%42%47%5E%42%4E%3E%70; filename*1*=%4A%73%46%7E%4E%4F%4D%51%25%55%25%29%21%3C%25%5E%25%43%25%48; filename*2*=%1B%28%42%28%74%6F%70%69%63%73%29%2E%78%6C%73
Becky! ver.2.52のcontent header
Content-Type: application/octet-stream; name="=?ISO-2022-JP?B?GyRCR15CTj5wSnNGfk5PTVElVSUpITwlXhsoQg==?= =?ISO-2022-JP?B?GyRCJUMlSBsoQigbJEIlIiVRITwlSCU7JV8bKEI=?= =?ISO-2022-JP?B?GyRCJUohPBsoQikueGxz?=" Content-Disposition: attachment; filename="=?ISO-2022-JP?B?GyRCR15CTj5wSnNGfk5PTVElVSUpITwlXhsoQg==?= =?ISO-2022-JP?B?GyRCJUMlSBsoQigbJEIlIiVRITwlSCU7JV8bKEI=?= =?ISO-2022-JP?B?GyRCJUohPBsoQikueGxz?=" Content-Transfer-Encoding: base64
エラー内容
先程のcontent headerを含んだメールを次のようなscriptでparse_data()しようとすると、MIME::Parser::Filer が勝手に無視して、例外もcatch出来ませんでした。
sub parse_mail { my ($self,$msg_src) = @_; my $parser = MIME::Parser->new(); #MIME::Parserの準備 $parser->output_dir($CONF->{pop}->{tmp_dir}); #mailの一次保存場所 my $entity = $parser->parse_data($msg_src); unless ($entity){ my $msg = join("\n", "mailの読込みに失敗しました.", "$msg_src"); $self->error($msg); die $msg; } }
error msg
ignoring text in character set `ISO-2022-JP' at /usr/local/lib/perl5/site_perl/5.10.0/MIME/Parser/Filer.pm line 659
とりあえずの対応策
そこで、MIME::WordDecoder でwarningを出すものの文字列はそのまま返すようにしました。
sub unknown_mime_encoding { my ($self,@tmp) = @_; $self->warn("unknown_mime_encoding: $tmp[0]"); return $tmp[0]; } #multi partなmailをparseし、添付されているxlsのpathを返します sub parse_mail { my ($self,$msg_src) = @_; my $mime_wd = MIME::WordDecoder->new(['ISO-2022-JP' =>"KEEP", '*'=>sub{$self->unknown_mime_encoding(@_)}]); MIME::WordDecoder->default($mime_wd); my $parser = MIME::Parser->new(); #MIME::Parserの準備 $parser->output_dir($CONF->{pop}->{tmp_dir}); #mailの一次保存場所 my $entity = $parser->parse_data($msg_src); unless ($entity){ my $msg = join("\n", "mailの読込みに失敗しました.", "$msg_src"); $self->error($msg); die $msg; } }
とりあえず動作しているので、しばらく様子を見ます。