翻译XEP-0124: HTTP Binding(转) - Part2

原创
2014/08/25 09:04
阅读数 173

14,多个流

    14.1 介绍

本章描述的
OPTIONAL特性将使单一的HTTP session能够包含多个XMPP流。在限制客户端并发发送请求数量的环境下,该特性是必要的,因为如果客户端同时打开多个帐号,就需要多-流sessions。这个特性使得客户端在HTTP上建立平行的流时降低网络的传输量。

    14.2 展开

        如果连接管理器支持多-流特性,它在创建session响应时MUST包含'stream'属性。如果客户端没有收到'stream'属性,那么它MUST假定连接管理器不支持该特性。

        'stream'属性指定了session需要打开的第一个流。每个'stream'的值MUST是一个不透明的、不可预知的名字,在连接管理器应用中是唯一的。

        Example 30. 创建session响应,带有stream名字

 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. 请求另外一个流

 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. 客户端请求一个节被发送(所有流上)

 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. 失败的流错误

 charset=utf-8
body type='terminate'
      condition='remote-connection-failed'
      stream='secondStreamName'
      xmlns='http://jabber.org/protocol/httpbind'/>

        Note:如果在失败的绑定错误时,连接管理器不包含'stream'属性,那么session所有的流都要在接收和发送两端被关闭,session也MUST被终止。

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连接管理器按照下面的做:

  1. 如果是<presence/>节,那么丢掉节,不必要向服务器发送错误。

  2. 如果是<iq/>节,那么向服务器返回<service-unavailable/>错误。

  3. 如果是<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

展开阅读全文
打赏
0
1 收藏
分享
加载中
更多评论
打赏
0 评论
1 收藏
0
分享
返回顶部
顶部