Perl: 2009年5月アーカイブ

メール解析のプログラムを作成してて気づいたのだが、SoftBank の携帯(テストで使ってたのは、俺の 810T だが)のメールヘッダって、Content-Type ヘッダの後ろに空白を入れないんだな。

例えば、PC のメールソフト(Outlook とか EDMax とか AL-Mail とか諸々)だと、Content-Type ヘッダは、

Content-Type: multipart/mixed;

こんな感じで、'Content-Type:' の後ろに半角スペースがひとつ入ってる。
でも、810T のメールは、

Content-Type:multipart/mixed;

なんだよ。
他にも、コンテンツの属性を示すヘッダ関係は軒並み、

Content-Type:text/plain;charset=ISO-2022-JP
Content-Disposition:attachment;filename="HOGEHOGE.JPG"
Content-Transfer-Encoding:base64

みたいな感じで全て半角スペースは含まれてない。

他のヘッダ(To とか From とか Subject とか)は、全て半角スペースが含まれているのに・・・である。

変な実装。(^^;
いや、RFC にどう書かれているのかわからないが、半角スペースが無いなら無いで全然かまわんのやけど、他のヘッダと、Content 関係だけがフォーマットに違いがあるのが何か気持ち悪いよなあ。

PC から出したメールに添付した画像は抜き出せるのに、携帯メールに添付した画像が抜けないので、何でかいな?と調べたらそういうことで、

if ($data =~ /Content-Type\:\s+(\S+[^\;]*?)/i) {

という正規表現を使った条件をすり抜けてた。

if ($data =~ /Content-Type\:\s*(\S+[^\;]*?)/i) {

とすればOK。

Foma とか AU の端末もこんなんかなあ?

Perl で、POP3 サーバからメールを受信する処理を書かないといけなくなった。

今までだと、直接 Socket の確立から、実際の POP3 コマンドの発行部分まで自分で書いてたんだけど(その方が無駄な処理を省いてシンプルなソースが書けるんでねぇ)、しかし、今回は納期も予算も少ない案件なので、Mail::POP3Client モジュールを使ってみることにした。
(例しに CPAN モジュールでインストールしてみたら、珍しくスコっと入ったし(笑))

use Mail::POP3Client;

して、受信処理の書き方は

 my $pop = new Mail::POP3Client(
  USER => $Muser,
  HOST => $Mhost,
  PASSWORD => $Mpass,
  DEBUG => 0
 );

こんな感じで $pop を Mail::POP3Client クラスのオブジェクトとして宣言し、後は、

 受信メールの件数取得
 $pop->Count

 ヘッダ部の受信
 $pop->Head(メッセージ番号)

 ボディ部の受信
 $pop->Body(メッセージ番号)

 メッセージの削除
 $pop->Delete(メッセージ番号)

 POP3接続の切断
 $pop->Close

などのメソッドを適時使ってソースを書けばいいだけ。
(もちろん、Subject を MIME decode したり、添付ファイルを切り出したりといった処理は自分で書く必要あり)

なのに、実行すると、

Use of uninitialized value in pattern match (m//) at /usr/lib/perl5/site_perl/5.8.5/Mail/POP3Client.pm line 1078, <GEN0> line 2.

なエラーが出てしまい、処理が中断されてしまう。なぜ???

DEBUG 表示を ON にして(DEBUG => 1)実行してみると、

# ./get_pop3_mail.pl
POP3 <- +OK <20028.1242047733@serv.exsample.com>
 at ./get_pop3_mail.pl line 97
POP3 -> APOP mail_test@exsample.com feb4f975bc9cd0c24151ac7ceea4dc1f
 at ./get_pop3_mail.pl line 97
POP3 <- -ERR authorization failed
 at ./get_pop3_mail.pl line 97
POP3 -> NOOP
 at ./get_pop3_mail.pl line 97
Use of uninitialized value in pattern match (m//) at /usr/lib/perl5/site_perl/5.8.5/Mail/POP3Client.pm line 1078, <GEN0> line 2.

となる。
ああ、APOP 未対応の POP3 サーバに対して、APOP 認証しようとしてるのね。で、エラーになってるんだ。
そこで Connection closed by foreign host. になっちゃうので、その後 NOOP コマンドを投げても何のレスポンスも返ってこないから(空値に対してパターンマッチを行おうとして)、そういうエラーを吐いちゃうんだ・・・

しかし、それで Perl のエラーが発生するというのはどういう実装よ。(^^;
なんとかハンドリング出来んのかいな。Socket 接続が切れてたらコマンド送らないとか。むーん・・・

どうも微妙に気持ち悪いんだが、今回は APOP 認証を止めればエラーは出ないので、それで良しとする。

普通にプレーンパスワードで認証をするように、

 my $pop = new Mail::POP3Client(
  AUTH_MODE => 'PASS',
  USER => $Muser,
  HOST => $Mhost,
  PASSWORD => $Mpass,
  DEBUG => 1
 );

という具合に、AUTH_MODE => 'PASS' を追加してやる。

これで、

# ./get_pop3_mail.pl
POP3 <- +OK <23657.1242048016@serv.exsample.com>
 at ./get_pop3_mail.pl line 97
POP3 -> USER mail_test@exsample.com
 at ./get_pop3_mail.pl line 97
POP3 <- +OK
 at ./get_pop3_mail.pl line 97
POP3 -> PASS hogehoge
 at ./get_pop3_mail.pl line 97
POP3 <- +OK
 at ./get_pop3_mail.pl line 97
POP3 -> STAT
 at ./get_pop3_mail.pl line 97
POP3 <- +OK 1 998
 at ./get_pop3_mail.pl line 97
POP3 -> TOP 1 0
 at ./get_pop3_mail.pl line 112
POP3 <- +OK
 at ./get_pop3_mail.pl line 112
POP3 <- Return-Path: <exsample@gmail.com>
<以下略>

という具合に、正常に POP3 によるメール受信が成功する。バッチリ。

おお、DEBUG 出力を無効(DEBUG => 0)にしとかなきゃ。

このアーカイブについて

このページには、2009年5月以降に書かれたブログ記事のうちPerlカテゴリに属しているものが含まれています。

前のアーカイブはPerl: 2009年4月です。

次のアーカイブはPerl: 2009年6月です。

最近のコンテンツはインデックスページで見られます。過去に書かれたものはアーカイブのページで見られます。

ウェブページ

  • photo
  • photo2008
  • podcasting
電気ウナギ的○○ mobile ver.

携帯版「電気ウナギ的○○」はこちら