摘要

  • RFC 2447 为 iTIP 定义了电子邮件绑定:MIME 负责封装,text/calendar 中的 iCalendar 对象承载日程数据。
  • multipart/alternative 可以同时照顾日历客户端与普通邮件阅读器,但两部分应表达同一对象,而不是两个互相竞争的时间。

三层职责被装进一封邮件

一封邀请邮件看似只是“发件人、收件人、主题、正文”。对日历软件来说,它其实还要回答另一个问题:哪一部分才是可以交给日程协议处理的对象?RFC 2447(iMIP)在 1998 年给出了这层连接。iCalendar 定义事件数据,iTIP 定义跨实现的日程操作,邮件负责传输;iMIP 则把前两者装进 MIME 消息。它没有把电子邮件的标题、发件人栏或普通文本变成日程语义。

其核心约定是 MIME 内容类型 text/calendar。该部分必须带有 method 参数,而且参数值要与对象内部的 METHOD 属性一致。两个地方写下同一个方法,不是多余重复:外层让 MIME 处理者识别这一部分的用途,内层则是日历对象自身的字段。外层与内层若相矛盾,处理者便无法确定包裹的意图。多个日历对象如果采用不同方法,应各自放入 text/calendar 实体,再由 multipart/mixed 组合;不能把几种不同操作压成一个含糊的对象。

给人看的说明不是另一份日程

当时并非每个邮件客户端都能理解 text/calendar。MIME 因而允许一封消息包含普通文本与结构化日历的两种表示。没有日历功能的软件可以显示日期、地点和参与者;具备日历功能的客户端则处理 iCalendar 对象。这就是 multipart/alternative 的用途:让不同能力的客户端读取同一个安排。

它不应该被误用为“二选一”机制。两份开始时间不同的 VEVENT 并不是同一日程的两种显示方式。若把它们放进替代部分,接收方无从判断这是邀约选项、修正还是意外冲突。真正的日程变更应由 iTIP 的操作表达,MIME 结构只组织内容的封装与呈现。这样一来,普通文本可以帮助人理解消息,却不取代机器可读对象。

字符集和传输编码也决定对象能否完整穿过邮件路径。RFC 2447 要求在出现非 ASCII 字符时声明字符集,并说明如何为不适合当前传输的内容使用编码。RFC 6047 在 2010 年取代 RFC 2447,并更新了消息格式和 S/MIME 相关要求。这些规范关注的是字节如何保留下来、如何被解码,并不证明邮件已经送达,或日历应用已经保存了变更。

附件引用揭示了另一种容易被忽略的差别。日历对象可以通过 Content-ID 或 Message-ID 指向其他内容。RFC 2447 建议尽量把被引用的 MIME 部分和日历对象一同发送;外部引用可能指向接收者无法访问或无权打开的资源。引用能指出目标,却不是目标内容本身,更不是访问授权。

邮件头也不能可靠地替代日历角色。转发会改变当前的 Sender,而邮件代理不必把 ORGANIZER 自动复制到 Reply-To。因此,RFC 2447 要求实现从 text/calendar 中读取 ORGANIZER 与 ATTENDEE,而不是仅凭外层地址推断谁在组织或回应。RFC 2447 曾借助 RFC 1847 的 MIME 安全多部分来讨论认证和保密;RFC 6047 后来要求使用 S/MIME 认证。即使受保护部分的签名通过验证,它也只证明特定内容与签名者之间的关系,不能证明收件箱收到邮件、客户端执行了处理或用户同意出席。

RFC 2447 于 1998 年 11 月作为标准轨迹文件发布,2010 年由 RFC 6047 取代。这段演进史能说明邮件绑定如何随消息格式和安全方案更新,却不能说明市场采用比例。它留下的架构原则更克制:日程含义属于日历对象,MIME 说明对象如何装入消息,邮件负责传递;三者不能被一个“已发送”状态合并。

来源