题干与适用场景
WebDAV 服务允许同一资源被多个 binding 指向。客户端以 Depth infinity 发出 PROPFIND,服务器在同一个 207 Multi-Status 回应中多次遇到相同资源。请说明 208 Already Reported 的语意、何时产生、旧客户端策略,以及它与 508 Loop Detected 的差异。
题目聚焦 RFC 5842 的 WebDAV binding 扩充;208 不是一般 REST API 用来表示「资料已存在」的通用成功码。
面试官考察点
- 能否指出 208 是 207 Multi-Status 内部的 status 元素结果,而非独立 HTTP response body。
- 能否理解 binding alias、资源身份和重复列举的关系。
- 能否区分「已报告」与真正的 binding loop,并正确使用 508。
- 能否设计 Depth、客户端能力、XML 解析和日志观测。
回答前需要澄清的问题
- 服务是否支持 RFC 5842 binding 方法与
DAV:resource-id? - 客户端是否理解 208,还是只支持基本 WebDAV 207?
- PROPFIND 的 Depth 是 0、1 还是 infinity,是否有服务器上限?
- 重复来源是多个 binding、符号连结,还是实际的父子循环?
- 产品需要完整 alias 清单,还是只需每个资源回报一次?
30 秒回答框架
「208 只在 207 Multi-Status 中标记同一回应内已经报告过的资源,通常用于 WebDAV binding 造成的重复枚举。服务器先以稳定 resource-id 去重,再对第一次出现回传完整 propstat,后续同资源回传 208;若是无法安全终止的 binding loop,应回传 508。对不理解 208 的客户端,我会限制 Depth 或降级成可解析的 207,并记录去重、深度、循环和截断原因。一般 REST 的『已存在』不应使用 208。」
分步骤深入解答
1. 确认回应层级
外层 HTTP 回应通常是 207 Multi-Status;每个 response 内含资源 URI 与一个或多个 propstat。208 是其中 DAV:status 的状态行,表示该 binding 指向的资源已在同一个 Multi-Status 回应中报告,不能把整个 HTTP response status 写成 208 来取代 207。
2. 以资源身份去重
URI 不一定等于资源身份。多个 binding 可能有不同 URI 却指向同一资源;服务可用 DAV:resource-id 或内部稳定 ID 建立本次遍历的 visited set。第一次遇到资源输出完整属性,后续 binding 输出 208,仍保留该 URI 的关联,避免无限重复 XML。
PROPFIND Depth: infinity
/alias-a -> resource R: full propstat
/alias-b -> resource R: 208 Already Reported
/child -> resource C: full propstat3. 将 208 限定在适用情境
208 的价值是节省 207 内容并避免 binding 重复;它不表示资料库插入冲突、幂等重试成功或快取命中。对一般 JSON API,应选择明确的 200、201、204 或 409 语意,避免客户端看到无法理解的 WebDAV 状态。
4. 区分 508 Loop Detected
如果遍历发现 binding 关系形成循环,且不是单纯同资源的再次列举,服务器需要停止递回并使用 508 Loop Detected。208 表示资源已在本次回应中成功报告;508 表示为避免无限循环而中止处理。测试要覆盖 alias 重复、真正 cycle 和深度限制。
5. 兼容与资源上限
先协商或观测客户端对 208 的解析能力。对旧客户端可把 Depth infinity 限制为较小深度、拒绝不安全的请求,或在不破坏 WebDAV 语意的前提下返回可理解的 propstat。设定节点数、回应大小、时间和 visited set 上限,避免恶意 binding 消耗记忆体。
6. 观测与故障回复
记录 request ID、Depth、已访问资源数、208 次数、508 次数、截断原因、回应大小和客户端能力;不要记录档案内容或凭证。若去重索引故障,宁可安全截断并回传明确错误,也不要输出未终止的递回。保留可重现的 binding 图以排查资源身份错误。
高品质示范回答
「外层回应仍是 207 Multi-Status,208 只出现在其中的 propstat status,表示同一资源已在这次回应报告过。对 Depth infinity 的 PROPFIND,我用 resource-id 建立 visited set:第一个 binding 回完整属性,后续 alias 回 208;URI 仍保留,让客户端知道哪个 binding 被遍历。若关系形成真正 cycle,就停止递回并回 508。208 不应拿来表示一般 API 的已存在或重试成功。对旧客户端限制深度或拒绝高风险请求,并监测资源数、回应大小、208、508 和截断原因。」
常见错误
- 把整个 HTTP response 设成 208 → 破坏 207 Multi-Status 结构 → 208 放在相应的 propstat status。
- 用 URI 当唯一资源键 → 不同 binding 仍重复列出资源 → 用 resource-id 或稳定内部身份去重。
- 用 208 表示资料已存在 → 一般 REST 客户端语意错误 → 使用 409 或明确业务回应。
- 把所有重复都当 508 → 正常 alias 被误判成循环 → 区分已报告资源与未终止 cycle。
- 没有 Depth 和回应上限 → binding 图可耗尽记忆体 → 限制节点、时间、大小并保留 visited set。
追问及应对
208 回应还需要带 URI 吗?
需要保留该 binding 对应的 response,让客户端知道哪个 URI 已被报告;但不必重复完整属性。具体 XML 结构应符合 WebDAV Multi-Status 解析规则。
为什么不直接删除重复项?
删除会让客户端无法知道 alias 已被遍历,也可能误以为服务器漏回。208 保留遍历证据,同时避免重复 property payload。
何时应拒绝 Depth infinity?
当客户端不理解 208、binding 图超过资源上限、或无法建立可靠 visited set 时,限制深度或拒绝请求比输出不完整或无限递回更安全。