8. General Request and Response Handling (通用请求和响应处理)
8. General Request and Response Handling (通用请求和响应处理)
8.1 Precedence in Error Handling (错误处理的优先级)
服务器必须优先返回授权错误而不是其他错误。这可以避免泄露有关受保护资源的信息 (例如, 客户端通过看到对资源的匿名请求的 423 Locked 响应而发现隐藏资源的存在)。
8.2 Use of XML (XML 的使用)
在 HTTP/1.1 中, 方法参数信息专门在 HTTP 头中编码。与 HTTP/1.1 不同, WebDAV 在 XML ([REC-XML]) 请求实体主体或 HTTP 头中编码方法参数信息。使用 XML 编码方法参数的动机是能够向现有结构添加额外的 XML 元素, 提供可扩展性; 以及 XML 在 ISO 10646 字符集中编码信息的能力, 提供国际化支持。
除了编码方法参数外, WebDAV 中还使用 XML 来编码来自方法的响应, 为方法输出和输入提供 XML 的可扩展性和国际化优势。
当 XML 用于请求或响应主体时, Content-Type 类型应该是 application/xml。实现必须在请求和响应主体中接受 text/xml 和 application/xml。不推荐使用 text/xml。
所有符合 DAV 的客户端和资源必须使用符合 [REC-XML] 和 [REC-XML-NAMES] 的 XML 解析器。请求或响应中使用的所有 XML 必须至少是格式良好的, 并正确使用命名空间。如果服务器接收到格式不良的 XML, 则服务器必须使用 400 (Bad Request) 拒绝整个请求。如果客户端在响应中接收到格式不良的 XML, 则客户端绝对不能假设已执行方法的结果, 并且应该将服务器视为故障。
请注意, 处理由不受信任的源提交的 XML 可能会导致与隐私, 安全性和服务质量相关的风险 (参见第 20 节)。服务器可以拒绝可疑的请求 (即使它们由格式良好的 XML 组成), 例如, 使用 400 (Bad Request) 状态码和解释问题的可选响应主体。
8.3 URL Handling (URL 处理)
URL 在请求和响应中的许多地方出现。与 [RFC2518] 的互操作性经验表明, 许多解析 Multi-Status 响应的客户端未完全实现 [RFC3986] 第 5 节中定义的完整引用解析。因此, 特别是服务器在响应中处理 URL 时需要小心, 以确保客户端有足够的上下文来解释所有 URL。本节中的规则不仅适用于 Multi-Status 响应中 'href' 元素中的资源 URL, 还适用于 Destination 和 If 头资源 URL。
发送者可以在两种方法之间进行选择: 使用相对引用 (根据 Request-URI 解析) 或完整 URI。服务器必须确保 Multi-Status 响应中的每个 'href' 值使用相同的格式。
WebDAV 在其扩展中仅使用一种相对引用形式, 即绝对路径。
Simple-ref = absolute-URI | ( path-absolute [ "?" query ] )
absolute-URI, path-absolute 和 query 产生式在 [RFC3986] 的第 4.3, 3.3 和 3.4 节中定义。
在 Simple-ref 产生式中, 发送者绝对不能:
- 使用点段 ("." 或 ".."), 或
- 具有与 Request-URI 不匹配的前缀 (使用 [RFC2616] 第 3.2.3 节中定义的比较规则)。
集合的标识符应该以 '/' 字符结尾。
8.3.1 示例 - 正确的 URL 处理
考虑集合 http://example.com/sample/ 与内部成员 URL http://example.com/sample/a%20test 以及下面的 PROPFIND 请求:
请求:
PROPFIND /sample/ HTTP/1.1
Host: example.com
Depth: 1
在这种情况下, 服务器应该返回包含以下内容的两个 'href' 元素
http://example.com/sample/和http://example.com/sample/a%20test, 或/sample/和/sample/a%20test
请注意, 即使服务器可能在内部将成员资源存储为 'a test', 但在 URI 引用中使用时也必须进行百分比编码 (参见 [RFC3986] 的第 2.1 节)。另请注意, 合法的 URI 可能仍包含需要在 XML 字符数据中转义的字符, 例如 & 符号字符。
8.4 Required Bodies in Requests (请求中的必需主体)
这些新方法中的一些不定义主体。服务器必须检查所有请求的主体, 即使没有预期主体。在存在请求主体但服务器会忽略的情况下, 服务器必须使用 415 (Unsupported Media Type) 拒绝请求。这通知客户端 (可能一直在尝试使用扩展) 主体无法按客户端的意图进行处理。
8.5 HTTP Headers for Use in WebDAV (WebDAV 中使用的 HTTP 头)
HTTP 定义了许多可以在 WebDAV 请求和响应中使用的头。并非所有这些都适合所有情况, 某些交互可能未定义。请注意, HTTP 1.1 要求在所有响应中尽可能使用 Date 头 (参见 [RFC2616] 第 14.18 节)。
服务器必须在检查任何 HTTP 条件头之前进行授权检查。
8.6 ETag
HTTP 1.1 建议使用 ETags 而不是修改日期来进行缓存控制, 并且有更强的理由在创作中首选 ETags。在分布式创作环境中, ETag 的正确使用更为重要, 因为 ETags 与锁一起是避免丢失更新问题所必需的。例如, 当锁超时且客户端意外离线或正在进行长时间上传时, 客户端可能无法续订锁。当客户端无法续订锁时, 只要在此期间没有进行任何更改, 资源很可能仍然可以重新锁定, 用户可以继续编辑。客户端需要 ETags 才能区分这种情况。否则, 客户端被迫询问用户是否覆盖服务器上的资源, 而无法告诉用户它是否已更改。时间戳在解决此问题方面不如 ETags 有效。
强 ETags 对于创作用例比弱 ETags 更有用 (参见 [RFC2616] 的第 13.3.3 节)。语义等价性可能是一个有用的概念, 但这取决于文档类型和应用程序类型, 互操作性可能需要一些超出本规范和 HTTP 范围的协议或标准。另请注意, 弱 ETags 在 HTTP 中有某些限制, 例如, 这些不能在 If-Match 头中使用。
请注意, PUT 响应中 ETag 的含义在本文档或 RFC 2616 中都没有明确定义 (即, ETag 是否意味着资源在字节上等同于 PUT 请求的主体, 或者服务器是否可以在存储时对文档的格式或内容进行细微更改)。这是一个 HTTP 问题, 而不仅仅是 WebDAV 问题。
由于如果 ETag 更改, 客户端可能被迫提示用户或丢弃更改的内容, 因此 WebDAV 服务器不应该为具有未更改主体和位置的资源更改 ETag (或 Last-Modified 时间)。ETag 表示资源主体或内容的状态。没有类似的方法来判断属性是否已更改。
8.7 Including Error Response Bodies (包含错误响应主体)
在 WebDAV 版本控制扩展规范引入一种机制来在错误响应主体中包含更具体的信息之前, HTTP 和 WebDAV 并未将大多数错误响应的主体用于机器可解析的信息 ([RFC3253] 第 1.6 节)。错误主体机制适用于任何可能采用主体但尚未定义主体的错误响应。当状态码可能意味着许多事情时, 该机制特别合适 (例如, 400 Bad Request 可能意味着缺少必需的头, 头格式不正确等等)。此错误主体机制在第 16 节中介绍。
8.8 Impact of Namespace Operations on Cache Validators (命名空间操作对缓存验证器的影响)
请注意, HTTP 响应头 "Etag" 和 "Last-Modified" (参见 [RFC2616] 第 14.19 和 14.29 节) 是按 URL (而非按资源) 定义的, 并由客户端用于缓存。因此, 服务器必须确保执行影响 URL 命名空间的任何操作 (例如 COPY, MOVE, DELETE, PUT 或 MKCOL) 确实保留其语义, 特别是:
- 对于任何给定的 URL, "Last-Modified" 值必须在 GET 返回的表示每次更改时递增 (在时间戳分辨率的限制内)。
- 对于任何给定的 URL, "ETag" 值绝对不能被重新用于 GET 返回的不同表示。
在实践中, 这意味着服务器
- 可能必须为命名空间操作的目标命名空间内的每个资源增加 "Last-Modified" 时间戳, 除非它可以更有选择地这样做, 以及
- 类似地, 可能必须为这些资源重新分配 "ETag" 值 (除非服务器以确保它们在服务器管理的整个 URL 命名空间中唯一的方式分配实体标签)。
请注意, 这些考虑因素也适用于特定用例, 例如使用 PUT 在以前已映射但此后已删除的 URL 处创建新资源。