如何根据 RFC 5322 折叠带有长电子邮件地址的电子邮件 header?
How to fold an email header with long email addresses according to RFC 5322?
假设电子邮件具有以下 header 字段:
To: =?utf-8?q?Foo_Bar?= <1234567890123456789012345678901234567890123456789012345678901234@abcdefghiabcdefghiabcdefghiabcdefghiabcdefghiabcdefghiabcdefghi.com>
有没有办法折叠header
- 完全符合RFC 5322
- 这样电子邮件仍然被常用的 MTA 接受,并且
- 没有一行超过 78 个字符的长度?
我知道行长度的硬性限制是 998 个字符,但我想知道是否也可以满足所有 SHOULD-requirements。如果我理解增强 Backus-Naur 形式
domain-literal = [CFWS] "[" *([FWS] dtext) [FWS] "]" [CFWS]
dtext = %d33-90 / ; Printable US-ASCII
%d94-126 / ; characters not including
obs-dtext ; "[", "]", or "\"
在section 3.4.1中是正确的,可以将折叠空格插入到域文字中,以下应该是有效的:
To: =?utf-8?q?Foo_Bar?=
<1234567890123456789012345678901234567890123456789012345678901234@abcdefgh
iabcdefghiabcdefghiabcdefghiabcdefghiabcdefghiabcdefghi.com>
然而,这被最新版本的 postfix 和 exim 拒绝了:
501: <1234567890123456789012345678901234567890123456789012345678901234@abcdefgh: '>' missing at end of address
要么两个 MTA 都损坏了(这似乎不太可能),要么我对 RFC 的解释是错误的。
附录以防有人遇到类似问题:
在发布问题之前,我实际上尝试在 @
和 .
处弃牌,如 RFC-conformant 所示,但得到了相同的错误消息。事实证明,这不是 MTA 的错,而是我使用的 SMTP 客户端库的错,它从 header 中提取收件人地址,用于为 SMTP 生成 RCPT TO:
命令,但未能过滤掉换行符。
您不能在域中间跨线边界断开域(这是您所做的),只能 before/after 域。
RFC5322 说你不应该绕过 @
,但这并不意味着不可以。
angle-addr = [CFWS] "<" addr-spec ">" [CFWS] /
obs-angle-addr
addr-spec = local-part "@" domain
local-part = dot-atom / quoted-string / obs-local-part
domain = dot-atom / domain-literal / obs-domain
domain-literal = [CFWS] "[" *([FWS] dtext) [FWS] "]" [CFWS]
dtext = %d33-90 / ; Printable US-ASCII
%d94-126 / ; characters not including
obs-dtext ; "[", "]", or "\"
atext = ALPHA / DIGIT / ; Printable US-ASCII
"!" / "#" / ; characters not including
"$" / "%" / ; specials. Used for atoms.
"&" / "'" /
"*" / "+" /
"-" / "/" /
"=" / "?" /
"^" / "_" /
"`" / "{" /
"|" / "}" /
"~"
atom = [CFWS] 1*atext [CFWS]
dot-atom-text = 1*atext *("." 1*atext)
dot-atom = [CFWS] dot-atom-text [CFWS]
specials = "(" / ")" / ; Special characters that do
"<" / ">" / ; not appear in atext
"[" / "]" /
":" / ";" /
"@" / "\" /
"," / "." /
DQUOTE
因此,如果我们扩展定义并将其应用于您的示例,我们得到的是(每个标记各占一行以避免需要水平滚动):
[CFWS]
"<"
[CFWS]
"1234567890123456789012345678901234567890123456789012345678901234"
[CFWS]
"@"
[CFWS]
"abcdefghiabcdefghiabcdefghiabcdefghiabcdefghiabcdefghiabcdefghi"
"."
"com"
[CFWS]
">"
无论您看到 [CFWS]
是规范在技术上允许您插入换行符的地方。
所以打破你的 To
header 的一个例子是这样的:
To: =?utf-8?q?Foo_Bar?=
<
1234567890123456789012345678901234567890123456789012345678901234
@
abcdefghiabcdefghiabcdefghiabcdefghiabcdefghiabcdefghiabcdefghi.com
>
任何 RFC-compliant 地址解析器都需要处理这个问题。
(Self-promotion 这里,但是 MimeKit 的地址解析器处理这个 ;-)
假设电子邮件具有以下 header 字段:
To: =?utf-8?q?Foo_Bar?= <1234567890123456789012345678901234567890123456789012345678901234@abcdefghiabcdefghiabcdefghiabcdefghiabcdefghiabcdefghiabcdefghi.com>
有没有办法折叠header
- 完全符合RFC 5322
- 这样电子邮件仍然被常用的 MTA 接受,并且
- 没有一行超过 78 个字符的长度?
我知道行长度的硬性限制是 998 个字符,但我想知道是否也可以满足所有 SHOULD-requirements。如果我理解增强 Backus-Naur 形式
domain-literal = [CFWS] "[" *([FWS] dtext) [FWS] "]" [CFWS]
dtext = %d33-90 / ; Printable US-ASCII
%d94-126 / ; characters not including
obs-dtext ; "[", "]", or "\"
在section 3.4.1中是正确的,可以将折叠空格插入到域文字中,以下应该是有效的:
To: =?utf-8?q?Foo_Bar?=
<1234567890123456789012345678901234567890123456789012345678901234@abcdefgh
iabcdefghiabcdefghiabcdefghiabcdefghiabcdefghiabcdefghi.com>
然而,这被最新版本的 postfix 和 exim 拒绝了:
501: <1234567890123456789012345678901234567890123456789012345678901234@abcdefgh: '>' missing at end of address
要么两个 MTA 都损坏了(这似乎不太可能),要么我对 RFC 的解释是错误的。
附录以防有人遇到类似问题:
在发布问题之前,我实际上尝试在 @
和 .
处弃牌,如 RFC-conformant RCPT TO:
命令,但未能过滤掉换行符。
您不能在域中间跨线边界断开域(这是您所做的),只能 before/after 域。
RFC5322 说你不应该绕过 @
,但这并不意味着不可以。
angle-addr = [CFWS] "<" addr-spec ">" [CFWS] /
obs-angle-addr
addr-spec = local-part "@" domain
local-part = dot-atom / quoted-string / obs-local-part
domain = dot-atom / domain-literal / obs-domain
domain-literal = [CFWS] "[" *([FWS] dtext) [FWS] "]" [CFWS]
dtext = %d33-90 / ; Printable US-ASCII
%d94-126 / ; characters not including
obs-dtext ; "[", "]", or "\"
atext = ALPHA / DIGIT / ; Printable US-ASCII
"!" / "#" / ; characters not including
"$" / "%" / ; specials. Used for atoms.
"&" / "'" /
"*" / "+" /
"-" / "/" /
"=" / "?" /
"^" / "_" /
"`" / "{" /
"|" / "}" /
"~"
atom = [CFWS] 1*atext [CFWS]
dot-atom-text = 1*atext *("." 1*atext)
dot-atom = [CFWS] dot-atom-text [CFWS]
specials = "(" / ")" / ; Special characters that do
"<" / ">" / ; not appear in atext
"[" / "]" /
":" / ";" /
"@" / "\" /
"," / "." /
DQUOTE
因此,如果我们扩展定义并将其应用于您的示例,我们得到的是(每个标记各占一行以避免需要水平滚动):
[CFWS]
"<"
[CFWS]
"1234567890123456789012345678901234567890123456789012345678901234"
[CFWS]
"@"
[CFWS]
"abcdefghiabcdefghiabcdefghiabcdefghiabcdefghiabcdefghiabcdefghi"
"."
"com"
[CFWS]
">"
无论您看到 [CFWS]
是规范在技术上允许您插入换行符的地方。
所以打破你的 To
header 的一个例子是这样的:
To: =?utf-8?q?Foo_Bar?=
<
1234567890123456789012345678901234567890123456789012345678901234
@
abcdefghiabcdefghiabcdefghiabcdefghiabcdefghiabcdefghiabcdefghi.com
>
任何 RFC-compliant 地址解析器都需要处理这个问题。
(Self-promotion 这里,但是 MimeKit 的地址解析器处理这个 ;-)