在Perl中发送文本附件时出现问题

时间:2018-10-01 08:24:12

标签: perl smtp email-attachments

我有一个发送邮件的程序,如下所示:

sub SendMail {
    my $subject = shift;
    my @message = @_;
    my $sender;

    my $MIME_BOUNDARY = '====Multipart.Boundary.689464861147414354====';
    my $now = strftime("%Y-%m-%d %H:%M:%S", localtime);
    my @addresses = split(",", $ENV{ADMIN_MAIL});
    my $sender = $ENV{USER} || $ENV{USERNAME};
    $sender .= "\@" . hostname();
    my $smtp = Net::SMTP->new($ENV{MAILHOST} || 'mailhost', Debug => 1);
    unless ( $smtp ) {
        die "Error while sending notification mail. Not connected to SMTP server.";
    }
    $smtp->mail( $addresses[0] );
    $smtp->recipient( @addresses );
    $smtp->data;
    $smtp->datasend("From: $sender\n");
    $smtp->datasend("To: " . join(",", @addresses) . "\n");
    $smtp->datasend("Subject: $subject\n");
    $smtp->datasend("Date: " . strftime("%a, %d %b %Y %H:%M:%S %z", localtime) . "\n");     

    if ( @log_messages ) {
        $smtp->datasend("Mime-Version: 1.0\n");
        $smtp->datasend("Content-Type: multipart/mixed; boundary=\"$MIME_BOUNDARY\"\n");
        $smtp->datasend("This is a multipart message in MIME format.\n");
        $smtp->datasend("--$MIME_BOUNDARY\n");
    }

    $smtp->datasend("Content-type: text/plain; charset=UTF-8\n");
    $smtp->datasend("Content-Disposition: quoted-printable\n");
    $smtp->datasend("\n");
    foreach ( @message ) { $smtp->datasend("$_\n") }
    $smtp->datasend("\n\n");
    $smtp->datasend("Message from " . hostname() . " (PID=$$) sent by 'LogDumper.pl' at $now");
    $smtp->datasend("\n");

    if ( @log_messages ) {
        $smtp->datasend("\n");
        $smtp->datasend("--$MIME_BOUNDARY\n");
        $smtp->datasend("Content-Type: text/plain; name=\"logs.txt\"\n");
        $smtp->datasend("Content-Disposition: attachment; filename=\"logs.txt\"\n");
        $smtp->datasend("\n");
        foreach ( @log_messages ) { $smtp->datasend("$_\n") }
        $smtp->datasend("\n");
        $smtp->datasend("--$MIME_BOUNDARY--\n");
    }

    $smtp->dataend;
    $smtp->quit;

}

该过程适用于纯文本邮件,即空@log_messages。但是,如果我尝试附加文本文件

my @log_messages;
push @log_messages, "Line 1";
push @log_messages, "Line 2";
SendMail("The Subject", "The Message");

然后不发送邮件。

调试输出是这样的:

Net::SMTP=GLOB(0x7a78a40)<<< 354 Start mail input; end with <CRLF>.<CRLF>
Net::SMTP=GLOB(0x7a78a40)>>> From: Domscheit@xxxxx
Net::SMTP=GLOB(0x7a78a40)>>> To: wernfried.domscheit@xxxxx.xxx
Net::SMTP=GLOB(0x7a78a40)>>> Subject: The Suject
Net::SMTP=GLOB(0x7a78a40)>>> Date: Mo, 01 Okt 2018 10:15:57 W. Europe Daylight Time
Net::SMTP=GLOB(0x7a78a40)>>> Mime-Version: 1.0
Net::SMTP=GLOB(0x7a78a40)>>> Content-Type: multipart/mixed; boundary="====Multipart.Boundary.689464861147414354===="
Net::SMTP=GLOB(0x7a78a40)>>> This is a multipart message in MIME format.
Net::SMTP=GLOB(0x7a78a40)>>> --====Multipart.Boundary.689464861147414354====
Net::SMTP=GLOB(0x7a78a40)>>> Content-type: text/plain; charset=UTF-8
Net::SMTP=GLOB(0x7a78a40)>>> Content-Disposition: quoted-printable
Net::SMTP=GLOB(0x7a78a40)>>> The Message
Net::SMTP=GLOB(0x7a78a40)>>> Message from xxxxx (PID=8072) sent by 'LogDumper.pl' at 2018-10-01 10:15:54
Net::SMTP=GLOB(0x7a78a40)>>> --====Multipart.Boundary.689464861147414354====
Net::SMTP=GLOB(0x7a78a40)>>> Content-Type: text/plain; name="logs.txt"
Net::SMTP=GLOB(0x7a78a40)>>> Content-Disposition: attachment; filename="logs.txt"
Net::SMTP=GLOB(0x7a78a40)>>> Line 1
Net::SMTP=GLOB(0x7a78a40)>>> Line 2
Net::SMTP=GLOB(0x7a78a40)>>> --====Multipart.Boundary.689464861147414354====--
Net::SMTP=GLOB(0x7a78a40)>>> .
Net::SMTP: Unexpected EOF on command channel at C:\Developing\Source\LogDumper.pl line 1271.

显然有一个丢失或不必要的\n。我试图将其放置在几乎所有地方,但无法正常工作。

更新

实际上,当我在Linux上执行脚本但在Windows开发PC上不执行脚本时,

1 个答案:

答案 0 :(得分:0)

我认为问题已经解决。

  • 它可以在Linux上的生产服务器上运行
  • 当我在办公室工作时,它可以在开发Windows PC上运行
  • 当我在家工作并通过VPN连接时,它在Windows上不起作用-讨厌的安全部门...

嗯,这并没有真正解决,但对我来说,它工作正常。我还没有测试(是否)它也不能针对其中一个较高级别的软件包通过VPN进行故障转移。