开发者

How to enforce that HTTP client uses conditional requests for updates?

In a (proper RMM level 3) RESTful HTTP API, I want to enforce the fact that clients should make conditional requests when updating resources, in order to avoid the lost update problem. What would be an appropriate response to return to clients that incorrectly attempt unconditional PUT requests?

I note that the (abandoned?) mod_atom returns a 405 Method Not Allowed with an Allow header set to GET, HEAD (view source) when an unconditional update is attempted. This seems slightly misleading - to me this implies that PUT is never a valid method to attempt on the resource. Perhaps the response just needs to have an entity body explaining that If-Match or If-Unmodified-Since must be used to make the PUT request conditional in which case it would be allowed?

Or perhaps a 400 Bad Request with a suitable explanation in the entity body would be a better solu开发者_如何学编程tion? But again, this doesn't feel quite right because it's using a 400 response for a violation of application specific semantics when RFC 2616 says (my emphasis):

The request could not be understood by the server due to malformed syntax.

But than again, I think that using 400 Bad Request for application specific semantics is becoming a widely accepted pragmatic solution (citation needed!), and I'm just being overly pedantic.


Following Jan's request for clarification on 27th September 2011, the HTTPbis working group published a new Internet-Draft on 18th October 2011, with the brand new 428 Precondition Required status, specifically to address the situation described in my question.

As of April 2012, this is now published as RFC 6585 (Additional HTTP Status Codes - an update of RFC 2616 (HTTP/1.1)). Full quote of section 3:

428 Precondition Required

The 428 status code indicates that the origin server requires the request to be conditional.

Its typical use is to avoid the "lost update" problem, where a client GETs a resource's state, modifies it, and PUTs it back to the server, when meanwhile a third party has modified the state on the server, leading to a conflict. By requiring requests to be conditional, the server can assure that clients are working with the correct copies.

Responses using this status code SHOULD explain how to resubmit the request successfully. For example:

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>

Responses with the 428 status code MUST NOT be stored by a cache.

Prior to the introduction of this new status code, Julian Reschke (a member of the HTTPbis working group) had recommended using a 403 Forbidden for the situation that is now covered by 428.


To my best knowledge, this is not properly defined.

I requested clarification: http://lists.w3.org/Archives/Public/ietf-http-wg/2011JulSep/0515.html


If your protocol uses unconditional PUTs for creating resources, then I would interpret the unconditional PUT as a create, not an update. Since the resource already exists, I'd return whatever error you return in that case. (409 Conflict?)

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜