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