RFC 3462: 多部分/报告内容类型
ELI5: 想象一个标准化的马尼拉文件夹,用于邮件相关事件报告。第一页是简明英文摘要,第二页是一个带有复选框和计算机可读代码的表单,第三页是原始信件的复印件。RFC 3462为电子邮件定义了这种文件夹格式。它后来被RFC 6522取代,但概念是相同的。
为什么存在这个格式
当DSN(递送状态通知)框架在1990年代中期创建时,作者需要一个MIME容器,可以在同一消息中承载人类可读和机器可读的内容。普通的multipart/mixed在结构上可行,但它没有提供语义信号表明该消息是具有特定内部格式的自动化报告。
multipart/report通过以下方式解决这个问题:
- 向邮件客户端发出信号,表明消息是自动化报告,启用特殊的UI处理(许多客户端显示退信方式不同于常规邮件)
- 包含
report-type参数,以便解析器知道内部预期的机器可读格式 - 定义严格的部分顺序:人类可读优先,机器可读其次,原始消息第三
RFC 3462是该规范的第二个版本(在RFC 1892之后)。它后来被RFC 6522废弃,该版本严格化了语言并更新了IANA注册。实际的网络格式没有改变——符合RFC 3462的消息也符合RFC 6522。
工作原理
multipart/report内容类型的工作方式类似任何MIME多部分,具有额外的约束:
Content-Type声明
Content-Type: multipart/report; report-type=delivery-status; boundary="REPORT-BOUNDARY"
report-type参数告诉收件人这是什么类型的报告。boundary参数分隔MIME部分,如同任何多部分消息一样。
三部分结构
--REPORT-BOUNDARY Content-Type: text/plain ; 第1部分:人类可读的摘要 向user@example.org的递送永久失败。 收件人邮箱不存在。 --REPORT-BOUNDARY Content-Type: message/delivery-status ; 第2部分:机器可读的报告 Reporting-MTA: dns; mx.example.com Final-Recipient: rfc822;user@example.org Action: failed Status: 5.1.1 --REPORT-BOUNDARY Content-Type: text/rfc822-headers ; 第3部分:原始消息头(可选) From: sender@example.com To: user@example.org Subject: Hello Message-ID: <msg-001@example.com> --REPORT-BOUNDARY--
关键技术细节
随时间推移定义的报告类型
当RFC 3462发布时,只存在delivery-status。后来的RFC添加了更多使用相同multipart/report容器的报告类型:
| report-type | 用途 | 定义者 |
|---|---|---|
delivery-status |
退信/递送通知 | RFC 3464 |
disposition-notification |
已读回执(MDN) | RFC 8098 |
feedback-report |
垃圾邮件投诉(ARF) | RFC 5965 |
tlsrpt |
TLS协商失败 | RFC 8460 |
所需的最少部分
RFC 3462要求至少两部分:人类可读的摘要和机器可读的报告。第三部分(原始消息)是可选的,但对DSN强烈推荐,因为它让发件人能够识别哪条消息退信了。
与RFC 6522的关系
RFC 6522废弃了本文档。这些改变是编辑性的,而非行为性的:
report-type参数被明确标记为必需(3462含糊不清)- IANA注册模板已更新至当前标准
- 添加了对国际化消息类型(
message/global)的支持
如果你的代码已正确处理RFC 3462,它也能处理RFC 6522。网络格式未改变。
常见错误
- 将人类可读部分视为权威。第一部分仅用于显示。自动化系统必须解析第二部分(机器可读)。人类可读的文本可能与结构化数据不匹配。
- 假设只有三部分。虽然大多数报告恰好有三部分,规范允许两部分(无原始消息)。解析器在缺少第三部分时不应失败。
-
完全忽略multipart/report。一些退信处理器尝试将所有退信消息解析为自由格式文本。这效果不佳。始终首先检查
multipart/report,并在可用时使用结构化数据。 -
不检查report-type。
report-type=feedback-report的multipart/report是垃圾邮件投诉,而非退信。将其视为退信(并从列表中删除地址)是错误的——地址有效,收件人只是不想要你的邮件。 - 生成不含第三部分的报告。虽然技术上有效,但省略原始消息头使发件人很难识别哪条消息触发了报告。始终至少包含头部。
可递送性影响
-
所有自动电子邮件反馈流通过此格式。无论是退信、垃圾邮件投诉、已读回执还是TLS报告,外部容器都是
multipart/report。理解该格式是处理任何这些的前提。 -
正确的退信分类从这里开始。通过首先检查
report-type,你的系统可以将delivery-status消息路由到退信处理器,并将feedback-report消息路由到投诉处理器——两个基本不同的工作流。 -
邮件客户端显示。许多邮件客户端识别
multipart/report并以特殊方式呈现它(例如,显示"递送失败"横幅)。生成格式良好的报告会改善服务器发送退信时的用户体验。 - Message-ID关联。第三部分(原始消息或头部)是如何将退信匹配回导致它的消息的。没有它,你只能根据收件人地址猜测,这对转发和别名不可靠。