摘要

  • RFC 5367 允许客户端在初始 SUBSCRIBE 中放入扁平资源 URI 名单,以 recipient-list-subscribe 要求服务能力,并在一个对话中通过 rlmi+xml 通知取得各资源状态。
  • 初始请求访问公开名单 URI;对话建立后,续订访问服务器提供的 URI。后者不支持名单正文的创建语义,收到此类正文时服务器以 415 拒绝。相同方法与文档不能抹平两个资源的权限差异。
  • 治理必须保留能力来源:调用者、公开入口、名单版本、规范集合、逐目标许可、对话、续订目标、通知位置、管理 URI、终止与已验证删除分别作证。

地址变化不是路由细节

URI 常被运营系统当作“把请求送到哪里”的字段。RFC 5367 让它承担更强的意义:不同 URI 暴露不同能力。

初始 SUBSCRIBE 指向资源名单的公开 URI。请求至少携带一个处置类型为 recipient-list 的正文,内容是 RFC 4826 格式的资源名单;Require 中必须包含 recipient-list-subscribe。

服务器接受后建立对话,并提供后续请求使用的 URI。续订不再发往最初公开入口。对客户端而言,前一个资源支持名单正文,后一个资源不支持。

若审计只记录方法是 SUBSCRIBE,就会漏掉最关键的权限变化。创建一个集合与维持已存在的集合不是同一动作,即使它们属于同一用户体验。

后续目标继承了有限能力

服务器提供续订 URI,是在对话已经合法建立之后产生的能力。它允许客户端延长持续时间等维护操作,却没有自动获得重新定义成员的权力。

RFC 5367 没有为后续 SUBSCRIBE 中的名单正文定义语义。客户端不应携带,服务器收到后按标准 SIP 过程返回 415 Unsupported Media Type。

这种拒绝是一条安全边界,而不是功能缺失。若每次续订都能悄悄替换名单,那么持有维护能力就等同于拥有扩大观察范围的能力。

日志应记录初始 URI、已认证主体、输入名单哈希、对话标识、服务器提供的目标、请求阶段以及任何 415。这样才能证明能力如何获得、允许什么,以及为什么某个正文没有生效。

一个响应不能代表所有下游资源

初始 SUBSCRIBE 的响应状态不说明资源名单服务器是否成功订阅了名单中的各个 URI。规范要求客户端从服务器发出的通知中获取这些信息。

因此,公开入口返回成功只证明顶层交互。Bill、Joe、Ted 的状态可能分别是成功、拒绝与未知。一个对话压缩了控制面连接,不会压缩事实数量。

仪表盘应同时展示对话状态和逐资源覆盖。规范集合决定分母;通知决定每个位置当前有什么证据。未出现在消息里的资源不能从分母消失。

重试也应按层次处理。某个位置不明不等于整条对话需要重建。否则正确资源会因一个未知项被重复扰动。

通知是状态载体,不是无限结论

RFC 4662 与 rlmi+xml 为名单资源通知提供结构。通知可以标识资源并承载与 event package 相关的状态。

但“收到通知”还不是完整性结论。系统仍要知道版本、覆盖模式、时间、资源身份以及是否存在更新丢失。全量与增量不能靠猜测区分。

每个位置应保存最后状态、来源通知、序列或版本、观察时间和终局语义。乱序消息不能把新状态倒退成旧状态,缺失消息也不能被解释成保持成功。

用户可见结果又是另一层。服务器报告订阅状态,不必然证明终端展示、业务动作或人类理解。

丰富 XML 到执行集合之间存在投影

RFC 4826 能表示层级名单和 entry-ref。RFC 5367 选择它作为默认格式,却只需要扁平 URI 列表。客户端应该不用层级和引用;服务器可以丢弃多余信息。

这意味着文档通过 schema 验证,不等于所有结构都进入执行。一个在编辑器里有意义的组层级,可能在订阅服务中没有权力。

证据链应同时保留原文档、支持的配置版本、丢弃项、规范化算法与最终扁平集合。原始文件哈希证明接收了什么;执行集合哈希证明服务解释了什么。

如果系统只保存最终集合,就无法解释用户为何认为某个引用应展开。只保存原文又无法证明下游实际面对哪些资源。

管理 URI 是第三种能力

服务器可以在建立订阅的 NOTIFY 中,通过 Call-Info 和 purpose=list-management 提供一条操纵相关名单的 URI。

它不同于公开创建 URI,也不同于对话续订 URI。收到链接不证明操作已发生,更不证明持有者在任何时间都能修改。

管理服务必须独立认证、授权、验证变更并返回收据。应用需要记录 URI 发给了谁、绑定哪个订阅、允许什么方法、何时失效以及每次变更的结果。

把三条 URI 存在同一数据库列,会诱发错误复用。它们应以能力类型和生命周期分别建模。

名单寿命绑定订阅寿命

通过管理 URI 操纵的名单,其寿命与订阅绑定。订阅到期或终止时,名单应被销毁。

这里的“应”建立了治理方向:临时名单不能因系统方便而变成永久通讯录。但协议计时器与物理删除仍是不同证据。

Expires 归零证明一个时间条件;终止通知证明对话状态;主库删除、缓存失效、索引清理与副本清理各需要自己的观察。

运营合同应写清删除对象、时限、复制拓扑、审计保留例外与完成标志。不能因为无法证明全部删除,就把仍存在的数据说成符合目的限制。

合法调用者不等于所有目标同意

RFC 5367 继承 RFC 4662 和 RFC 5363 的安全要求。资源名单服务器必须认证、授权客户端,URI 名单服务还要遵守目标 opt-in 等规则。

调用者身份只解释谁提出观察请求。它不证明每个 URI 同意当前 event package、目的与持续时间。

许可应绑定主体、服务、事件、规范 URI、用途和时间。一个“可使用订阅功能”的角色不能默默变成任意目标的观察权。

拒绝也必须留下原因。否则通知中的空位无法区分隐私保护、授权失败、路由问题或尚未尝试。

注册表没有运行时观测能力

IANA 登记 recipient-list-subscribe 与 list-management。它们让双方共享能力名称和链接目的。

Require 或 Supported 中出现选项标签,只证明协议声明;不证明各资源订阅成功。Call-Info 的 purpose 解释 URI 用途,不证明它仍有效或已经完成修改。

RFC 5367 于 2008 年 10 月以 Standards Track 发布,并通过允许 NOTIFY 携带 Call-Info 更新 RFC 3265。RFC 3265 后来被 RFC 6665 取代。现行实现应阅读完整演进关系。

标准演进不会让创建 URI 与续订 URI 合并,也不会让通知替代删除收据。

一条能力链需要十项收据

至少分别保存:客户端认证、服务授权、初始 URI、原始文档、规范集合、逐目标 opt-in、对话建立、续订 URI、逐资源通知、管理与终止删除。

上一步不能替下一步作证。2xx 不是所有资源成功,NOTIFY 不自动是完整集合,管理链接不是变更,终止也不是可观察的物理删除。

Lu Heng 的“最小初始规范”提供了明确披露的分析框架:共享合同只定义必要语义,未来变化留给拥有本地信息的参与者。RFC 5367 拒绝为后续名单正文虚构语义,正体现这种克制。

“现实层”笔记补充了证据纪律:URI、哈希、状态码、通知和计时器都是不同层的符号。必须有连接收据,才能把它们提升为更强的运行事实。协议事实仍由 RFC 与 IANA 支撑。