您的位置:首页 > 其它

RFC3261(9 取消一个请求)

2012-11-04 19:25 302 查看
前边几节讲述了UA对所有方法的请求和处应答的通用处理过程。在本节中,我们讨论一个通用的方法,CANCEL。

CANCEL请求,就像名字所说的,是用来取消客户端发起的上一个请求的。特别是,它请求UAS去终止上一个请求并且对上一个请求产生一个错误的应答。CANCEL对UAS已经给出最终应答的请求无效。所以,CANCEL请求的最大用处是取消需要服务器长时间处理的请求。也就是说,CANCEL最常用来处理取消INVITE请求,因为INVITE通常需要花费很长时间来产生一个最终应答。在这种使用中,UAS接收到对一个INVITE请求的CANCEL请求,当这个INVITE还没有得到终结应答的时候,UAS会”停止振铃”,并且给INVITE请求一个错误的应答(487)。

CANCEL可以由proxy或者UAC发起。15节讲述了在何种情况下,UAC会CANCEL一个INVITE请求,在16.10节讲述了proxy对CANCEL的使用。

一个有状态的proxy需要对CANCEL进行响应,而不是简单的转发从下行流中接收到的一个应答。基于这个原因,CANCEL是一个”点对点”(hop-by-hop)的请求,也就是说,CANCEL需要每一个有状态的proxy节点进行处理和应答。

9.1 客户行为(Client Behavior)

CANCEL请求不应该取消除INVITE之外的请求。因为除了INVITE之外的请求都是立即响应的,所以,发送CANCEL来取消一个非INVITE请求总是形成一种竞态的局面(就是说,cancel先到还是被取消的请求先到)。

下列步骤用于创建一个CANCEL请求。在CANCEL请求中的Request-URI、 Call-ID、 To、Cseq的数字部、From这些头域都必须和被取消的请求头域一样,包含这些头域的tags. 客户端创建的CANCEL必须只有一个Via头域值,这个头域值和被取消的请求的最上一个Via头域值相同。这些头域的值和请求的值相同可以让CANCEL请求和被取消的请求相匹配(9.2节描述了如何匹配)。在Cseq请求头域的method部分必须是一个CANCEL方法。这个让CANCEL请求被当作自己的事务而被正确的鉴别和处理(参见17节)。

如果被取消的请求包含一个Route头域,CANCEL请求也必须包含这个Route头域的值。这个是让无状态的proxy能够正确路由CANCEL请求。

CANCEL头域绝对不能包含任何Require或者Proxy-Require头域。

一旦CANCEL请求被创建了,客户端应当检查是否收到了这个CANCEL请求取消的原始请求的任何应答(临时的或者终结的应答)。如果没有任何临时应答收到,这个CANCEL请求一定不能发送,直到客户端等到了第一个临时应答。如果原始请求已经收到一个终结应答,这个CANCEL也不应当发送,因为CANCEL请求对已经产生了终结应答的请求没有任何作用。当客户端决定发送一个CANCEL,它会为这个CANCEL创建一个客户transaction,并且通过目的地址、端口、传输层来发送CANCEL请求。这个CANCEL中的目标地址、端口和传输层必须和原始请求一样。

如果允许在接收应答之前发送CANCEL请求,那么服务端必须支持在接收原始请求之前接收到CANCEL请求。

注意,原始请求的事务和CANCEL请求的事务都是互相独立的。也就是说,UAC判定一个请求的取消不能依赖原始请求的一个487(请求终止)应答,遵循RFC2543协议,UAS不会产生这样一个应答。如果原始请求经过了64*T1(T1在17.1.1.1节定义)秒还没有应答,客户端应当认为原始请求已经取消,并且应当销毁对应原始请求的客户端事务。

9.2 服务端行为(Server Behavior)

CANCEL请求要求服务端的TU取消相关的事务(transaction)。TU根据接收到的CANCEL请求,并且假定请求的方法不是CANCEL或者ACK,并且用17.2.3节描述的事务匹配方法来匹配事务,这样TU就可以决定那个事务需要被取消了,被匹配的事务就是需要被取消的事务。

服务端对CANCEL请求的处理依赖于服务器的类型。一个无状态的proxy会转发这个请求,一个有状态的proxy可能会响应这个请求,并且自己再产生一些CANCEL请求,UAS会响应这个CANCEL请求。16.10节讲述了proxy怎样处理CANCEL请求。

当UAS收到CANCEL请求,首先按照8.2节的UAS通用处理方法进行处理。然而,因为CANCEL请求是基于”点对点”(hop-by-hop)的,不允许重复提交,他们不允许服务器为了获得Authorization头域中正确的认证而反复尝试。注意,CANCEL请求也不能包含Require头域。

如果根据上边的步骤,UAS不能找到与CANCEL请求相匹配的事务,它应该给CANCEL一个481应答(调用的Leg/Transaction不存在 对话/事务不存在)。如果对应原始请求的事务存在,那么UAS在接收到CANCEL请求的处理就依赖于是否已经给这个原始请求发出了终结应答。如果已经发出了,不会对CANCEL请求对应的原始请求做任何处理,不会更改任何会话状态,不会对原始请求的应答做任何处理。如果UAS没有发出对原始请求的终结应答,它会依赖于CANCEL所取消的原始请求方法。如果原始请求方法是INVITE,UAS应当立刻响应INVITE一个487(请求终止)。本协议中,对CANCEL取消的其他本协议中定义的方法没有约定。

不管原先请求的方法是什么,只要CANCEL匹配一个事务,UAS就响应CANCEL请求一个200(OK)应答。这个应答根据8.2.6节约定构造。注意,给CANCEL应答的To tag和给原始请求的应答的To tag应该是一样的。对CANCEL的应答会通过服务端transaction来传送。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐