摘要

  • 支持定向字段的缓存,会按目标列表的顺序选取第一个有效且非空的字段;未把该字段列为目标的缓存不得因此改变行为。
  • 因而,即使 CDN-Cache-Control 语法完全正确,同一响应在不同缓存上仍可能被存储、拒绝存储,或由另一个优先级更高的字段支配。

设想一个明确虚构的上线场景。源站同时发送 Cache-Control: no-store 和 CDN-Cache-Control: max-age=600。第一家 CDN 识别定向字段,将响应缓存十分钟;后方的企业缓存没有把该字段列入目标,遵守 no-store;另一家 CDN 则把厂商专用字段排在目标列表首位,选择了另一套策略。监控面板却只留下一个结论:“缓存策略为 600 秒”。

响应头并没有说谎。真正丢失的是赋予这个字段含义的选择过程。

RFC 9213 把定向缓存控制字段定义为:通过独立字段名标明所针对缓存或缓存类别的响应字段。CDN-Cache-Control 是标准化实例。字段值沿用缓存指令语义,但实现该规范的缓存还维护一个有序目标列表。该列表可以固定、由运营方配置,也可以针对每次请求生成。响应中出现多个已识别字段时,缓存按列表顺序选择第一个有效、非空的字段。

这个选择会排除其他候选。缓存选中定向字段后,就用它决定该响应的缓存策略,并忽略该响应中的普通 Cache-Control 和 Expires。如果目标列表内没有任何有效且非空的字段,缓存才回退到 RFC 9111 规定的普通 HTTP 缓存机制。因此,两台合规缓存即便收到完全相同的字节,也可能因目标列表不同而作出不同决定。

作用域与优先级同样重要。不在某缓存目标列表中的定向字段,不能改变该缓存的行为,而且必须继续传递。非 CDN 缓存可以看见 CDN-Cache-Control 却不执行它。执行该字段的 CDN 通常会把它转发给下游 CDN,但 RFC 9213 也允许在不希望继续传播时删除它。某个观测点看到的字段,不能证明前后每一跳看到的字段集合完全相同。

解析结果是另一条边界。定向字段采用 Structured Fields 字典。它看起来常与普通 Cache-Control 相似,但错误处理并不相同。空值或无效字段会被忽略,从而触发回退策略。面板若只记录原始字符串而不记录解析结论,就可能把某项行为错误归因于一个缓存从未接受的字段。

新鲜度也只能相对于执行策略的缓存解释。RFC 9213 的示例允许 CDN 把响应视为 3,600 秒内新鲜,其他共享缓存只认 600 秒,其余缓存只认 60 秒。经过 1,800 秒后,同一响应对 CDN 仍然新鲜,对其他缓存却已经过期。这不是协议矛盾,而是适用策略不同。把这些状态压成一个“全链路新鲜度”,才是运营错误。

这种压缩还可能演变为安全问题。RFC 9213 提醒,多套缓存策略并存会造成混淆,甚至导致敏感信息被意外复用。源站测试成功只能证明预期字段已经发出,不能证明哪些缓存识别了它、各自选择哪个字段、解析是否成功、字段是否被移除,以及实际复用是否符合预期边界。

因此,可执行的证据单位应是逐跳缓存决策记录。针对每个关键缓存,绑定其类别和身份、有序目标列表、实际收到的字段、解析结果、被选字段、有效指令、新鲜度输入、回退路径、转发或删除动作,以及一次真实的存储或复用观测。未知跳点必须明确保留为未知。

这份记录是编辑性运营控制,并非 IETF 定义的协议对象。它的作用,是阻止一个有效字段被扩大为对整条链路的无证据断言。

来源