16. 前置/后置条件XML元素 (Precondition/Postcondition XML Elements)
16. 前置/后置条件XML元素 (Precondition/Postcondition XML Elements)
如第8.7节所述,有关错误条件的额外信息可以包含在许多状态响应的主体中。本节对错误主体机制的使用提出要求,并引入了许多前置条件和后置条件代码。
方法的"前置条件 (precondition)"描述了执行该方法必须为真的服务器状态。方法的"后置条件 (postcondition)"描述了该方法完成后必须为真的服务器状态。
每个前置条件和后置条件都有一个与之关联的唯一XML元素。在207 Multi-Status响应中,XML元素必须出现在适当的'propstat或'response'元素中的'error'元素内,这取决于条件是应用于一个或多个属性还是应用于资源作为整体。在使用本规范的'error'主体的所有其他错误响应中,前置条件/后置条件XML元素必须作为响应主体中顶级'error'元素的子元素返回(除非请求另有协商),以及适当的响应状态。最常见的响应状态码是403(Forbidden),如果请求不应重复,因为它总是会失败;以及409(Conflict),如果预期用户可能能够解决冲突并重新提交请求。'error'元素可以包含具有特定错误信息的子元素,并且可以使用任何自定义子元素进行扩展。
此机制不能代替使用此处或HTTP中定义的正确数字状态码,因为客户端必须始终能够仅基于数字代码采取合理的操作方案。但是,它确实消除了定义新数字代码的需要。用于此目的的新机器可读代码是分类为前置条件和后置条件的XML元素,因此自然地,任何定义新条件代码的组都可以使用自己的命名空间。与往常一样,"DAV:"命名空间保留供IETF特许的WebDAV工作组使用。
支持本规范的服务器应该在违反本文档中定义的前置条件或后置条件时使用XML错误。对于本文档中未指定的错误条件,服务器可以简单地选择适当的数字状态并将响应主体留空。但是,服务器可以使用自定义条件代码和其他支持文本,因为即使客户端不自动识别条件代码,它们在互操作性测试和调试中也可能非常有用。
示例 - 带有前置条件代码的响应 (Example - Response with precondition code):
HTTP/1.1 423 Locked
Content-Type: application/xml; charset="utf-8"
Content-Length: xxxx
<?xml version="1.0" encoding="utf-8" ?>
<D:error xmlns:D="DAV:">
<D:lock-token-submitted>
<D:href>/workspace/webdav/<D:href>
<D:lock-token-submitted>
<D:error>
在此示例中,不知道父集合"/workspace/webdav/"上的深度无限锁的客户端尝试修改集合成员"/workspace/webdav/proposal.doc"。
在其他扩展WebDAV的规范中已定义了一些其他有用的前置条件和后置条件,例如RFC3744、[RFC3253]和[RFC3648]。
所有这些元素都在"DAV:"命名空间中。除非另有说明,否则每个条件的XML元素的内容定义为空。
lock-token-matches-request-uri
名称 (Name): lock-token-matches-request-uri
使用 (Use with): 409 Conflict
目的 (Purpose): (前置条件) -- 请求可以包含Lock-Token头来标识UNLOCK方法的锁。但是,如果Request-URI不在令牌标识的锁的范围内,服务器应该使用此错误。锁的范围可能不包括Request-URI,或者锁可能已消失,或者令牌可能无效。
lock-token-submitted
名称 (Name): lock-token-submitted (前置条件)
使用 (Use with): 423 Locked
目的 (Purpose): 请求无法成功,因为应该提交锁令牌。如果存在,此元素必须包含至少一个阻止请求的锁定资源的URL。在涉及集合锁的MOVE、COPY和DELETE的情况下,客户端可能很难找出哪个锁定资源导致请求失败 -- 但服务器只负责返回一个这样的锁定资源。如果服务器知道所有阻止请求成功的锁定资源,则可以返回它们。
<!ELEMENT lock-token-submitted (href+) >
no-conflicting-lock
名称 (Name): no-conflicting-lock (前置条件)
使用 (Use with): 通常为423 Locked
目的 (Purpose): 由于存在已经存在的冲突锁,LOCK请求失败。请注意,即使请求所针对的资源仅被间接锁定,锁也可能存在冲突。在这种情况下,前置条件代码可用于通知客户端作为冲突锁根的资源,避免单独查找"lockdiscovery"属性。
<!ELEMENT no-conflicting-lock (href)* >
no-external-entities
名称 (Name): no-external-entities
使用 (Use with): 403 Forbidden
目的 (Purpose): (前置条件) -- 如果服务器因为请求主体包含外部实体而拒绝客户端请求,服务器应该使用此错误。
preserved-live-properties
名称 (Name): preserved-live-properties
使用 (Use with): 409 Conflict
目的 (Purpose): (后置条件) -- 服务器收到了原本有效的MOVE或COPY请求,但无法在目标位置维护具有相同行为的活属性。可能是服务器仅在存储库的某些部分支持某些活属性,或者只是有内部错误。
propfind-finite-depth
名称 (Name): propfind-finite-depth
使用 (Use with): 403 Forbidden
目的 (Purpose): (前置条件) -- 此服务器不允许对集合的无限深度PROPFIND请求。
cannot-modify-protected-property
名称 (Name): cannot-modify-protected-property
使用 (Use with): 403 Forbidden
目的 (Purpose): (前置条件) -- 客户端尝试在PROPPATCH中设置受保护的属性(例如DAV:getetag)。另请参见[RFC3253],第3.12节。