非推奨のやり方をポストするのはどうかと思うけど、せっかく苦い経験をしたので、ブログ記事にでもしなきゃ気がすまないよ!ということで。
そもそも、もともとは下記のようなコードを書いていたので、それを手直ししてSMTP-AUTHにも対応できるようにしようとするほうが自然で労力がかからないと思ってた。
もともとのコード
use Encode 'encode';
use Email::Sender::Simple 'sendmail';
use Email::MIME;
use Email::Sender::Transport::SMTP;
my ($enc_h, $enc) = ('MIME-Header-ISO_2022_JP', 'ISO-2022-JP');
my $email = Email::MIME->create(
header => [
From => encode( $enc_h => '"from me" <from@xxx.jp>'),
To => encode( $enc_h => '"to you" <to@yyy.jp>'),
Subject => encode( $enc_h => 'subject'),
],
attributes => {
content_type => 'text/plain',
charset => $enc,
encoding => '7bit',
},
body => encode( $enc => 'New ip address here: '.$ip),
);
my $transport = Email::Sender::Transport::SMTP->new(
host => 'mymy.jp',
port => 587,
);
sendmail($email, { transport => $transport });
このコードはこの記事を参考にしました。
Net::SMTP::TLS
しかし、いろいろ試行錯誤したけどだめで、最終的に下記のようなコードになった。(もともとのコードの跡形なし)
use Net::SMTP::TLS;
my $mailer = new Net::SMTP::TLS(
'your.mail.host',
Hello => 'some.host.name',
Port => 25, #redundant
User => 'emailguy',
Password=> 's3cr3t');
$mailer->mail('emailguy@your.mail.host');
$mailer->to('someonecool@somewhere.else');
$mailer->data;
$mailer->datasend("Sent thru TLS!");
$mailer->dataend;
$mailer->quit;
これは、Net::SMTP::TLS - search.cpan.org のSYNOPSYSそのものなんだけど、Email::Senderのようなラッパークラスではだめで、もっと低レベルのクラスを使ってやっと書けた。
Net::SMTP::TLSを書き換え
しかし、実はこのコードを実行するには、Net::SMTP::TLSを直接手直しする必要があった。Net::SMTP::TLSが使う IO::Socket::SSL のTLSのバージョンが合わないようで、Net::SMTP::TLSを下記のように書き換える
#SSL_version => "SSLv3 TLSv1")){ #182行目
SSL_version => "TLSv1")){
このような小細工をして、ようやく動いた。
このバグはすでに報告済み
SSLのバージョンがうまく噛み合わない件は、CPAN上ですでに報告されている。
しかし、それが修正される気配はない。そもそもNet::SMTP::TLSは更新日が2006年1月16日で、すでに長いこと放置されている。なので、こちらを使うことは推奨できない。
Net::SSLeay のインストールでハマる確率高い
ちなみに、そもそもNet::SMTP::TLSをインストールするところでハマったという経緯もある。Net::SMTP::TLSにはNet::SSLeayが必要なのだが、これのCPANインストールでこけまくった。
openssl が足りないだの、ghostscriptが入らないだの言われて、MacPortsを試してみたり、tarボールを直接makeしてみたりいろいろやって、結局わけがわからなくなって、再度やってみたら、何故かNet::SSLeayがインストールできていたという、再現不可能な感じで、ここまで辿り着いた。
Email::Sender::Transport::SMTP::TLS がラッパー
Net::SMTP::TLSはSMTP-AUTHでメールを送る低レベルなAPIだけど、これに対するラッパがじつはあって、それが Email::Sender::Transport::SMTP::TLS です。
こちらは、すでに長期間放置されているNet::SMTP::TLSの当該バグを、Net::SMTP::TLS::ButMaintained という別のモジュールで修正して、そちらを使用して動作するものです。
で、やっぱりどちらも使わないほうがいいです
ここまで、長々と書いてきたけど、Net::SMTP::TLSにしろ、Email::Sender::Transport::SMTP::TLSにしろ、もう使わないほうがいいです。
代わりになるモジュールが
です。(つづく)