摘要
- RFC 3503 让多个邮件用户代理通过同一 IMAP 邮箱中的
$MDNSent共享“不再生成 MDN”的决定,避免各自发送一次处置通知。 - 这个名字容易被误读:用户拒绝通知、保存已发送邮件、保存未完成邮件,以及某些没有实际发出通知的自动处理,都会写入同一个标记;它证明的是抑制状态,而不是发送事件或人工阅读。
设想一封邮件先在办公室电脑上被处理,晚上又在笔记本上打开。第一台电脑已经判断是否回应邮件中的处置通知请求,并把决定记在本地。第二台电脑能看到服务器上的邮件,却看不到前一台电脑的私有记忆。如果每个客户端都从头判断,一次请求可能引出多次通知。
2003 年 3 月发布的 RFC 3503 把问题缩到一个很窄的共同层。它没有发明新的 IMAP 命令,也没有增加新的响应,而是定义了专用邮箱关键字 $MDNSent,要求不同邮件用户代理遵守同一套读写规则。共享邮箱不仅存邮件,也存一项足以阻止重复动作的状态。
关键在于:这个关键字的名称并不等于它的全部语义。“MDN 已发送”像是在叙述过去,但规范要求客户端在自动处置后写入该标记,“无论 MDN 是否被发送”。用户明确拒绝回执时,客户端也可以写入它,以免另一台设备再次询问或代为发送。保存到已发送文件夹的副本必须带上它;保存尚未完成的邮件也必须带上它。
这些写入路径有完全不同的历史,却产生相同的未来约束。最稳妥的解释是:对这个存储中的邮件对象,后续合规客户端不得再生成 MDN。它不能回答哪个客户端作出决定、是否构造了通知、是否提交给邮件系统、是否送达,更不能回答收件人是否阅读或理解原文。
客户端首先要检查邮箱是否能永久保存这项状态。RFC 3503 要求在打开邮箱时查看 PERMANENTFLAGS,确认服务器能够保存 $MDNSent 本身,或者允许任意关键字。能力声明与一次具体写入仍是两件事。服务器可能已经声明支持任意关键字,却因为该邮箱的关键字容量耗尽而对 STORE 返回 NO。
规范对失败的处理暴露了优先级:若客户端无法保存 $MDNSent,就不应发送 MDN。立即发送可能完成眼前动作,却不给其他客户端留下可靠记忆,随后便可能重复发送。RFC 3503 选择了“宁可缺少一次通知,也不要在没有共同状态时冒险重复”。这不是对所有故障都成立的恰好一次保证,而是一个封闭式的局部安全选择。
现有的 IMAP 标志不能随意顶替。\Recent 看似表示新邮件,但多个连接同时选择同一邮箱时,哪一个连接能看到 Recent 状态并没有确定规则,因此它不能承担共同任务分配。\Seen 可以成为“不发送”的一个参考,却已有自己的含义。\Draft 表示邮件不完整,也会阻止通知。一旦 $MDNSent 出现,客户端必须为 MDN 决策忽略其他标志和关键字。
这个状态还是单向的。客户端写入后不得删除。单向转移减少了旧请求被意外重新激活的机会,但也说明它不是审计日志:它没有保存时间、主体、理由、授权或外部结果。一个不会回退的停止位,可以很好地协调未来,却无法还原过去。
复制邮件时,状态必须与对象一起移动。客户端应验证普通 COPY 是否保留 $MDNSent;跨服务器用 APPEND 复制时,必须正确附带该关键字。否则目的邮箱只得到内容,没有得到抑制决定,新客户端会把“标记丢失”错当成“尚未处理”。
ACL 规则进一步分开了不同权限。服务器仍必须检查客户端是否有权复制邮件;但若复制本身被允许,即便客户端没有一般性的写标志权限,服务器也应在副本上保留 $MDNSent。复制授权不等于任意修改授权,而共同协调属性又不能因为缺少后一种授权而脱落。
大小写也不能制造多个状态。规范示例把 $MdnSENt、$MdnSENT 和 $mdnsent 视为同一个关键字,并允许用另一种大小写搜索。如果不同客户端按字面大小写分裂状态,所谓共同记忆就会失效。
MDN 本身属于另一条证据链。RFC 2298 给出了早期格式,RFC 3798 作了修订,RFC 8098 最终成为互联网标准 STD 85。它对处置类型给出严格边界:displayed 只说明邮件用户代理把消息显示给正在查看邮箱的某个人,并不保证内容被阅读或理解;processed 可能完全由规则或服务器完成;deleted 也不能说明此前没人见过邮件,或以后无法恢复。
隐私要求同样限制回执。默认选择应是不发送;地址不一致等情形需要用户确认;MDN 可能被伪造、丢失、用来放大邮件流量,或泄露客户端信息。RFC 8098 明确说它不提供不可否认的投递证明,也不能保证邮件已经或尚未被看见。即使真的收到一个 MDN,它也只是带有来源与传输问题的类型化声明。
RFC 5788 后来登记 $MDNSent 时,用更准确的措辞解释了目的:被该关键字标注的邮件不得再发送 MDN。这是一个禁止规则,而不是一段事件传记。IANA 的关键字登记让这种共享语义可以被统一发现,却没有增加运行时证据。
RFC 9007 把同一概念带到 JMAP,并把动作与状态结合得更紧。客户端在调用 MDN/send 时要安排成功后更新 $mdnsent;服务器必须拒绝不会产生这项更新的调用,并可在标记已存在时返回 mdnAlreadySent。这减少了 JMAP 操作与共同记忆之间的间隙,但不能倒推 RFC 3503 的实现,也不能证明人类阅读或通知最终送达。
因此,审计必须保留完整阶梯。PERMANENTFLAGS 证明服务器宣告一种存储能力;STORE OK 证明一次标记变更被接受;$MDNSent 证明后续客户端应停止生成;构造、提交、传输和送达通知各有自己的收据;MDN 中的 disposition 只是限定范围的陈述;人的注意、理解和行动还在更后面。
RFC 3503 的历史意义不在于创造“已读回执”,而在于把共同层限制在真正需要共同的内容:多个独立客户端不得对同一存储对象重复生成 MDN。它没有把邮箱服务器变成阅读事实的裁判,也没有把方便的字段名变成事件证明。
共享记录能够协调行为,却不自动描述现实。名称越像结论,越应该检查所有写入路径。对 $MDNSent 来说,最重要的事实恰恰是:有时什么也没有发送,而停止命令仍然完全有效。
来源
- https://www.rfc-editor.org/rfc/rfc3503.html
- https://www.rfc-editor.org/rfc/rfc3503.txt
- https://www.rfc-editor.org/info/rfc3503
- https://datatracker.ietf.org/doc/rfc3503/
- https://datatracker.ietf.org/doc/rfc3503/history/
- https://www.rfc-editor.org/errata_search.php?rfc=3503
- https://www.rfc-editor.org/rfc/rfc2298.html
- https://www.rfc-editor.org/rfc/rfc3798.html
- https://www.rfc-editor.org/rfc/rfc8098.html
- https://www.rfc-editor.org/info/rfc8098
- https://www.rfc-editor.org/rfc/rfc3501.html
- https://www.rfc-editor.org/rfc/rfc9051.html
- https://www.rfc-editor.org/rfc/rfc2086.html
- https://www.rfc-editor.org/rfc/rfc4314.html
- https://www.rfc-editor.org/rfc/rfc5788.html
- https://www.iana.org/assignments/imap-jmap-keywords/imap-jmap-keywords.xhtml
- https://www.rfc-editor.org/rfc/rfc9007.html
- https://www.rfc-editor.org/rfc/rfc8621.html
- https://heng.lu/minimum-initial-specification-localized-future-decision-voluntary-adoption-internet-coordination-system/
- https://heng.lu/on-reality-layers-symbolic-power-and-why-clarity-feels-so-hostile/
会员简报
档案背景详情
使用相应会员等级登录,即可解锁完整简报与来源注释。
仅限 Strategic Circle
Strategic Circle
所有读者均可浏览。加入并登录后可解锁档案简报。
加入 Strategic Circle仅限 Leadership Alliance
Leadership Alliance
符合条件的 IP 资产所有者和管理层可登录查看 Leadership Alliance 简报。
加入 Leadership Alliance
