如何强制HTTP客户端使用条件请求进行更新?

时间:2011-09-26 17:14:56

标签: http rest

在(适当的RMM级别3)RESTful HTTP API中,我想强制要求客户端在更新资源时应该发出条件请求,以避免lost update problem返回错误尝试无条件PUT请求的客户端的适当响应是什么?

我注意到(放弃?)mod_atom返回405 Method Not AllowedAllow标头设置为GET, HEADview source),当无条件更新时尝试。这似乎有点误导 - 对我而言,这意味着PUT永远不是尝试资源的有效方法。也许响应只需要有一个实体正在解释必须使用If-MatchIf-Unmodified-Since来使PUT请求成为条件,在这种情况下才允许这样做?

或许在实体主体中有适当解释的400 Bad Request可能是更好的解决方案吗?但同样,这感觉不太正确,因为当RFC 2616说(我强调)时,它会使用400响应来违反特定于应用程序的语义:

  

由于格式错误的语法,服务器无法理解该请求。

但是,我认为将400 Bad Request用于特定于应用程序的语义正在成为一种被广泛接受的实用解决方案(引用需要!),而我只是过于迂腐。

3 个答案:

答案 0 :(得分:6)

2011年9月27日Jan's request for clarification之后,2011年10月18日的HTTPbis工作组published a new Internet-Draft以全新的 428 Precondition Required 状态,专门针对在我的问题中描述的情况。

截至2012年4月,现在发布为RFC 6585(其他HTTP状态代码 - RFC 2616(HTTP / 1.1)的更新)。完整引用section 3

  

428必要条件

     

428状态代码表示原始服务器需要   请求有条件。

     

它的典型用途是避免“丢失更新”问题,其中a   客户端获取资源的状态,修改它,然后将其恢复   服务器,同时第三方已经修改了状态   服务器,导致冲突。要求提出要求   有条件的,服务器可以确保客户端正在使用   正确的副本。

     

使用此状态代码的响应应该解释如何重新提交   请求成功。例如:

HTTP/1.1 428 Precondition Required
Content-Type: text/html

<html>
   <head>
      <title>Precondition Required</title>
   </head>
   <body>
      <h1>Precondition Required</h1>
      <p>This request is required to be conditional;
      try using "If-Match".</p>
   </body>
</html>
     

428状态代码的响应绝不能由缓存存储。

在引入此新状态代码之前,Julian Reschke(HTTPbis工作组成员)had recommended使用 403 Forbidden 表示现在由428覆盖。

答案 1 :(得分:3)

据我所知,这个定义不正确。

我要求澄清:http://lists.w3.org/Archives/Public/ietf-http-wg/2011JulSep/0515.html

答案 2 :(得分:2)

如果您的协议使用无条件PUT来创建资源,那么我会将无条件PUT解释为创建而不是更新。由于资源已经存在,我将返回在这种情况下返回的任何错误。 (409冲突?)