我在 Amazon Linux 服务器上使用 MantisBT 1.2.6。它有自己的电子邮件发送类,位于 PHP mail() 函数之上。实际上,它还有其他选项可以直接使用 smtp 或 sendmail,但我使用 PHP mail。然后 PHP mail 又使用 sendmail。
我将 sendmail 配置为使用智能主机,它运行良好,因为我可以编写一个小型 PHP 程序通过其 mail() 函数成功发送消息。
但 MantisBT 发送的邮件从未到达且未被退回。
/var/log/maillog
显示 MantiBT 消息已成功发送到智能主机
(relay=my-smarthost-hostname) with "stat=Sent (ok nnnn qp nnnn)"
如果我更改 /etc/mail/authinfo 文件以使用错误的密码,maillog 将显示该中继的“stat=Service unavailable”。
因此,问题似乎出在 MantiBT 代码中的某个微妙之处。我使用 xdebug 找到它对 mail() 的调用,并获取其参数的值,然后将它们提取到一个单独的 php 文件中进行操作。除了第四个参数中的“From:”,它还传递了一些标头,我怀疑它们可能只是用 \n 而不是 RFC (2)821 要求的 \r\n 分隔,这导致了问题。但我添加了代码以将标头字符串中的 \n 更改为 \r\n,这没有任何区别。
最后,导致问题的原因是存在(正确的)“Date:”标头。当我从 mail() 的第 4 个参数中删除该标头时,邮件立即被发送。因此,我编辑了 MantisBT 源代码以不生成该标头,一切正常(我还编辑了 MantisBT 源代码以不在“-f”选项和发件人地址之间放置空格)。
所以我的问题是,mail() 的第 4 个参数中是否存在“Date:”标头会导致通过智能主机发送时出现问题。如果智能主机不喜欢看到 Date 标头,那么您是否会期望邮件日志中出现退回或消息?
PS 当我在邮件日志中看到已发送消息时,我实际上已经致电 Network Solutions 技术支持,但在我将其隔离到日期标头之前。当然,这没有得到任何有用的信息,只是关于如何为 POP 或 IMAP 配置电子邮件客户端的说明 :-)
答案1
显然,我被我自己的方法论所害了。
现在看来,日期标头导致邮件被智能主机接受但未被投递的原因在于,我没有在每次测试时更改标头中的时间戳。因此,智能主机看到多条具有相同邮件 ID 和时间戳的邮件进入,但只是没有投递重复的邮件。
在使事情正常运转的过程中,我看到了一些错误,其中 -f 选项被当作收件人地址(可能是因为“-f”和发件人地址之间有空格),以及其他问题。所以,当我修复了这些问题后,消息可能顺利通过了。但随后,确认成功的尝试陷入了重复消息陷阱。当然,在现实生活中,时间戳永远不会与消息 ID 重复,这只是将传递给 mail() 的参数捕获到独立静态测试用例中的一种产物。
无论如何,我认为我现在已经一切就绪,我会将日期标头恢复到 MantisBT 代码。
之前我很少发送邮件,所以这次经历对我来说是一次学习。也许这对其他人也有用,因为如果你想测试外发邮件,你不能使用固定的邮件头和不变的 MessageID 和 Date 邮件头!