使用perl发送TLS加密邮件(更新发送乱码问题解决办法)

 

废话不多说。

 

目录:

一、TLS邮件发送涉及模块

二、CPAN上的实例

三、针对Email::Send::SMTP::TLS的使用做一个详细说明

四、总结,并含有完整perl脚本(html邮件,带附件)。

五、邮件发送时subject(主题)乱码问题解决——8月11日更新。

 

 

TLS邮件发送涉及模块:

Net::SMTP::TLS

Email::Send::SMTP::TLS

MIME::Entity

(Plus:如果不需要加密,使用net::smtp就可以了,如果需要发送ssl加密的邮件,使用Email::Send::Gmail模块)

 

其中,依赖模块如下:(可以直接在cpan上面查看依赖关系,然后下载还没有安装的模块)

Net::SMTP::TLS
    Net::SSLeay
        Test::More
        MIME::Base64
        ExtUtils::MakeMaker
    IO::Socket::SSL
        Scalar::Util
    Digest::HMAC_MD5
        Digest::MD5
        Digest::SHA
    IO::Socket::INET

 

Email::Send::SMTP::TLS
    Test::More
        Return::Value
            strict
            ExtUtils::MakeMaker
            Exporter
            Carp
    Module::Build
        Email::Address
            Encode::MIME::Header
        Email::Send
            Scalar::Util
                Capture::Tiny
                    IO::File
                    version
                    File::Spec
                    File::Temp
                    lib
            Email::Abstract
                Module::Pluggable
                    if
                Email::Simple
                    Email::Date::Format
                    Time::Local
                MRO::Compat
            MIME::Entity
                Mail::Header
                    Net::SMTP
                    Date::Format
                MIME::Base64
                File::Path
                Test::Deep
                    Test::Tester
                    Test::NoWarnings
        Net::SMTP::TLS::ButMaintained
            Net::SSLeay
                Digest::HMAC_MD5
                    Digest::MD5
                    Digest::SHA
            IO::Socket::SSL

模块在cpan上下载,使用perl Makefile.PL / make install安装模块,这里不再赘述。

名义上,Email::Send::SMTP::TLS模块是供Gmail使用的,但实际测试,所有使用TLS加密的smtp服务器都是可以用的。

 

CPAN上的实例如下:

Net::SMTP::TLS使用示例:

#!/usr/bin/perl -w
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;

 

Email::Send::SMTP::TLS使用示例:

#!/usr/bin/perl -w
use Email::Send;

my $mailer = Email::Send->new( {
    mailer => 'SMTP::TLS',
    mailer_args => [
        Host => 'smtp.gmail.com',
        Port => 587,
        User => 'username@gmail.com',
        Password => 'password',
        Hello => 'fayland.org',
    ]
} );

use Email::Simple::Creator; # or other Email::
my $email = Email::Simple->create(
    header => [
        From    => 'username@gmail.com',
        To      => 'to@mail.com',
        Subject => 'Subject title',
    ],
    body => 'Content.',
);

eval { $mailer->send($email) };
die "Error sending email: $@" if <a target=_blank href="mailto:$@;">$@;
</a>

 

测试结果,发现Net::SMTP::TLS模块是无法使用的,可能该模块只能支持默认端口为25的情况,一直提示:

invalid SSL_version specified at /usr/lib/perl5/site_perl/5.10.0/IO/Socket/SSL.pm line 467

按照CPAN的帮助提供任何版本的SSL都无法通过smtp服务。


而令人欣慰的是,虽然Email::Send::SMTP::TLS要求安装N多模块,但是是可以发送邮件的,不会报ssl版本问题。

 

下面针对Email::Send::SMTP::TLS(下面如果没有另外说明,默认TLS模块指代这个模块)的使用做一个详细说明。

一、基础

        这个模块实际上是“继承”(姑且这么叫)Email::Send模块的,只是加入了TLS支持,所以所有方法都是和Email::Send模块相通的。

二、变化

        TLS模块和Email::Send模块不同的地方,就仅仅在于构造邮件句柄的时候使用了SMTP::TLS作为“mailer”参数传入,当然,针对匿名的smtp服务,这里还需要输入用户名、密码等信息。

三、使用

        使用TLS模块,首先要构造一个sender句柄(姑且这么叫吧,就是Email::Send->new出来的东东)。然后用 MIME::Entity、MIME::Lite或者 Email::Simple构造一个消息句柄,将这个句柄作为Email::Send->send方法的参数传入,就可以发送邮件了。


        1. sender句柄构造方法:

方式一:

my $sender = Email::Send->new( {
    mailer => 'SMTP::TLS',
    mailer_args => [
        Host => 'smtp.gmail.com',
        Port => 587,
        User => 'username@gmail.com',
        Password => 'password',
        Hello => 'fayland.org',
    ]
} );



方式二:

my $sender = Email::Send->new( {mailer => 'SMTP::TLS'});
$sender -> mailer_args (Host => 'smtp.gmail.com',
        Port => 587,
        User => 'username@gmail.com',
        Password => 'password',
        Hello => 'username');

都是一样的,另外,sender句柄的new方法还有一个message_modifier参数,不知道有啥用,看着貌似会pass很多东西,有钻研精神的同志研究出来后告诉一下我。

 

        2. 邮件消息句柄构造方法:

使用Email::Simple:(不能带附件,不能带html格式)

my $email = Email::Simple->create(
    header => [
        From    => 'sam-from<samsam@frommail.com>',
        To      => 'sam-to<samsam@tomail.com>',
        Subject => 'Mail Test',
    ],
    body => ${mail_content},   #mail_content就是邮件正文,仅支持纯文本
);


使用MIME::Entity、MIME::Lite(效果是一样的,这两个模块基本通用):

文本方式带附件:

my $email = MIME::Entity->build(From    => 'sam-from<samsam@frommail.com>',
                           To      => 'sam-to<samsam@tomail.com>',
                           Subject => "Mail Test with Attach",
                           Data    => ${mail_content}
                           );
#附件,如果不需要附件就省略下面这一段
$email->attach(Path => "/home/sam/attach_test.txt",
             Type => "AUTO");   #这个Type参数不能省略!


html方式带附件:

my $email = MIME::Entity->build(From    => 'sam-from<samsam@frommail.com>',
                           To      => 'sam-to<samsam@tomail.com>',
                           Subject => "Mail Test with Attach",
                           Type    => "multipart/related"
                           );
#看懂了没,就是以附件的形式添加html格式的正文
$top -> attach(Type => 'Text/html',
               Data => qq{${mail_content}});  #这里的content区别于上面的content,带有html格式
#附件,如果不需要附件就省略下面这一段
$email->attach(Path => "/home/sam/attach_test.txt",
             Type => "AUTO");   #这个Type参数不能省略!


四、总结

        上面的内容基本是抄袭CPAN的,不过CPAN是英文,看着真心累,于是翻译一下,以供参考。

 

下面是完整是使用html格式邮件发送带附件邮件的perl代码:

#!/usr/bin/perl -w
use Email::Send;
use MIME::Entity;

sub SendMail {
	my $att_path = "/home/sam/tmpa.txt";
	my $mail_host = 'smtp.sendmailhost.com';
	my $mail_port = 587;
	my $mail_user = 'username@sendmail.com';
	my $mail_pass = 'this is your password';
	my $from_add  = '发件人<from@frommail.com>';
	my $to_add    = '收件人<to@tomail.com>';
	my $subject   = 'Mail Test with Attach and Html';
	
	my @Hello     = split(/\@/,${mail_user});
	my $mail_content = '
	<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"></meta></head>
	<body style="FONT-FAMILY: 宋体; COLOR: rgb(0,0,0); FONT-SIZE: 13px">
	<p> </p>
	<p>亲爱的samsam(^_^):</p>
	<table>这是邮件正文,带html格式</table>
	</body></html>
	';
	#构造sender句柄
	my $sender = Email::Send->new({mailer => 'SMTP::TLS'});
	$sender -> mailer_args(Host     => ${mail_host},
	                       Port     => ${mail_port},
	                       User     => ${mail_user},
	                       Password => ${mail_pass},
	                       Hello    => ${Hello[0]});
	#构造消息句柄
	$email = MIME::Entity->build(From    => ${from_add},
	                             To      => ${to_add},
	                             Subject => ${subject},
	                             Type    => "multipart/related");
	$email -> attach(Type => 'Text/html',
	                 Data => qq{${mail_content}});
	#添加附件
	$email->attach(Path => ${att_path},
	               Type => "AUTO");
	
	eval { $sender->send($top) };
	die "Error sending email: $@" if $@;
}

SendMail();

 

 

五、邮件发送时subject(主题)乱码问题解决

上面代码发送英文邮件,或者邮件正文内含有中文,都没有问题(如果有问题,在$sender -> mailer_args里面加一个参数:Encoding => "base64")。

但是邮件的主题死活不能显示中文。

查阅相关帖子,针对邮件主题,需要进行base64编码才可以正常显示。

编码方式:

#!/usr/bin/perl -w
use MIME::Base64::Perl;
my $subject = encode_base64('测试123',"");
$subject = "=?gb2312?B?${subject}?=";

为了方便好看,我将编码行和格式化行分开写了,实际上直接一行过就ok:

my $subject = "=?gb2312?B?".encode_base64('测试123',"")."?=";


这样,在将subject变量代入$email = MIME::Entity->build中的Subject =>${subject},就可以了。

 

另外一点遗留问题,收件人和发件人如果别名含有中文,也会乱码,修改方式和主题雷同,不过要注意邮件地址和尖括号不能使用base64编码,不然会收不到邮件!

编码方式:

my $from_add = "=?gb2312?B?".encode_base64('我是发件人','')."?=".'<from_address@mail.com>';

my $to_add = "=?gb2312?B?".encode_base64('我是收件人1','')."?=".'<to_address@mail.com>'


 

 

 

————————————————————————————————————

参考文献:

Net::SMTP::TLS(http://search.cpan.org/~awestholm/Net-SMTP-TLS-0.12/lib/Net/SMTP/TLS.pm

Email::Send::SMTP::TLS(http://search.cpan.org/~fayland/Email-Send-SMTP-TLS-0.04/lib/Email/Send/SMTP/TLS.pm

Email::Send(http://search.cpan.org/~rjbs/Email-Send-2.199/lib/Email/Send.pm

Email::Simple(http://search.cpan.org/~rjbs/Email-Simple-2.203/lib/Email/Simple.pm

MIME::Entity(http://search.cpan.org/~dskoll/MIME-tools-5.505/lib/MIME/Entity.pm

MIME::Lite(http://search.cpan.org/~rjbs/MIME-Lite-3.030/lib/MIME/Lite.pm

perl发送html的邮件(http://bbs.chinaunix.net/thread-899782-1-1.html

用Perl自动发送带有附件的电子邮件(http://www.hailongchang.org/index.php/archives/474

Base-64编码及Perl实现(http://blog.csdn.net/delphiwcdj/article/details/8146836)(http://zh.wikipedia.org/wiki/Base64

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值