14,多个流
14.1 介绍
本章描述的OPTIONAL特性将使单一的HTTP session可以包含多个XMPP流。在限制客户端并发发送请求数量的环境下,该特性是必要的,由于若是客户端同时打开多个账号,就须要多-流sessions。这个特性使得客户端在HTTP上创建平行的流时下降网络的传输量。
14.2 展开
若是链接管理器支持多-流特性,它在建立session响应时MUST包含'stream'属性。若是客户端没有收到'stream'属性,那么它MUST假定链接管理器不支持该特性。
'stream'属性指定了session须要打开的第一个流。每一个'stream'的值MUST是一个不透明的、不可预知的名字,在链接管理器应用中是惟一的。
Example 30. 建立session响应,带有stream名字
html
charset=utf-8
body authid='ServerStreamID'
wait='60'
inactivity='30'
polling='5'
requests='2'
accept='deflate,gzip'
sid='SomeSID'
secure='true'
stream='firstStreamName'
charsets='ISO_8859-1 ISO-2022-JP'
xmlns='http://jabber.org/protocol/httpbind'/>
14.3 对一个Session新增流
若是链接管理器在建立session响应时包含了'stream'属性,那么客户端能够发送一个带有'to'属性的空<body/>元素来请求链接管理器打开另一个流。该请求MUST包含有效的'sid'和'rid'属性,它SHOULD包含'xml:lang'属性。请求MAY包含'route'和'secure'属性,但SHOULD NOT包含'content','hold'或者'wait'属性。
Example 31. 请求另一个流
java
charset=utf-8
body sid='SomeSID'
rid='1573741820'
to='jabber.org'
route='xmpp:jabber.org:9999'
secure='true'
xml:lang='en'
xmlns='http://jabber.org/protocol/httpbind'/>
若是链接管理器在session开始时没有指定它支持多流,那么它MUST忽略额外的属性,只当其是一个普通的空请求(参考发送和接收XML节)。不然,它MUST对服务器打开一个新的流(参考建立session),生成一个新的流名字并响应给客户端。响应MAY包含'authid'和'secure'属性,可是它SHOULD NOT包含'sid', 'requests', 'polling', 'inactivity', 'accept', 'charsets' 或者 'wait'属性。
Example 32. 新增流的响应
安全
charset=utf-8
body stream='secondStreamName'
authid='ServerStreamID'
secure='true'
xmlns='http://jabber.org/protocol/httpbind'/>
Note:若是响应没有'authid'属性,那么其余属性MUST由以后的响应发送(参考建立session),'stream'属性也要被指定。
14.4 节的传输
若是一个session打开的流数目大于一个,那么链接管理器发送的全部非空<body>元素MUST包含‘stream’以指出它发送的节是属于哪一个流的。相同的缘由,客户端也SHOULD包含‘stream’属性。客户端MAY忽略‘stream’属性使链接管理器在全部打开的流上发送节。Note:一个<body/>元素MUST NOT含有针对不一样流的不一样节。
若是流的名字没有与session打开的流的某个名字相同,那么接收流的链接管理器SHOULD返回一个HTTP 404错误,或者接收流的客户端SHOULD终止session。若是接收者仅仅是关闭流(发送者在发送节的时候不可能注意到这状况),那么接受者只要简单的忽略<body/>元素包含的节就能够了。
Note:不包含'authid'属性的<body/>元素SHOULD NOT包含'stream'属性(由于没有任何信息要在流中传输)。若是这样的一个<body/>元素包含了'stream'属性,那么接收者SHOULD忽略该属性。
Example 33. 客户端发送的节,带有流的名字
服务器
charset=utf-8
body rid='1249243562'
sid='SomeSID'
stream='secondStreamName'
xmlns='http://jabber.org/protocol/httpbind'>
<message to='contact@example.com'
xmlns='jabber:client'>
<body>Hi there!</body>
</message>
</body>
Note:响应的‘stream’属性的值MAY与对应请求的值不一样。
Example 34. 链接管理器以不一样的流名字响应
网络
charset=utf-8
body stream='firstStreamName'
xmlns='http://jabber.org/protocol/httpbind'>
<message from='contact@example.com'
to='user@example.com'
xmlns='jabber:client'>
<body>Hi yourself!</body>
</message>
</body>
若是链接管理器没有指定流的名字,那么客户端MUST假定收到的节是与第一个流名字有关的信息(甚至在第一个流被关闭了也这样认为)。
若是客户端没有指定流的名字,那么链接管理器MUST在全部打开的流上发送节。
Example 35. 客户端请求一个节被发送(全部流上)
session
charset=utf-8
body rid='1249243562'
sid='SomeSID'
xmlns='http://jabber.org/protocol/httpbind'>
<presence xmlns='jabber:client'>
<show>away</show>
</presence>
</body>
14.5 关闭一个流
若是一个session打开了多个流,客户端MAY在任什么时候候使用由终止HTTP Session中描述的方法关闭一个打开的流,要由‘stream’属性指定一个流名字。若是客户端关闭了最后一个流,链接管理器MUST终止session。若是客户端没有指定流名字,那么链接管理器MUST关闭全部打开的流(全部流发送终止请求),而且终止session。
Example 36. 客户端关闭一个流
并发
charset=utf-8
body rid='1249243564'
sid='SomeSID'
stream='secondStreamName'
type='terminate'
xmlns='http://jabber.org/protocol/httpbind'>
<presence type='unavailable'
xmlns='jabber:client'/>
</body>
14.6 错误情形
若是一个session打开多个流,在失败的绑定错误中(参考终止绑定状况)链接管理器MAY包含‘stream’属性。若是‘stream’属性设置了,那么接收和发送端都MUST关闭流,可是session SHOULD NOT被终止。
Example 37. 失败的流错误
app
charset=utf-8
body type='terminate'
condition='remote-connection-failed'
stream='secondStreamName'
xmlns='http://jabber.org/protocol/httpbind'/>
Note:若是在失败的绑定错误时,链接管理器不包含'stream'属性,那么session全部的流都要在接收和发送两端被关闭,session也MUST被终止。post
15,错误和状态码加密
在HTTP响应中有4种错误和状态
表1:错误类型
Condition Type Description
HTTP Conditions 链接管理器对无效的客户端请求返回一个标准的HTTP error响应。无效的请求包括绑定语法错误,可能的攻击等。注意,受限制的客户端不能区别HTTP errors的区别。
Terminal Binding Conditions 这类错误可能由受限制的客户端读取到。用于链接管理器产生的问题,流问题以及链接管理器与XMPP服务器联络的问题。
Recoverable Binding Conditions 用于在链接管理器和客户端之间联络的问题。这种状况不须要终止session。客户端只要经过从新发送以前没有被响应的<body/>元素就能够恢复正常。
XMPP Stanza Conditions XMPP错误是与<body/>元素中XML节相关的,通常来讲,由RFC或者XEP给出相应的情形。这种状况不须要终止session。(上面jabber:iq:auth给出了这样的一个例子。)
详细描述由下面提供
15.1 HTTP情况
下面给出的错误和状态码在本协议中有特别的意义(其余错误和状态码仍是其自己的意义)。在收到HTTP 错误(400,403,404)时,HTTP客户端MUST认为HTTP session是空的。
Note:这些HTTP码都是在HTTP规范中定义的。在使用Jabber协议时,不要与传统的HTTP错误相混淆。
表2:HTTP错误和状态码
Code Name Purpose
200 OK 客户端请求的有效响应。
400 Bad Request 通知客户端HTTP头和绑定元素的格式是不被接受的。(好比,语法错误).
403 Forbidden 通知客户端它的请求不符合session的规则。(好比,请求太频繁,太多的并发链接)。
404 Not Found 通知客户端:(1) 'sid'是无效的, (2) 'stream'是无效的, (3) 'rid'值超过了但愿的窗口数, (4) 链接管理器不能从新发送响应,(5) 'key'序列无效。
15.2 终止绑定状况
对于任意发送给客户端的响应,链接管理器MAY经过设置<body/>元素的属性‘type’值为‘terminate’来返回一个失败错误。这个错误暗示HTTP session被终止了(除非指定了‘stream’属性,参考多个流-错误情形)。(这种错误大多数也意味着RFC 3920定义的XMPP流错误,不过实际上在链接管理器与服务器之间的XMPP流错误是一个“remote-stream-error”,在下面有描述)。
Example 38. 远端链接失败的错误
charset=utf-8
body type='terminate'
condition='remote-connection-failed'
xmlns='http://jabber.org/protocol/httpbind'/>
属性‘condition’值的定义以下。
表3:绑定错误情形
Condition Purpose
host-gone 属性‘to’指定的目标域或者属性‘route’指定的主机或者端口不在提供服务了。
host-unknown 链接管理器没法获知属性‘to’指定的目标域或者属性‘route’指定的主机或者端口。
improper-addressing 初始化元素缺乏‘to’或者‘route’属性(或者属性没值),可是链接管理器须要其中之一。
internal-server-error 链接管理器收到一个内部错误,阻止其响应请求。
other-request 在请求终止session的时候,另外一个请求正在被处理。
remote-connection-failed 链接管理器对XMPP服务器不可以链接、不能安全的链接、或者失去链接。
remote-stream-error 压缩一个XMPP流出错。流内容是一个从XMPP服务器接收到的<stream:error/>元素。
see-other-uri 在一个URI上(好比,链接管理器仅接收客户端在一些https:URI上的SSL或者TLS链接,而不支持在http:URI上的),链接管理器不能进行操做。客户端能够在<uri/>子元素的内容中post内容。
system-shutdown 链接管理器即将关闭。全部活动的sessions都要被终止。不能建立新的sessions。
undefined-condition 未在此定义的错误。链接管理器SHOULD在<body/>元素内容中包含一个应用程序指定的信息。
下面是一个"see-other-uri" 情形的例子:
Example 39. see-other-uri的错误
charset=utf-8
body condition='see-other-uri'
type='terminate'
xmlns='http://jabber.org/protocol/httpbind'>
<uri>https://secure.jabber.org/xmppcm</uri>
</body>
下面是一个"remote-stream-error"情形的例子:
Example 40. 远端错误
charset=utf-8
body condition='remote-stream-error'
type='terminate'
xmlns='http://jabber.org/protocol/httpbind'>
<xml-not-well-formed xmlns='urn:ietf:params:xml:ns:xmpp-streams'/>
<text xmlns='urn:ietf:params:xml:ns:xmpp-streams'
xml:lang='en'>
Some special application diagnostic information!
</text>
<escape-your-data xmlns='application-ns'/>
</body>
固然,客户端也MAY通知链接管理器绑定错误,尽管这未必会有。
15.3 可恢复绑定状况
对于任意发送给客户端的响应,链接管理器MAY经过设置<body/>元素中属性'type'值为'error'来发送一个可恢复的错误。这种错误并不指session已经终止了。
若是决定从错误中恢复,那么客户端MUST重复发送HTTP请求以及以前全部没有收到响应的HTTP请求。这些请求的内容MUST与以前请求的<body/>元素内容相同。这就容许链接管理器因为联络失败而错过以前请求之后,能够恢复。
Example 41. 可恢复的错误
charset=utf-8
body type='error'
xmlns='http://jabber.org/protocol/httpbind'/>
15.4 XMPP节的状况
应用级别的错误一般是由第3方产生的而且由链接管理器传递到客户端,所以他们就超出了这里定义的范围,他们在RFC或者XEP中有更详细的描述。
然而,链接管理器有可能收到一个须要发送到客户端的节,可是客户端的链接已经不在激活状态(好比在链接管理器要通知服务器该链接不在激活以前)。在此时,链接管理器要向服务器发送一个错误。因为这种状况与RFC 3920 11.1章定义的相似,所以RECOMMENDED链接管理器按照下面的作:
若是是<presence/>节,那么丢掉节,没必要要向服务器发送错误。
若是是<iq/>节,那么向服务器返回<service-unavailable/>错误。
若是是<message/>节,那么向服务器返回<recipient-unavailable/>错误。
当服务器从链接管理器处收到一个带有<recipient-unavailable/>错误的<message/节>时,它SHOULD保存这些信息(不在线状态下容许发送消息),而不仅是单单的将错误节传输给它。
16,实施备忘录
这里想象的只是将这个协议的实现做为XMPP服务器的一个链接管理器,也可能实现一个没有XMPP实现的链接管理。并且,它也能够简单的扮演处理XML结构的角色。所以在这定义的XML schemas不只仅是针对XMPP服务器端的,使用链接管理器的应用程序应有责任处理这些错误,而不是链接管理器。
17,安全考虑
联络SHOULD在一个加密的HTTP链接上进行。客户端和链接管理器直接的加密协商SHOULD在传输层或HTTP层进行。这个协商SHOULD遵循SSL定义的HTTP/SSL协议,它MAY遵循RFC 2818定义的HTTP/TLS协议或者RFC 2817定义的HTTP协议中的TLS。
若是发送初始化session请求的链接是加密的,那么这个session的全部链接SHOULD都是加密的。若是验证检定在创建加密的链接(用来发送初始化session请求)中互换,客户端和/或链接管理器SHOULD确保相同的验证检定在session之后用到的链接中也被使用。一旦这样一个‘安全的session’创建好:
若是链接管理器拒绝创建一个加密的链接或者提供不一样检定,那么客户端SHOULD关闭链接和终止session,无需发送其余请求。
若是客户端在链接(没有加密或者检定不一样)中发送一个封装好的元素(是安全的session中的一部分),那么链接管理器SHOULD只要关闭链接,而SHOULD NOT终止session,由于这样已经能够帮助拒绝攻击了。
SID和RID是重要的安全因素,因此它们MUST是不可预知和不重复的(参考RFC 1750针对产生随机sid和rid的建议)。
当链接管理器独立于XMPP服务器做为一个代理时,它又有其余的安全漏洞。RECOMMENDED是:客户端经过加密确保发送的节的安全性(参考xep0116-加密的session)。
18,IANA考虑
参考IANA(The Internet Assigned Numbers Authority)
19,XMPP登记考虑
19.1 协议命名空间
参考XMPP登录xep-0053
20,XML Schema
结束!这里是原文档。
原文转自:http://www.blogjava.net/howard/archive/2006/12/04/85309.html