Perl MIME::Lite 正在分解 HTML 主体

Perl MIME::Lite is breaking up HTML body

大约在 2004 年,我用 MIME::Lite 写了一个 Perl 电子邮件程序,从那时起就一直有效。只有现在客户端才尝试用它发送 HTML 。以下代码(精简到重要部分)正确设置了所有值。 HTML 正文附加为 text/html。在附件之前,数据显然没有 CR(CRLF 或 LF)。但是在附加它之后 HTML 确实 有一个嵌入式 CR。这个好像是在1000字之后加的

不幸的是,它落在了标签的中间,因此破坏了在收件人电子邮件中呈现为标签的标签,而不是完全呈现为格式化文本:<BR> 显示为 < BR>.而且它没有破坏特定的标签。我可以更改标签,它总是围绕相同的字符位置中断。我已经通读了 MIME::Lite 代码(使用我非常生疏的 Perl 技能),但我看不出它会在哪里执行此拆分操作。

use MIME::Lite; # v3.030

my $bodyWithNoCR = "<html>" . ("x" x 1020) . "</html>";

my $mime_msg = MIME::Lite->new(
    From => 'x@x.com',
    To   => 'x@x.com',
    Subject => 'Subject',
    Type    =>'multipart/mixed')
or die "$!\n";

$mime_msg->attach(
    Type => 'text/html',
    Data => $bodyWithNoCR)
or die "$!\n";

my $bodyWithCR = $mime_msg->as_string;

不只是 as_string 显示了这一点,Net::SMTP 转储显示了 HTML 跨行拆分,这反映在收件人的电子邮件客户端中。

我知道 MIME::Lite 被认为是有问题的。但我的问题是这个特定问题是否被识别(最好参考跟踪器 ID)。 "yes, I've seen that" 的响应很有帮助,但(恭敬地)不足以确认这是旧代码中的已知问题。如果我能找到这个问题的跟踪器项目,我就会知道我是否可以寻找补丁,或者我是否需要向用户建议这个特定代码不能用于这个特定目的。

任何人都可以建议 attach() 的替代代码,这可能会导致它避免破坏块的任何东西吗?

至于使用其他工具(预期响应),多年后我用 PHPMailer 为其他客户重写了这一切,但 API 不同,客户重新使用工具会很麻烦用那个。我也可以用其他东西替换 MIME::Lite(按照维护者的建议),但是在旧的 Linux 框上,依赖链的要求可能会阻止加载任何更新的内容。也就是说,欢迎使用 MIME::Lite 的替代方法。

目前没有更好的解决方案,正在考虑(但根本不喜欢)的唯一解决方法是使用 980-1020、1980-2020 等列的嵌入空间构建 HTML,因此即使嵌入了 CR,收件人的邮件客户端中也看不到空格。 (是的,讨厌!)

我相信 this 可能与正在发生的事情有关:

#------------------------------
#
# encode_8bit STRING
#
# Encode the given string using 8BIT.
# This breaks long lines into shorter ones.

sub encode_8bit {
    my $str = shift;
    $str =~ s/^(.{990})/\n/mg;
    $str;
}

SMTP 服务器有行长度限制,最多允许 1000 个八位字节。因此,MIME::Lite 提供以下内容传输编码选择说明:

Use encoding:     | If your message contains:
------------------------------------------------------------
7bit              | Only 7-bit text, all lines <1000 characters
8bit              | 8-bit text, all lines <1000 characters
quoted-printable  | 8-bit text or long lines (more reliable than "8bit")
base64            | Largely non-textual data: a GIF, a tar file, etc.

启发式算法默认使用 8 位,因此 MIME::Lite 正在添加换行符以在不合适的输入下做到最好。解决方案是告诉 MIIME::Lite 使用 quoted-printable(或 base64)编码。

$mime_msg->attach(
    Type     => 'text/html',
    Encoding => 'quoted-printable',
    Data     => $bodyWithNoCR)
or die "$!\n";

[在评论中,OP 澄清说他们说“CR”时的意思是“换行符”。但是,OP 仍然提到 CR,所以我将这段话留在这里。]

至于马车 Returns,我什至在添加 Encoding => 'quoted-printable' 之前都没有得到。我怀疑您的 $bodyWithCR 没有 Carriage Returns,并且该错误在您检查它的方式中。具体来说,我认为你打印了 $bodyWithCR 到一个句柄,而没有先对它做 binmode