XCAP协议中的幂等性(idempotency)研究

阅读更多
XCAP协议中的幂等性(idempotency)研究
************************************************************************
作者:胡家辉/雨水     转载请注明出处http://blog.csdn.net/gobitan
************************************************************************
XCAP(XML Configuration Access Protocol,XML配置访问协议),也称XML配置接入协议。它是IETF制定的一个协议,前面陆续发布了一系列草案,于2007年5月正式成为RFC规范。
该协议允许客户端读、写、修改存放在服务器中的XML格式的应用配置数据。XCAP将XML文档中的节点映射到HTTP URIs中,使得这些组件能够直接通过HTTP访问。
该协议中有一个极为重要的概念—幂等性,英文为idempotency。如果读者最先没有接触过相关协议,初次遇到这个概念难免不知所云。本文结合XCAP协议对这个概念做出解释。
首先,我们来看一下XCAP协议的原文,看看协议怎么说。原文摘自RFC 4825。
7.       Client Operations
HTTP also specifies that PUT and DELETE requests are idempotent. This means that, if the client performs a PUT on a document and it succeeds, it can perform the same PUT, and the resulting document will look the same(HTTP也要求PUT和DELETE请求满足幂等性。这意味着,如果一个客户端在一个文档上执行了PUT操作,并且执行成功。那么在该文档上再次执行同样的PUT操作,操作后的文档跟操作前是一样的(即内容没有发生改变)). Similarly, when a client performs a DELETE, if it succeeds, a subsequent DELETE to the same URI will generate a 404; the resource no longer exists on the server since it was deleted by the previous DELETE operation(同样地,当客户端执行一个DELETE,如果成功了,那么接下来的具有同样URI的DELETE操作将返回404,这是因为先前的DELETE已经将该资源删除,该资源已经不存在了) . To maintain this property, the client SHOULD construct its URIs such that, after the modification has taken place, the URI in the request will point to the resource just   inserted for PUT (i.e., the body of the request), and will point to   nothing for DELETE(为了维护这个属性,客户端构造的URI应该满足:修改发生之后,请求中的URI对于PUT来说将指向刚刚插入的资源(如请求消息体),对于DELETE则指向空). If this property is maintained, it is the case that GET to the URI in the PUT will return the same content (i.e., GET(PUT(X)) == x). This property implies idempotency(如果满足该属性,那么对PUT请求中的URI执行GET操作将返回与PUT请求消息体中同样的内容(即GET(PUT(X)==X))这个属性就被称为幂等性). Although a request can still be idempotent if it does not possess this property, XCAP does not permit such requests. If the client's request does not have this property, the server will reject the request with a 409 and indicate a cannot-insert error condition.(尽管不拥有这个属性的请求也可能是幂等的,但是XCAP不允许这样的请求。如果客户的请求不具有这个属性,那么服务器将以409拒绝,并指示不能插入错误。)
   从上面协议中的描述可以看出,这里的幂等性主要与修改操作有关,即PUT和DELETE方法。对于PUT来说,就是同样的PUT操作无论执行多少次,其结果都跟第一次执行的结果相同,后面会介绍一个例子。
而对于DELETE操作来说,一次删除之后资源就不存在了。这里举一个不满足幂等性的DELETE例子,如某个DELETE操作指示删除XML文档中某个根元素下的第一个元素,如果该根元素下不只一个元素,那么显然该操作不满足幂等性。因为第一次该根元素下的第一个元素被删除了,但是第二个元素自动成为了该根元素的第一个元素,第二次执行DELETE时并不返回404,因此不满足幂等性的规定。
下面我们再看看协议中7.4节对幂等性的描述,它提到了幂等性对操作所带来的限制以及解决办法。
7.4. Create or Replace an Element
To be certain that element insertions have the GET(PUT(x))==x property, the client can check that the attribute predicates in the final path segment of the URI match the attributes of the element in the body of the request. As an example of an request that would not have this property and therefore not be idempotent, consider the following PUT request (URIs are line-folded for readability):
(为了确保元素插入满足幂等性,客户端应该检查URI路径中的属性谓词,看它是否与请求消息体中元素的属性值向匹配。一个不具有该属性的请求,它是非幂等的,来看下面的请求(URI折行是为了便于阅读))
   PUT
   /rls-services/users/sip:[email protected]/index/~~/rls-services/
   service%5b@uri=%22sip:[email protected]%22%5d
    HTTP/1.1
   Content-Type:application/xcap-el+xml
   Host: xcap.example.com
  
     http://xcap.example.com/resource-lists/users   /sip:[email protected]/index/~~/resource-lists/list%5b@name=%22l1%22%5d
  

     
      presence
    

  

This request will fail with a 409. The Request URI contains a final path segment with a predicate based on attributes -   @uri="sip:[email protected]". However, this will not match the value of the "uri" attribute in the element in the body (sip:[email protected])(请求将以409失败。该请求的URI中包含了@uri="sip:[email protected]"。然而它与请求消息体中元素的属性值sip:[email protected]不匹配).
    也就是说,上面例子中URI中属性指示的值与请求消息体中不匹配,因此不满足幂等性。下面的协议部分讲述了幂等性的局限性。
The GET(PUT(x))==x property introduces some limitations on the types   of operations possible. It will not be possible to replace an element with one that has a new value for an attribute that is the sole unique element identifier, if the URI contained a node selector which was using the previous value of that attribute for purposes of selecting the element. This is exactly the use case in the example above(GET(PUT(x))==x属性给某些操作带来了一些限制。对于用一个新的属性值去替换一个元素,而该属性是该元素的唯一标识,这操作是可能执行的。因为如果URI的节点选择符中包含了先前的属性值,那么这正好是上面例中的情况). To get around this limitation, the selection can be done by position instead of attribute value, or the parent of the element to be replaced can be selected, and then the body of the PUT operation would contain the parent, the child to be replaced, and all other siblings.
(为了解决这个限制问题,可以通过基于位置的属性值替换。或者通过选择元素的父元素替换,这样它的子元素和所有其他兄弟都将被替换。)
下面对上面协议的描述做一个解释。幂等性带来的限制就是如果该属性唯一标识该元素,那么无法用新的属性值去替换一个元素。比如下面的例子,假设XML文档中含有如下元素:
Inside the C++ Object Model
这个时候你以如下的元素来替换上面的元素将是无法办到的,即
Unix Network Programming
原因在于,你如果要替换该元素那么首先要通过id=”1234567”来把该元素标识出来,即指明你要替换这个元素。然而你的PUT请求消息体中的id却是”7654321”,这就恰恰违背了幂等性操作的约束。这就使幂等性所带来的限制。
参考文献: http://www.ietf.org/rfc/rfc4825.txt

你可能感兴趣的:(XML,应用服务器,Unix,Access,Blog)