翻譯XEP-0124: HTTP Binding(轉) - Part2

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

  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

相關文章
相關標籤/搜索