【问题标题】:Net::SMTP::SSL (via gmail and amazon smtp) - 'Connection Closed' when sending email with attachmentNet::SMTP::SSL(通过 gmail 和 amazon smtp) - 发送带有附件的电子邮件时“连接已关闭”
【发布时间】:2017-05-26 10:36:02
【问题描述】:

我有一个 perl 导出脚本,它生成一个 .csv 文件,然后通过电子邮件将其发送给用户。我走这条路是因为我们不希望用户必须在特定页面上等待导出完成,而是允许它在后台导出。

但是,当附加 csv 并发送电子邮件时,我收到以下错误:

[Net::SMTP::SSL] Connection closed

我不能在这里放很多代码,但我至少可以告诉你代码的哪一部分报告了这个错误。我想知道这里是否有人知道为什么会发生这种情况,或者有一种简单的调试方法。

这是发送电子邮件的代码块(带有错误报告的注释):

my $mailer = new Net::SMTP::SSL($smtp, Port => $port) or die "Cannot create a SSL mailer instance!\n";
$mailer->auth($user, $pass) or die ("Can't authenticate");

$mailer->mail($email) or die $mailer->message;
$mailer->to(split(',', $to)) or die $mailer->message;
$mailer->data() or die $mailer->message;
$mailer->datasend($msg->as_string) or die $mailer->message; # Connection closed
$mailer->dataend() or die $mailer->message;
$mailer->quit() or die $mailer->message;

如果需要任何其他信息,请告诉我。我会尽力提供我能提供的。这很难解决,因为错误是如此模棱两可。

注意:删除违规附件时电子邮件成功发送,有时会根据 csv 内容发送。

【问题讨论】:

  • 请添加所有详细信息以使问题可重现。如果问题仅发生在特定邮件内容上,您需要将此内容添加到问题中。见How to create a Minimal, Complete, and Verifiable example
  • @SteffenUllrich 虽然我希望可以添加 csv 的内容,但有问题的内容是我无法提供的敏感数据。我知道这只会使事情复杂化,但我有点抓住稻草,看看是否有人遇到某些内容的问题,导致拒绝/关闭与 gmail 的 smtp 连接。
  • 您不需要添加导致问题的原始(敏感)内容,只需添加一些导致问题的(非敏感)内容就足够了。我怀疑您将无法解决您公认的奇怪问题,因为无法重现它。还要确保您使用的是最新版本的 Net::SMTP(由 Net::SMTP::SSL 使用),以防出现已知但已修复的错误。
  • 我不知道整个 csv 中的原因是什么。为了做到这一点,我需要逐行、逐列地找出问题发生的位置(30 多列,超过 100 行)。这也不是万能的,因为我需要在多个导出上对此进行测试,因为任何数据都可能导致类似的问题。
  • 正如答案中所建议的:邮件的大小比 CSV 的内容更有可能。您是否尝试发送相同尺寸的无用的东西?无论如何,敏感内容都应该进行 PGP 加密,通过亚马逊发送,可能还有谷歌,就像自己将其上传到 NSA 服务器一样。

标签: perl email gmail amazon


【解决方案1】:

这是由 Net::Cmd 中的错误引起的,已在 3.08 中修复。将 Net::Cmd 升级到 3.08 或更高版本,或通过更改来更正有问题的行(大约 530 和 573 行):

  unless (defined($w) && $w == $len) {

  unless (defined($w) && $w > 0) {

如果该行需要发送多个块,则该行会导致连接立即失败,即使代码已经正确处理了发送多个块。因此,当您必须发送大量时,它会失败,如果不是(没有附件)它会成功。

【讨论】:

  • 感谢您的洞察力,在我接受您的回答之前,我必须验证是否属实,但这听起来很正确。
  • 在 Ubuntu 16.04 上为我准备了 3.05。
  • 这很奇怪,因为我也有 Ubuntu 16.04,但补丁对我没有帮助。但是使用 CPAN 升级 Net::Cmd 确实如此,所以仍然赞成。
【解决方案2】:

Net::SMTP 也支持 SSL。您可能想尝试将它作为 Net::SMTP::SSL 的直接替代品,但我怀疑它会产生很大的不同。

尝试启用调试模式以查看发生了什么:

my $mailer = new Net::SMTP::SSL($smtp, Port => $port, Debug => 1) or die "Cannot create a SSL mailer instance!\n";

您应该尝试找出问题是否与从特定大小(1k?8k?)开始的电子邮件有关。

Gmail 永远不会只是关闭中间的连接,如果连接被有意关闭,它们总是会返回错误消息。

【讨论】:

  • 我将尝试使用调试模式,以及使用 Net::SMTP。感谢您提供替代方案,如果可以解决问题,我会回复您,或者如果调试器对此有所了解,请回答问题。
【解决方案3】:

调试器似乎有意外的 EOF 报告。这是重复的Net::SMTP: Net::Cmd::_is_closed(): unexpected EOF on command channel [perl]

新错误:Net::SMTP::SSL: Net::Cmd::datasend(): unexpected EOF on command channel

【讨论】:

    猜你喜欢
    • 2010-11-16
    • 1970-01-01
    • 1970-01-01
    • 2022-08-14
    • 2014-01-04
    • 2018-01-15
    • 2014-08-27
    • 2017-05-12
    • 2020-02-21
    相关资源
    最近更新 更多