XEP-0124

来自Jabber/XMPP中文翻译计划
(版本间的差异)
跳转到: 导航, 搜索
(BOSH技术)
(发送和接收XML载荷)
 
(未显示2个用户的58个中间版本)
第1行: 第1行:
 
[[Category:XMPP扩展]]
 
[[Category:XMPP扩展]]
[[Category:翻译中]]
+
[[Category:已翻译]]
  
 
'''本文的英文原文来自[http://www.xmpp.org/extensions/xep-0124.html XEP-0124]'''
 
'''本文的英文原文来自[http://www.xmpp.org/extensions/xep-0124.html XEP-0124]'''
第14行: 第14行:
 
|-
 
|-
 
!版权:
 
!版权:
|© 1999 - 2011 XMPP标准化基金会(XSF). 参见[[XEP-0124#法律通告|法律通告]].
+
|© 1999 - 2011 XMPP标准化基金会(XSF). 参见[[XEP-0124#附录C:法律通告|法律通告]].
 
|-
 
|-
 
!状态:
 
!状态:
第101行: 第101行:
 
如果在一个规定时间内(通常是几分钟)两个方向上都没有流量, 那么连接管理器以无数据来应答客户端, 并且那个应答立即触发一个新的客户端请求. 连接管理器这么做来确认是否网络连接已经中断,并且双方都在一个合理的时间内明白到这一点. 这一交换类似大部分持久TCP连接中的通用的 "keep-alive" 或 "ping" . 因为BOSH技术未使用轮询, 带宽消耗不会比标准TCP连接大很多. [[XEP-0124#附录G:备注|13]]
 
如果在一个规定时间内(通常是几分钟)两个方向上都没有流量, 那么连接管理器以无数据来应答客户端, 并且那个应答立即触发一个新的客户端请求. 连接管理器这么做来确认是否网络连接已经中断,并且双方都在一个合理的时间内明白到这一点. 这一交换类似大部分持久TCP连接中的通用的 "keep-alive" 或 "ping" . 因为BOSH技术未使用轮询, 带宽消耗不会比标准TCP连接大很多. [[XEP-0124#附录G:备注|13]]
  
Most of the time data can be pushed immediately. However, if one of the endpoints has just pushed some data then it will usually have to wait for a network round trip until it is able to push again. If HTTP Pipelining is available to the client then multiple concurrent requests are possible. Thus the client can always push data immediately. It can also ensure the connection manager is always holding enough requests such that even during bursts of activity it will never have to wait before pushing data. Furthermore, if the pool of requests being held by the connection manager is large enough, then the client will not be under pressure to send a new empty request immediately after receiving data from the connection manager. It can instead wait until it needs to send data. Therefore, if over time the traffic to and from the client is balanced, bandwidth consumption will be about the same as if a standard TCP connection were being used.
+
大部分时候数据可以被立刻推送. 无论如何, 如果其中一个端点刚推送了一些数据,在它再次推送之前将不得不等待网络往返. 如果客户端可以使用HTTP流水线,那么就可以拥有多个并发的请求了. 这样客户端就总能立刻推送数据了. 它也能保证连接管理器总是持有足够的请求,这样甚至在连续发送的时候它也绝不需要在发送数据之前等待. 此外, 如果连接管理器持有的请求池太大, 那么客户端从连接管理器接收数据之后在压力之下将不能立刻发送一个新的空请求. 它只能等待,除非需要发送数据. 所以, 如果随着时间的推移,客户端接收和发出的流量平衡了, 带宽消耗将和使用标准的TCP连接相同.
  
Each block of data pushed by the connection manager is a complete HTTP response. So, unlike the Comet technique, the BOSH technique works through intermediate proxies that buffer partial HTTP responses. It is also fully compliant with HTTP/1.0 -- which does not provide for chunked transfer encoding.
+
连接管理器推送的每一个数据块都是一个完整的HTTP应答. 所以, 和Comet技术不像, BOSH技术是通过中间代理缓冲部分HTTP请求来工作的. 它也完全兼容HTTP/1.0 -- 不提供分块传输编码.
  
==HTTP Overview==
+
==HTTP概述==
  
All information is encoded in the body of standard HTTP POST requests and responses. Each HTTP body contains a single <body/> wrapper which encapsulates the XML elements being transferred (see <body/> Wrapper Element).
+
所有信息被编码到标准的HTTP POST请求和应答的body中. 每个HTTP body包含一个单独的 <body/> 封装器用来封装被传输的XML元素 (见 [[XEP-0124#<body/>封装器元素]] ).
  
Clients SHOULD send all HTTP requests over a single persistent HTTP/1.1 connection using HTTP Pipelining. However, a client MAY deliver its POST requests in any way permitted by RFC 1945 or RFC 2616. For example, constrained clients can be expected to open more than one persistent connection instead of using Pipelining, or in some cases to open a new HTTP/1.0 connection to send each request. However, clients and connection managers SHOULD NOT use Chunked Transfer Coding, since intermediaries might buffer each partial HTTP request or response and only forward the full request or response once it is available.
+
客户端应该使用HTTP流水线通过一个持久的HTTP/1.1连接发送所有的HTTP请求. 不过, 客户端也可以用任何 '''RFC 1945''' 或 '''RFC 2616''' 允许的方式递送这些POST请求. 例如, 受约束的客户端可能期望打开不止多个持久连接而不是使用HTTP流水线, 或者在某些情况下打开一个新的HTTP/1.0连接来发送每个请求. 无论如何, 客户端和连接管理器不应该使用分块传输编码, 因为中间代理可能缓冲每部分的HTTP请求或应答并且在可以发送的时候只传输完整的请求或应答.
  
Clients MAY include an HTTP Accept-Encoding header in any request. If the connection manager receives a request with an Accept-Encoding header, it MAY include an HTTP Content-Encoding header in the response (indicating one of the encodings specified in the request) and compress the response body accordingly.
+
客户端可以在任何请求中包含一个HTTP Accept-Encoding头. 如果连接管理器接收到一个拥有Accept-Encoding头的请求, 它可以在应答中包含一个HTTP Content-Encoding头 (指定请求中说明的编码之一) 并据此压缩应答body.
  
Requests and responses MAY include HTTP headers not specified herein. The receiver SHOULD ignore any such headers.
+
请求和应答可以包含未在本文提到的HTTP头. 接收者应该忽略那些HTTP头.
  
Each BOSH session MAY share the HTTP connection(s) it uses with other HTTP traffic, including other BOSH sessions and HTTP requests and responses completely unrelated to this protocol (e.g., web page downloads). However, the responses to requests that are not part of the session sent over the same connection using HTTP pipelining (or queued to be sent over the same connection) might be delayed if they were sent while a request that is part of the session is being held (since the connection manager MUST send its responses in the same order that the requests were received, and the connection manager typically delays its responses).
+
每个BOSH会话可以分享其他用途的HTTP流量的HTTP连接, 包括其他BOSH会话以及和本协议完全无关的HTTP请求和应答 (例如, web页面下载). 无论如何, 使用HTTP流水线通过同一个连接对不是本会话一部分的请求的应答(或同一个连接中的发送队列)可能会导致对于本会话的一部分的请求的应答的延迟 (因为连接管理器必须以和接收到的请求相同的顺序来发送它的应答, 并且连接管理器通常会延迟它的某些应答).
  
The HTTP Content-Type header of all client requests SHOULD be "text/xml; charset=utf-8". However, clients MAY specify another value if they are constrained to do so (e.g., "application/x-www-form-urlencoded" or "text/plain"). The client and connection manager SHOULD ignore all HTTP Content-Type headers they receive.
+
所有客户端请求的HTTP Content-Type头应该是 "text/xml; charset=utf-8". 无论如何, 如果客户端受到某些约束,它们也可以指定其他的值 (例如, "application/x-www-form-urlencoded" "text/plain"). 客户端和连接管理器应该忽略所有接收到的HTTP Content-Type头.
  
==<body/> Wrapper Element==
+
==<body/>封装器元素==
  
The body of each HTTP request and response contains a single <body/> wrapper element qualified by the 'http://jabber.org/protocol/httpbind' namespace. The content of the wrapper is the data being transferred. The <body/> element and its content together MUST conform to the specifications set out in XML 1.0 [14]. They SHOULD also conform to Namespaces in XML [15]. The content MUST NOT contain any of the following (all defined in XML 1.0):
+
每个HTTP请求和应答的body包含一个单独的由 'http://jabber.org/protocol/httpbind' 命名空间限定的<body/>封装器元素. 这个封装器的内容就是被传输的数据. <body/>元素和它的内容都必须符合 [http://www.w3.org/TR/REC-xml/ XML 1.0] [[XEP-0124#附录G:备注|14]] 的一系列规格. 它们也应该符合 [http://www.w3.org/TR/REC-xml-names/ Namespaces in XML] [[XEP-0124#附录G:备注|15]]. 内容必须不包含任何以下的东西 (都定义于 '''XML 1.0''' ):
  
* Partial XML elements
+
* 部分XML元素
* XML comments
+
* XML注释
* XML processing instructions
+
* XML处理指令
* Internal or external DTD subsets
+
* 内部或外部DTD亚群
* Internal or external entity references (with the exception of predefined entities)
+
* 内部或外部实体引用 (预定义的实体除外)
  
The <body/> wrapper MUST NOT contain any XML character data, although its child elements MAY contain character data. The <body/> wrapper MUST contain zero or more complete XML immediate child elements (called "payloads" in this document, e.g., XMPP stanzas as defined in RFC 6120 or elements containing XML character data that represents objects using the JSON data interchange format as defined in RFC 4627 [16]). Each <body/> wrapper MAY contain payloads qualified under a wide variety of different namespaces.
+
<body/>封装器必须不包含任何XML字符串数据, 尽管它的子元素可以包含字符串数据. <body/>封装器必须包含零或多个完整的XML直接子元素(本文称为 "载荷" , 例如, 定义于 '''RFC 6120''' 的XMPP节或使用定义于 [http://tools.ietf.org/html/rfc4627 RFC 4627] [[XEP-0124#附录G:备注|16]] 的JSON数据交换格式来代表对象的包含XML字符串数据的元素).每个<body/>封装器可以包含各种广泛的命名空间限定的载荷.
  
The <body/> element of every client request MUST possess a sequential request ID encapsulated via the 'rid' attribute; for details, refer to the Request IDs section of this document.
+
每个客户端请求的<body/>元素必须拥有一个通过'rid'属性封装的顺序的请求ID; 具体信息, 参考本文的 [[XEP-0124#请求IDs|请求IDs]] 章节.
  
==Initiating a BOSH Session==
+
==发起BOSH会话==
===Session Creation Request===
+
===会话创建请求===
  
The first request from the client to the connection manager requests a new session.
+
从客户端到连接管理器的第一个请求是请求一个新的会话.
  
The <body/> element of the first request SHOULD possess the following attributes (they SHOULD NOT be included in any other requests except as specified under Adding Streams To A Session):
+
第一个请求的<body/>元素应该拥有以下属性 (它们应该不被包含在其他请求中,除非在 [[XEP-0124#添加流到一个会话|添加流到一个会话]] 时候指定):
  
* '''<nowiki>'to'</nowiki>''' -- This attribute specifies the target domain of the first stream.
+
* '''<nowiki>'to'</nowiki>''' -- 这个属性指定第一个流的目标域.
* '''<nowiki>'xml:lang'</nowiki>''' -- This attribute (as defined in Section 2.12 of XML 1.0 [17]) specifies the default language of any human-readable XML character data sent or received during the session.
+
* '''<nowiki>'xml:lang'</nowiki>''' -- 这个属性 (定义于 [http://www.w3.org/TR/REC-xml/ XML 1.0] [[XEP-0124#附录G:备注|17]] 的2.12) 指定会话期间发送或接收的任何人类可读的字符串数据的缺省语言.
* '''<nowiki>'ver'</nowiki>''' -- This attribute specifies the highest version of the BOSH protocol that the client supports. The numbering scheme is "<major>.<minor>" (where the minor number MAY be incremented higher than a single digit, so it MUST be treated as a separate integer). Note: The 'ver' attribute should not be confused with the version of any protocol being transported.
+
* '''<nowiki>'ver'</nowiki>''' -- 这个属性指定客户端支持的BOSH协议的最高版本. 编号方案是 "<主版本号>.<小版本号>" (这里小版本号可以递增到不止一位数子, 所以它必须被当成一个单独的整数来处理). 注意: 'ver' 属性应该不被误解成任何正被传输的协议的版本.
* '''<nowiki>'wait'</nowiki>''' -- This attribute specifies the longest time (in seconds) that the connection manager is allowed to wait before responding to any request during the session. This enables the client to limit the delay before it discovers any network failure, and to prevent its HTTP/TCP connection from expiring due to inactivity.
+
* '''<nowiki>'wait'</nowiki>''' -- 这个属性指定连接管理器在会话中应答任何请求之前被允许的等待时间(以秒计数). 这使客户端能限制它察觉任何网络失败之前的延迟, 并且阻止它的HTTP/TCP连接因为不活跃而过期.
* '''<nowiki>'hold'</nowiki>''' -- This attribute specifies the maximum number of requests the connection manager is allowed to keep waiting at any one time during the session. If the client is not able to use HTTP Pipelining then this SHOULD be set to "1".
+
* '''<nowiki>'hold'</nowiki>''' -- 这个属性指定连接管理器在会话中被允许同时保持的请求的最大数量. 如果客户端不能使用HTTP流水线那么它应该设为 "1".
  
Note: Clients that only support Polling Sessions MAY prevent the connection manager from waiting by setting 'wait' or 'hold' to "0". However, polling is NOT RECOMMENDED since the associated increase in bandwidth consumption and the decrease in responsiveness are both typically one or two orders of magnitude!
+
注意: 仅支持轮询会话的客户端可以通过设置'wait' 'hold' "0" 来阻止连接管理器等待. 无论如何, 轮询是不推荐的,因为带宽消耗的增加和响应能力的降低都会达到一到两个数量级!
  
A connection manager MAY be configured to enable sessions with more than one server in different domains. When requesting a session with such a "proxy" connection manager, a client SHOULD include a 'route' attribute that specifies the protocol, hostname, and port of the server with which it wants to communicate, formatted as "proto:host:port" (e.g., "xmpp:example.com:9999"). [18] A connection manager that is configured to work only with a single server (or only with a defined list of domains and the associated list of hostnames and ports that are serving those domains) MAY ignore the 'route' attribute. (Note that the 'to' attribute specifies the domain being served, not the hostname of the machine that is serving the domain.)
+
连接管理器可以被配置成允许在不同的域里和多个服务器进行会话. 当以一个"代理"连接管理器请求一个会话的时候, 客户端应该包含一个'route'属性来指定它想通讯的服务器的协议, 主机名, 和端口, 格式为 "proto:host:port" (例如, "xmpp:example.com:9999"). [[XEP-0124#附录G:备注|18]] 一个配置成只和一个 (或只和预定义的域列表以及服务于那些域的相关主机和端口列表的) 服务器配合工作的连接管理器可以忽略 'route' 属性. (注意 'to' 属性指定服务的域, 而不是服务于那个域的机器的主机名.)
  
The <body/> element of the first request MAY also possess a 'from' attribute, which specifies the originator of the first stream and which enables the connection manager to forward the originating entity's identity to the application server (e.g., the JabberID of an entity that is connecting to an XMPP server; see XEP-0206).
+
第一个请求的 <body/> 元素也可以拥有 'from' 属性, 它指定第一个流的发起者并允许连接管理器转发发起者实体的身份到应用服务器 (例如, 连接到一个XMPP服务器上的实体的 JabberID ; 见 '''XEP-0206''' ).
  
A client MAY include an 'ack' attribute (set to "1") to indicate that it will be using acknowledgements throughout the session and that the absence of an 'ack' attribute in any request is meaningful (see Acknowledgements).
+
客户端可以包含一个 'ack' 属性 (设为 "1") 来指示它将在会话中始终使用确认机制并且任何请求中缺少'ack'属性都是有特定意义的 (见 [[XEP-0124#确认|确认]] ).
  
Some clients are constrained to only accept HTTP responses with specific Content-Types (e.g., "text/html"). The <body/> element of the first request MAY possess a 'content' attribute. This specifies the value of the HTTP Content-Type header that MUST appear in all the connection manager's responses during the session. If the client request does not possess a 'content' attribute, then the HTTP Content-Type header of responses MUST be "text/xml; charset=utf-8".
+
一些客户端被约束只能接受特定Content-Types (例如, "text/html")的HTTP应答. 第一个请求的<body/>元素可以拥有一个'content'属性. 它指定在会话期间必须在所有连接管理器的应答中出现的HTTP Content-Type头的值. 如果该客户端请求没有'content'属性, 那么应答的HTTP Content-Type头必须是"text/xml; charset=utf-8".
 +
 
 +
'''示例1. 请求一个BOSH会话'''
  
'''Example 1. Requesting a BOSH session'''
 
 
<source lang="xml">
 
<source lang="xml">
 
POST /webclient HTTP/1.1
 
POST /webclient HTTP/1.1
第177行: 第178行:
 
</source>
 
</source>
  
Note: All requests after the first one MUST include a valid 'sid' attribute (provided by the connection manager in the Session Creation Response). The initialization request is unique in that the <body/> element MUST NOT possess a 'sid' attribute.
+
注意: 在第一个之后的所有请求必须包含一个有效的'sid'属性 (由连接管理器在会话创建应答中提供). 发起方请求是唯一的,在那个<body/>元素中必须没有'sid'属性.
===Session Creation Response===
+
  
After receiving a new session request, the connection manager MUST generate an opaque, unpredictable session identifier (or SID). The SID MUST be unique within the context of the connection manager application. The <body/> element of the connection manager's response to the client's session creation request MUST possess the following attributes (they SHOULD NOT be included in any other responses):
+
===会话创建应答===
  
* '''<nowiki>'sid'</nowiki>''' -- This attribute specifies the SID
+
在接收到到一个新的会话请求之后, 连接管理器必须生成一个不透明的不可预测的会话标识符 (或称为 SID). 这个SID在该连接管理器应用中的上下文中必须是唯一的. 该连接管理器对客户端的会话创建请求的应答中的 <body/> 元素必须拥有以下属性 (它们应该不被包含在任何其他应答中):
* '''<nowiki>'wait'</nowiki>''' -- This is the longest time (in seconds) that the connection manager will wait before responding to any request during the session. The time MUST be less than or equal to the value specified in the session request.
+
  
The <body/> element SHOULD also include the following attributes (they SHOULD NOT be included in any other responses):
+
* '''<nowiki>'sid'</nowiki>''' -- 该属性指定SID
 +
* '''<nowiki>'wait'</nowiki>''' -- 这是连接管理器在会话期间应答任何请求之前等待的最长时间 (以秒计数) . 这个时间必须小于或等于该会话请求的指定的值.
  
* '''<nowiki>'ver'</nowiki>''' -- This attribute specifies the highest version of the BOSH protocol that the connection manager supports, or the version specified by the client in its request, whichever is lower.
+
<body/>元素也应该包含以下属性 (它们应该不被包含在任何其他应答中):
* '''<nowiki>'polling'</nowiki>''' -- This attribute specifies the shortest allowable polling interval (in seconds). This enables the client to not send empty request elements more often than desired (see Polling Sessions and Overactivity).
+
* '''<nowiki>'inactivity'</nowiki>''' -- This attribute specifies the longest allowable inactivity period (in seconds). This enables the client to ensure that the periods with no requests pending are never too long (see Polling Sessions and Inactivity).
+
* '''<nowiki>'requests'</nowiki>''' -- This attribute enables the connection manager to limit the number of simultaneous requests the client makes (see Overactivity and Polling Sessions). The RECOMMENDED values are either "2" or one more than the value of the 'hold' attribute specified in the session request.
+
* '''<nowiki>'hold'</nowiki>''' -- This attribute informs the client about the maximum number of requests the connection manager will keep waiting at any one time during the session. This value MUST NOT be greater than the value specified by the client in the session request.
+
* '''<nowiki>'to'</nowiki>''' -- This attribute communicates the identity of the backend server to which the client is attempting to connect.
+
  
The connection manager MAY include an 'accept' attribute in the session creation response element, to specify a space-separated list of the content encodings it can decompress. After receiving a session creation response with an 'accept' attribute, clients MAY include an HTTP Content-Encoding header in subsequent requests (indicating one of the encodings specified in the 'accept' attribute) and compress the bodies of the requests accordingly.
+
* '''<nowiki>'ver'</nowiki>''' -- 这个属性指定连接管理器支持的BOSH协议的最高版本, 或客户端在它的请求中指定的版本, 取其中较低的版本.
 +
* '''<nowiki>'polling'</nowiki>''' -- 这个属性指定最小可允许的轮询间隔(以秒计数). 这使得客户端不需要以超出预期的频率发送空的请求元素 (见 [[XEP-0124#轮询会话|轮询会话]] 和 [[XEP-0124#过度活跃|过度活跃]] ).
 +
* '''<nowiki>'inactivity'</nowiki>''' -- 这个属性指定最长可允许的闲置期时间(以秒计数). 这使客户端能确保没有请求待发的时间段永远不会太长 (见 [[XEP-0124#轮询会话|轮询会话]] 和 [[XEP-0124#闲置|闲置]] ).
 +
* '''<nowiki>'requests'</nowiki>''' -- 这个属性使得连接管理器能限制客户端产生的并发请求的数量 (见  [[XEP-0124#过度活跃|过度活跃]] 和 [[XEP-0124#轮询会话|轮询会话]] ). 推荐的值是 "2" 或者比会话请求中指定的'hold' 属性值大一.
 +
* '''<nowiki>'hold'</nowiki>''' -- 这个属性通知客户端连接管理器在会话期间的任何时间将会保持等待的请求的最大数量. 这个值必须不大于客户端在会话请求中指定的值.
 +
* '''<nowiki>'to'</nowiki>''' -- 这个属性指定客户端尝试连接的后台服务器的通讯身份.
  
A connection manager MAY include an 'ack' attribute (set to the value of the 'rid' attribute of the session creation request) to indicate that it will be using acknowledgements throughout the session and that the absence of an 'ack' attribute in any response is meaningful (see Acknowledgements).
+
连接管理器可以在会话创建应答元素中包含一个'accept'属性, 来指定一个以空格分隔的可被解压的内容编码的列表. 在接收到一个带有'accept'属性的会话创建应答之后, 客户端可以在随后的请求中包含一个HTTP Content-Encoding头 (指示 'accept' 属性指定的编码之一) 并且据此压缩该请求的bodies.
  
If the connection manager supports session pausing (see Inactivity) then it SHOULD advertise that to the client by including a 'maxpause' attribute in the session creation response element. The value of the attribute indicates the maximum length of a temporary session pause (in seconds) that a client can request.
+
连接管理器可以包含一个'ack'属性 (值设为会话创建请求中的'rid'属性值) 来指示它将在该会话中始终使用确认机制,并且任何应答中缺少'ack'属性都是有特定意义的 (见 [[XEP-0124#确认|确认]] ).
  
For both requests and responses, the <body/> element and its content SHOULD be UTF-8 encoded. If the HTTP Content-Type header of a request/response specifies a character encoding other than UTF-8, then the connection manager MAY convert between UTF-8 and the other character encoding. However, even in this case, it is OPTIONAL for the connection manager to convert between encodings. The connection manager MAY inform the client which encodings it can convert by setting the optional 'charsets' attribute in the session creation response element to a space-separated list of encodings. [19]
+
如果连接管理器支持会话暂停 (见 [[XEP-0124#闲置|闲置]] ) 那么它应该通过在会话创建应答元素中包含一个'maxpause'属性来向客户端声明. 这个属性的值指示客户端可以请求的一个临时会话暂停的最大长度(以秒计数) .
  
As soon as the connection manager has established a connection to the server and discovered its identity, it MAY forward the identity to the client by including a 'from' attribute in a response, either in its session creation response, or (if it has not received the identity from the server by that time) in any subsequent response to the client. If it established a secure connection to the server (as defined in Initiating a BOSH Session), then in the same response the connection manager SHOULD also include the 'secure' attribute set to "true" or "1".
+
对请求和应答都一样, <body/>元素和它的内容应该以UTF-8编码. 如果请求/应答的HTTP Content-Type头指定了一个不同于UTF-8的字符编码, 那么连接管理器可以在UTF-8和该字符编码之间转换. 无论如何, 即使在这种情况下, 连接管理器转换编码也是可选的. 连接管理器可以通知客户端哪些编码它能够转换,通过在会话创建应答元素中设置可选的'charsets'属性为以空格分隔的编码列表. [[XEP-0124#附录G:备注|19]]
 +
 
 +
一旦连接管理器建立了一个连接到服务器并发现它的身份, 它可以在应答中包含一个'from'属性来转发这个身份给客户端, 要么在它的会话创建应答中, 要么 (如果那个时候它还没有从服务器接收到它的身份) 任何随后给客户端的应答中. 如果它建立了一个安全连接到服务器 (定义于 [[XEP-0124#发起BOSH会话|发起BOSH会话]] ), 那么在同一个应答中连接管理器也应该包含'secure'属性并把值设为 "true" "1".
 +
 
 +
'''示例2. 会话创建应答'''
  
'''Example 2. Session creation response'''
 
 
<source lang="xml">
 
<source lang="xml">
 
HTTP/1.1 200 OK
 
HTTP/1.1 200 OK
第225行: 第228行:
 
</source>
 
</source>
  
'''Example 3. Subsequent response with 'from' and 'secure' attributes'''
+
'''示例3. 随后的包含'from''secure'属性的应答'''
 +
 
 
<source lang="xml">
 
<source lang="xml">
 
HTTP/1.1 200 OK
 
HTTP/1.1 200 OK
第235行: 第239行:
 
</source>
 
</source>
  
==Sending and Receiving XML Payloads==
+
==发送和接收XML载荷==
  
After the client has successfully completed all required preconditions, it can send and receive XML payloads via the HTTP binding.
+
客户端成功完成所有必需的前提条件之后, 它就可以通过HTTP绑定来发送和接收XML载荷了.
 +
 
 +
'''示例4. 传输载荷'''
  
'''Example 4. Transmitting payloads'''
 
 
<source lang="xml">
 
<source lang="xml">
 
POST /webclient HTTP/1.1
 
POST /webclient HTTP/1.1
第261行: 第266行:
 
</source>
 
</source>
  
Upon receipt of a request, the connection manager SHOULD forward the content of the <body/> element to the server as soon as possible. In any case it MUST forward the content from different requests in the order specified by their 'rid' attributes.
+
在收到一个请求之后,一旦有可能连接管理器应该转发<body/>元素的内容到服务器. 在任何情况下它必须按照它们的'rid'属性指定的顺序来从不同的请求转发内容.
  
The connection manager MUST also return an HTTP 200 OK response with a <body/> element to the client. Note: This does not indicate that the payloads have been successfully delivered to the application server.
+
连接管理器也必须在<body/>元素中返回一个HTTP 200 OK应答给客户端. 注意: 这并不表示载荷已经被成功发送到应用服务器.
  
It is RECOMMENDED that the connection manager not return an HTTP result until a payload has arrived from the application server for delivery to the client. However, the connection manager SHOULD NOT wait longer than the time specified by the client in the 'wait' attribute of its Session Creation Request, and it SHOULD NOT keep more HTTP requests waiting at a time than the number specified in the 'hold' attribute of the session creation request. In any case it MUST respond to requests in the order specified by their 'rid' attributes.
+
建议连接管理器在载荷已经从服务器到达客户端之前不要返回HTTP结果. 无论如何, 连接管理器不应该让等待时间超过客户在它的会话创建请求中指定的'wait'属性的值 , 而且在同一时间它保持的HTTP请求数量不应该多于会话创建请求中的'hold'属性的值. 任何情况下它必须以它们的'rid'属性指定的顺序来应答请求.
  
If there are no payloads waiting or ready to be delivered within the waiting period, then the connection manager SHOULD include an empty <body/> element in the HTTP result:
+
如果在等待周期里没有载荷等待或准备好发送, 那么连接管理器应该在HTTP结果中包含一个空的<body/>元素:
 +
 
 +
'''示例5. 空应答'''
  
'''Example 5. Empty response'''
 
 
<source lang="xml">
 
<source lang="xml">
 
HTTP/1.1 200 OK
 
HTTP/1.1 200 OK
第278行: 第284行:
 
</source>
 
</source>
  
If the connection manager has received one or more payloads from the application server for delivery to the client, then it SHOULD return the payloads in the body of its response as soon as possible after receiving them from the server. The example below includes payloads qualified by different namespaces:
+
如果连接管理器已经从应用服务器收到一个或多个载荷要发送给客户端, 那么在它从服务器收到它们之后一旦有可能它应该立即在它的应答的body中返回这些载荷. 以下这个例子包含被不同命名空间限定的载荷:
 +
 
 +
'''示例6. 排队节的应答'''
  
'''Example 6. Response with queued stanza'''
 
 
<source lang="xml">
 
<source lang="xml">
 
HTTP/1.1 200 OK
 
HTTP/1.1 200 OK
第325行: 第332行:
 
</source>
 
</source>
  
The client MAY poll the connection manager for incoming payloads by sending an empty <body/> element.
+
客户端可以通过发送空的<body/>元素来轮询连接管理器的输入节.
 +
 
 +
'''示例7. 请求XML载荷'''
  
'''Example 7. Requesting XML Payloads'''
 
 
<source lang="xml">
 
<source lang="xml">
 
POST /webclient HTTP/1.1
 
POST /webclient HTTP/1.1
第340行: 第348行:
 
</source>
 
</source>
  
The connection manager MUST wait and respond in the same way as it does after receiving payloads from the client.
+
连接管理器必须以和它从客户端接收载荷同样的方法等待并回应.
  
==Acknowledgements==
+
==确认==
===Request Acknowledgements===
+
===请求确认===
  
When responding to a request that it has been holding, if the connection manager finds it has already received another request with a higher 'rid' attribute (typically while it was holding the first request), then it MAY acknowledge the reception to the client. The connection manager MAY set the 'ack' attribute of any response to the value of the highest 'rid' attribute it has received in the case where it has also received all requests with lower 'rid' values.
+
当应答一个保持的请求时, 如果连接管理器发现它已经接收了另一个更高'rid'属性的请求(通常此时它正在保持第一个请求), 那么它可以向客户端确认已收到. 当连接管理器也接收了所有更低的'rid'属性的请求时,它可以设置任何应答的 'ack' 属性高于它已经接收到的最高的'rid'属性.
 +
 
 +
'''示例8. 应答请求的确认'''
  
'''Example 8. Response with request acknowledgement'''
 
 
<source lang="xml">
 
<source lang="xml">
 
HTTP/1.1 200 OK
 
HTTP/1.1 200 OK
第357行: 第366行:
 
</source>
 
</source>
  
If the connection manager will be including 'ack' attributes on responses during a session, then it MUST include an 'ack' attribute in its session creation response, and set the 'ack' attribute of responses throughout the session. The only exception is that, after its session creation response, the connection manager SHOULD NOT include an 'ack' attribute in any response if the value would be the 'rid' of the request being responded to.
+
如果连接管理器在一个会话过程中将要包含'ack'属性, 那么它必须在它的会话创建应答中包含一个'ack'属性, 并且在会话过程中始终设置应答的'ack'属性. 唯一的例外是, 在它的会话创建应答之后, 如果这个值和任何要应答的请求的'rid'值相同,连接管理器不应该包含一个'ack'属性在应答之中.
 +
 
 +
如果连接管理器被允许同一时间保持多个请求, 那么从连接管理器收到低于预期的'ack'值(或意外的缺少'ack'属性)可以给客户端一个可能发生网络失败的早期预警(例如, 如果客户端认为连接管理在它应答的时候应该已经接收到了另一个请求).
  
If the connection manager is permitted to hold more than one request at a time, then the reception of a lower-than-expected 'ack' value from the connection manager (or the unexpected abscence of an 'ack' attribute) can give the client an early warning that a network failure might have occurred (e.g., if the client believes the connection manager should have received another request by the time it responded).
+
===应答确认===
===Response Acknowledgements===
+
  
The client MAY similarly inform the connection manager about the responses it has received by setting the 'ack' attribute of any request to the value of the highest 'rid' of a request for which it has already received a response in the case where it has also received all responses associated with lower 'rid' values. If the client will be including 'ack' attributes on requests during a session, then it MUST include an 'ack' attribute (set to '1') in its session creation request, and set the 'ack' attribute of requests throughout the session. The only exception is that, after its session creation request, the client SHOULD NOT include an 'ack' attribute in any request if it has received responses to all its previous requests.
+
客户端可以同样通过把任何请求的'ack'属性值设为它已经接收到的的应答的最高'rid'值(此时它也已经接收了所有拥有更低'rid'值的应答)来通知连接管理器它已经收到了应答. 如果客户端在一个会话中要在请求中包含'ack'属性, 那么它必须在它的会话创建请求中包含一个'ack'属性(值为'1'), 并且在会话中始终设置请求的'ack'属性. 唯一的例外是, 在它的会话创建请求之后, 如果客户端已经接收到所有在它之前的请求的应答,那么客户端不应该包含一个'ack'属性到任何请求.
  
'''Example 9. Request with response acknowledgement'''
+
'''示例9. 请求应答确认'''
 
<source lang="xml">
 
<source lang="xml">
 
POST /webclient HTTP/1.1
 
POST /webclient HTTP/1.1
第378行: 第388行:
 
</source>
 
</source>
  
After receiving a request with an 'ack' value less than the 'rid' of the last request that it has already responded to, the connection manager MAY inform the client of the situation by sending its next response immediately instead of waiting until it has payloads to send to the client (e.g., if some time has passed since it responded). In this case it SHOULD include a 'report' attribute set to one greater than the 'ack' attribute it received from the client, and a 'time' attribute set to the number of milliseconds since it sent the response associated with the 'report' attribute.
+
在接收到一个'ack'值低于最后一个已应答请求的'rid'值的请求时, 连接管理器可以通过立即发送它的下一个应答而不是等到它有需要发送给客户端的载荷的时候才发送应答(例如, 假如从它应答的时候到现在已经过了一段时间),以此告知客户端这种情况. 在这种情况下它应该包含一个'report'属性并把值设为高于它从客户端接收到的'ack'属性, 'time'属性则设为它发送'report'相关应答的时间,以毫秒计数.
  
'''Example 10. Response with report'''
+
'''示例10. 应答报告'''
 
<source lang="xml">
 
<source lang="xml">
 
HTTP/1.1 200 OK
 
HTTP/1.1 200 OK
第391行: 第401行:
 
</source>
 
</source>
  
Upon reception of a response with 'report' and 'time' attributes, if the client has still not received the response associated with the request identifier specified by the 'report' attribute, then it MAY choose to resend the request associated with the missing response (see Broken Connections).
+
在收到一个拥有'report''time'属性的应答之后, 如果客户端仍未收到'report'属性指定的请求id相关的应答, 那么它可以选择重发这个丢失的应答相关的请求 (见 [[XEP-0124#断开的连接|断开的连接]] ).
  
==Inactivity==
+
==闲置==
  
After receiving a response from the connection manager, if none of the client's requests are still being held by the connection manager (and if the session is not a Polling Session), the client SHOULD make a new request as soon as possible. In any case, if no requests are being held, the client MUST make a new request before the maximum inactivity period has expired. The length of this period (in seconds) is specified by the 'inactivity' attribute in the session creation response.
+
从连接管理器接收到一个应答之后, 如果没有客户端请求继续被连接管理器保持 (并且如果会话不是一个轮询会话), 客户端应该一有可能就制造一个新的请求. 在任何情况下, 如果没有请求被hold住, 客户端必须在最大闲置时间过期之前制造一个新的请求. 这个时间段(以秒计数) 是在会话创建应答中的'inactivity'属性定义的.
  
If the connection manager has responded to all the requests it has received within a session and the time since its last response is longer than the maximum inactivity period, then it SHOULD assume the client has been disconnected and terminate the session without informing the client. If the client subsequently makes another request, then the connection manager SHOULD respond as if the session does not exist.
+
如果连接管理器已经应答了一个会话中它所接收到的所有请求并且从最后一次应答到当前的时间超过最大闲置时间段, 那么它应该假定客户端已经失去连接并且不通知客户端就终止这个会话. 如果接下来客户端再制造另一个请求, 那么连接管理器应该像这个会话不存在一样来应答.
  
If the connection manager did not specify a maximum inactivity period in the session creation response, then it SHOULD allow the client to be inactive for as long as it chooses.
+
如果连接管理器在会话创建应答里没有指定一个最大闲置时间, 那么它应该允许客户端选择它的闲置时间.
  
If the session is not a polling session then the connection manager SHOULD specify a relatively short inactivity period to ensure that disconnections are discovered as quickly as possible. The RECOMMENDED time would be a little more than the number of seconds for a comfortable network round trip between the connection manager and the client under difficult network conditions (since the client can be expected to make a new request immediately -- see above).
+
如果会话不是轮询会话那么连接管理器应该指定一个相对短的闲置时间来确保尽可能快的发现断链. 建议的时间应该比连接管理器和客户端在困难的网络条件下一次顺利的网络往返的秒数多一点 (因为可以期待客户端立刻制造一个新请求 -- 见上文).
  
If a client encounters an exceptional temporary situation during which it will be unable to send requests to the connection manager for a period of time greater than the maximum inactivity period (e.g., while a runtime environment changes from one web page to another), and if the connection manager included a 'maxpause' attribute in its Session Creation Response, then the client MAY request a temporary increase to the maximum inactivity period by including a 'pause' attribute in a request. Note: If the connection manager did not specify a 'maxpause' attribute at the start of the session then the client MUST NOT send a 'pause' attribute during the session.
+
如果客户端遇到意外的临时状况,在此期间它将不能在最大闲置时间之内发送请求到连接管理器(例如, 当运行时环境从一个web页面变成另一个页面), 并且如果连接管理器在它的会话创建应答中包含了'maxpause'属性, 那么客户端可以通过在一个请求中包含'pause'属性来请求临时增加最大闲置时间的. 注意: 如果连接管理器没有在会话开始的时候定义一个'maxpause'属性那么客户端不能在会话期间发送'pause'属性.
  
'''Example 11. Requesting a Session Pause'''
+
'''示例11. 请求会话暂停'''
 
<source lang="xml">
 
<source lang="xml">
 
POST /webclient HTTP/1.1
 
POST /webclient HTTP/1.1
第419行: 第429行:
 
</source>
 
</source>
  
Upon reception of a session pause request, if the requested period is not greater than the maximum permitted time, then the connection manager SHOULD respond immediately to all pending requests (including the pause request) and temporarily increase the maximum inactivity period to the requested time. Note: The response to the pause request MUST NOT contain any payloads.
+
接收到一个会话暂停请求之后, 如果请求的时间段不超过最大允许时间, 那么连接管理器应该立刻应答所有未决的请求(包括暂停请求)并临时增加最大限制时间到请求的时间. 注意: 对暂停请求的应答不能包含任何载荷.
  
Note: If the client simply wants the connection manager to return all the requests it is holding then it MAY set the value of the 'pause' attribute to be the value of the 'inactivity' attribute in the connection manager's session creation response. (If the client believes it is in danger of becoming disconnected indefinitely then it MAY even request a temporary reduction of the maximum inactivity period by specifying a 'pause' value less than the 'inactivity' value, thus enabling the connection manager to discover any subsequent disconnection more quickly.)
+
注意: 如果客户端简单地希望连接管理器返回所有它保持住的请求,那么它可以把'pause'属性值设为连接管理器的会话请求应答中的'inactivity'属性值. (如果客户端认为它有无限期断线的危险,那么它甚至可以通过指定一个小于'inactivity'值的'pause'值来请求临时减少闲置时间, 这样使得连接管理器能快速发现接下来的断链.)
  
The connection manager SHOULD set the maximum inactivity period back to normal upon reception of the next request from the client (assuming the connection manager has not already terminated the session).
+
连接管理器应该在从客户端接到下一个请求之前(假定连接管理器尚未终止该会话)把闲置时间设回正常.
  
==Overactivity==
+
==过度活跃==
  
The client SHOULD NOT make more simultaneous requests than specified by the 'requests' attribute in the connection manager's Session Creation Response. However the client MAY make one additional request if it is to pause or terminate a session.
+
客户端不应该制造超过连接管理器的会话创建应答中的'requests'属性定义数量的并发请求. 无论如何,如果客户端暂停或终止一个会话,它可以制造一个额外的请求.
  
If during any period the client sends a sequence of new requests (i.e. requests with incremented rid attributes, not repeat requests) longer than the number specified by the 'requests' attribute, and if the connection manager has not yet responded to any of the requests, and if the last request did not include either a 'pause' attribute or a 'type' attribute set to "terminate", then the connection manager SHOULD consider that the client is making too many simultaneous requests, and terminate the HTTP session with a 'policy-violation' terminal binding error to the client. Note: This behavior applies to equally to normal and polling sessions.
+
如果在任何时间段客户端发送系列的新请求(也就是说请求的rid属性是增长的, 而不是重复的请求)超过了'requests'属性指定的数量, 并且如果连接管理器尚未应答这些请求中的任何一个, 并且如果最后一次请求既不包含一个'pause'属性也不包含一个值为"terminate"的'type'属性, 那么连接管理器应该认为客户端正在制造过多的并发请求, 并且发一个'policy-violation'终止绑定错误给客户端来终止该HTTP会话. 注意: 这个行为同时适用于普通和轮询会话.
  
'''Example 12. Too many simultaneous requests response'''
+
'''示例12. 过多并发请求应答'''
 
<source lang="xml">
 
<source lang="xml">
 
HTTP/1.1 200 OK
 
HTTP/1.1 200 OK
第442行: 第452行:
 
</source>
 
</source>
  
Note: If the connection manager did not specify a 'requests' attribute in the session creation response, then it MUST allow the client to send as many simultaneous requests as it chooses.
+
注意: 如果连接管理器在会话创建应答中没有指定一个'requests'属性, 那么它必须允许客户端按它选择的数量来发送并发请求.
  
If during any period the client sends a sequence of new requests equal in length to the number specified by the 'requests' attribute, and if the connection manager has not yet responded to any of the requests, and if the last request was empty and did not include either a 'pause' attribute or a 'type' attribute set to "terminate", and if the last two requests arrived within a period shorter than the number of seconds specified by the 'polling' attribute in the session creation response, then the connection manager SHOULD consider that the client is making requests more frequently than it was permitted and terminate the HTTP session and return a 'policy-violation' terminal binding error to the client. Note: the behavior for Polling Sessions is slightly different.
+
如果在任何时间段客户端发送系列新请求等于'requests'属性指定的数量, 并且如果连接管理器尚未应答这些请求中的任何一个, 并且如果最后一次请求既不包含一个'pause'属性也不包含一个值为"terminate"的'type'属性, 并且最后两个请求到达的时间差小于创建会话应答中的'polling'属性定义的值, 那么连接管理器应该认为客户端正在制造超过它允许的频率的请求并且发一个'policy-violation'终止绑定错误给客户端来终止该HTTP会话. 注意: 这个行为对于轮询会话略有不同.
  
'''Example 13. Too frequent requests response'''
+
'''示例13. 过于频繁的请求应答'''
 
<source lang="xml">
 
<source lang="xml">
 
HTTP/1.1 200 OK
 
HTTP/1.1 200 OK
第457行: 第467行:
 
</source>
 
</source>
  
Note: If the connection manager did not specify a 'polling' attribute in the session creation response, then it MUST allow the client to send requests as frequently as it chooses.
+
注意: 如果连接管理器在会话创建应答中未定义'polling'属性, 那么它必须允许客户端按它选择的频率来发送请求.
  
==Polling Sessions==
+
==轮询会话==
  
It is not always possible for a constrained client to either use HTTP Pipelining or open more than one HTTP connection with the connection manager at a time. In this case the client SHOULD inform the connection manager by setting the values of the 'wait' and/or 'hold' attributes in its session creation request to "0", and then "poll" the connection manager at regular intervals throughout the session for payloads it might have received from the server. Note: Even if the client does not request a polling session, the connection manager MAY require a client to use polling by setting the 'requests' attribute (which specifies the number of simultaneous requests the client can make) of its Session Creation Response to "1", however this is NOT RECOMMENDED.
+
对一个受约束的客户端来说不一定总是能使用HTTP流水线或在同一时间和连接管理器打开多个HTTP连接. 在这种情况下客户端应该在它的会话创建请求中把'wait' /'hold' 属性值设为"0"来通知连接管理器, 并且然后在会话中始终有规律地"轮询"连接管理器来获得它可能从服务器收到的载荷. 注意: 即使客户端不请求一个轮询会话, 连接管理器可以通过设置它的 [[XEP-0124#会话创建应答|会话创建应答]] 的'requests'属性(它指定客户端能制造的并发请求的数量)"1"来要求一个客户端使用轮询, 无论如何这是不推荐的.
  
If a session will use polling, the connection manager SHOULD specify a higher than normal value for the 'inactivity' attribute (see Inactivity) in its session creation response. The increase SHOULD be greater than the value it specifies for the 'polling' attribute.
+
如果一个会话将使用轮询, 连接管理器应在它的会话创建应答中指定一个高于普通值的'inactivity'属性(见 [[XEP-0124#闲置|闲置]] ) . 这个增加值应该大于它指定的'polling'属性值.
  
If the client sends two consecutive empty new requests (i.e. requests with incremented rid attributes, not repeat requests) within a period shorter than the number of seconds specified by the 'polling' attribute (the shortest allowable polling interval) in the session creation response, and if the connection manager's response to the first request contained no payloads, then upon reception of the second request the connection manager SHOULD terminate the HTTP session and return a 'policy-violation' terminal binding error to the client.
+
如果客户端在一个低于会话创建应答中'polling'属性(允许的最短轮询间隔)指定的秒数的时间段内发送两个连续的空的新请求(也就是说请求的rid属性是增加的, 而不是重复的请求), 并且如果连接管理器应答的第一个请求不包含载荷, 那么在收到第二个请求之后连接管理器应该终止HTTP会话并返回一个'policy-violation'终止绑定错误给客户端.
  
'''Example 14. Too frequent polling response'''
+
'''示例14. 过于频繁的轮询应答'''
 
<source lang="xml">
 
<source lang="xml">
 
HTTP/1.1 200 OK
 
HTTP/1.1 200 OK
第478行: 第488行:
 
</source>
 
</source>
  
Note: If the connection manager did not specify a 'polling' attribute in the session creation response, then it MUST allow the client to poll as frequently as it chooses.
+
注意: 如果连接管理器在会话创建应答中未指定'polling'属性, 那么它必须允许客户端按它选择的频率来轮询.
  
==Terminating the HTTP Session==
+
==终止HTTP会话==
  
At any time, the client MAY gracefully terminate the session by sending a <body/> element with a 'type' attribute set to "terminate". The termination request MAY include one or more payloads that the connection manager MUST forward to the server to ensure graceful logoff.
+
任何时候, 客户端可以发送一个'type'属性为"terminate"的<body/>元素来正常地终止会话. 终止请求可以包含一个或多个载荷,连接管理器必须转发给服务器以确保正常的注销登录.
  
'''Example 15. Session termination by client'''
+
'''示例15. 来自客户端的会话终止'''
 
<source lang="xml">
 
<source lang="xml">
 
POST /webclient HTTP/1.1
 
POST /webclient HTTP/1.1
第501行: 第511行:
 
</source>
 
</source>
  
The connection manager SHOULD respond to this request with an HTTP 200 OK containing an empty <body/> element.
+
连接管理器应该用一个包含空的<body/>元素的HTTP 200 OK来应答这个请求  .
  
'''Example 16. Connection manager acknowledges termination'''
+
'''示例16. 连接管理器确认终止'''
 
<source lang="xml">
 
<source lang="xml">
 
HTTP/1.1 200 OK
 
HTTP/1.1 200 OK
第513行: 第523行:
 
</source>
 
</source>
  
Upon receiving the response, the client MUST consider the HTTP session to have been terminated.
+
在接收到该应答后, 客户端必须认为该HTTP会话已经被终止.
  
==Request IDs==
+
==请求IDs==
===Generation===
+
===生成===
  
The client MUST generate a large, random, positive integer for the initial 'rid' (see Security Considerations) and then increment that value by one for each subsequent request. The client MUST take care to choose an initial 'rid' that will never be incremented above 9007199254740991 [21] within the session. In practice, a session would have to be extraordinarily long (or involve the exchange of an extraordinary number of packets) to exceed the defined limit.
+
客户端必须生成一个大的, 随机的, 正整数用于初始的'rid' (见 [[XEP-0124#安全事项|安全事项]] ) ,并且随后的每个请求的rid做加一的处理. 客户端必须小心选择一个初始的'rid',在整个会话中它的值不能够加到超过 9007199254740991 [[XEP-0124#附录G:备注|21]] . 在实践中, 一个会话可能被迫变得非常长 (或涉及到非常多的包交换) 以至于超过定义的限制.
===In-Order Message Forwarding===
+
===顺序的消息转发===
  
When a client makes simultaneous requests, the connection manager might receive them out of order. The connection manager MUST forward the payloads to the server and respond to the client requests in the order specified by the 'rid' attributes. The client MUST process responses received from the connection manager in the order the requests were made.
+
当一个客户端制造了并发请求, 连接管理器可能没能按顺序接收到它们. 连接管理器必须按照'rid'属性指定的顺序来转发载荷到服务器并应答客户端的这些请求. 客户端必须按照请求的顺序来处理从连接管理器接收到的应答.
  
The connection manager SHOULD expect the 'rid' attribute to be within a window of values greater than the 'rid' of the previous request. The size of the window is equal to the maximum number of simultaneous requests allowed by the connection manager. If it receives a request with a 'rid' greater than the values in the window, then the connection manager MUST terminate the session with an error:
+
连接管理器应该期望'rid'属性值在一个大于前一个请求的数值窗内. 这个数值窗等于连接管理器允许的最大并发请求数量. 如果它接收到的请求的'rid'大于这个数值窗, 那么连接管理器必须以一个错误来终止会话:
  
'''Example 17. Unexpected rid error'''
+
'''示例17. 意外的rid错误'''
 
<source lang="xml">
 
<source lang="xml">
 
HTTP/1.1 200 OK
 
HTTP/1.1 200 OK
第536行: 第546行:
 
</source>
 
</source>
  
===Broken Connections===
+
===断开的连接===
  
Unreliable network communications or client constraints can result in broken connections. The connection manager SHOULD remember the 'rid' and the associated HTTP response body of the client's most recent requests which were not session pause requests (see Inactivity) and which did not result in an HTTP or binding error. The number of responses to non-pause requests kept in the buffer SHOULD be either the same as the maximum number of simultaneous requests allowed by the connection manager or, if Acknowledgements are being used, the number of responses that have not yet been acknowledged.
+
不可靠的网络通讯或客户端约束可能造成断开的连接. 连接管理器应该记住'rid'以及相应的那些客户端的非暂停请求(见 [[XEP-0124#闲置|闲置]] )和非HTTP或绑定错误的请求的HTTP应答. 保持在缓冲之中的对于非暂停请求的应答的数量应该和连接管理器允许的并发请求数量相同, 或者,如果使用了确认机制, 则和还未确认的应答数量相同.
  
If the network connection is broken or closed before the client receives a response to a request from the connection manager, then the client MAY resend an exact copy of the original request. Whenever the connection manager receives a request with a 'rid' that it has already received, it SHOULD return an HTTP 200 (OK) response that includes the buffered copy of the original XML response to the client (i.e., a <body/> wrapper possessing appropriate attributes and optionally containing one or more XML payloads). If the original response is not available (e.g., it is no longer in the buffer), then the connection manager MUST return an 'item-not-found' terminal binding error:
+
如果网络连接中断或在客户端接收到连接管理器对于某个请求的应答之前关闭了, 那么客户端刻一重新发送一个原请求的精确副本. 任何时候连接管理器发现收到的请求的'rid已经接收过, 它应该返回一个包含缓冲区的原有XML应答的 HTTP 200 (OK) 应答给客户端 (也就是说, 一个封装了了拥有适当属性以及可选的包含一个或多个XML载荷的<body/>). 如果原有的应答不可用 (例如, 它已经不在缓冲区了), 那么连接管理器必须返回一个 'item-not-found' 终止绑定错误:
  
'''Example 18. Response not in buffer error'''
+
'''示例18. 应答不在缓冲区错误'''
 
<source lang="xml">
 
<source lang="xml">
 
HTTP/1.1 200 OK
 
HTTP/1.1 200 OK
第553行: 第563行:
 
</source>
 
</source>
  
Note: The error is the same whether the 'rid' is too large or too small. This makes it more difficult for an attacker to discover an acceptable value.
+
注意: 无论这个'rid'是过大还是过小,错误都是一样的. 这使得攻击者更难搜索到可接受的值.
  
==Protecting Insecure Sessions==
+
==保护不安全的会话==
===Applicability===
+
===适用性===
  
The OPTIONAL key sequencing mechanism described here MAY be used if the client's session with the connection manager is not secure. The session SHOULD be considered secure only if all client requests are made via SSL (or TLS) HTTP connections and the connection manager generates an unpredictable session ID. If the session is secure, it is not necessary to use this key sequencing mechanism.
+
如果客户端和连接管理器之间的会话不安全,可以使用这里描述的可选的密钥序列机制. 只有所有客户端请求都是通过 SSL(TLS) HTTP连接并且连接管理器生成了一个不可预知的会话ID,该会话才应该被认为是安全的. 如果会话是安全的, 则不需要使用这个密钥序列机制.
  
Even if the session is not secure, the unpredictable session and request IDs specified in the preceding sections of this document already provide a level of protection similar to that provided by a connection bound to a single pair of persistent TCP/IP connections, and thus provide sufficient protection against a 'blind' attacker. However, in some circumstances, the key sequencing mechanism defined below helps to protect against a more determined and knowledgeable attacker.
+
即使会话不安全, 本文前述章节定义的意外会话和请求IDs已经通过把连接绑定到一对持久TCP/IP连接的方法来提供了一个类似级别的保护,并且因此提供了防止''绑定的足够保护. 无论如何, 在某些环境下, 以下定义的密钥序列机制帮助抵御了更多确定的和有知识的攻击者.
  
It is important to recognize that the key sequencing mechanism defined below helps to protect only against an attacker who is able to view the contents of all requests or responses in an insecure session but who is not able to alter the contents of those requests (in this case, the mechanism prevents the attacker from injecting HTTP requests into the session, e.g., termination requests or responses). However, the key sequencing mechanism does not provide any protection when the attacker is able to alter the contents of insecure requests or responses.
+
重要的是要认识到以下定义的密钥序列机制只帮助我们保护抵御一个能在一个序列的不安全会话中看到所有请求或应答但不能修改那些请求的内容(在这种情况下, 这个机制阻止攻击者插入HTTP请求到会话, 例如, 终止请求或应答)的攻击者. 无论如何, 当攻击者能修改不安全的请求或应答的内容时,密钥序列机制不提供任何保护.
===Introduction===
+
  
The HTTP requests of each session MAY be spread across a series of different socket connections. This would enable an unauthorized user that obtains the session ID and request ID of a session to then use their own socket connection to inject <body/> request elements into the session and receive the corresponding responses.
+
===简述===
  
The key sequencing mechanism below protects against such attacks by enabling a connection manager to detect <body/> request elements injected by a third party.
+
每个会话的HTTP请求可以通过一系列不同的socket连接来散播. 这将使得一个未经授权的收到该会话ID和会话请求ID的用户能够使用他们自己的socket连接来插入<body/>请求元素到会话中并接收相应的应答.
===Generating the Key Sequence===
+
  
Prior to requesting a new session, the client MUST select an unpredictable counter ("n") and an unpredictable value ("seed"). The client then processes the "seed" through a cryptographic hash and converts the resulting 160 bits to a hexadecimal string K(1). It does this "n" times to arrive at the initial key K(n). The hashing algorithm MUST be SHA-1 as defined in RFC 3174 [22].
+
以下的密钥序列机制通过允许连接管理器探查第三方插入的<body/>请求元素来抵御这类攻击.
  
'''Example 19. Creating the key sequence'''
+
===生成密钥序列===
 +
 
 +
在请求一个新的会话之前, 客户端必须选择一个不可预知的计数器 ("n") 和一个不可预知的值 ("seed"). 然后客户端通过把这个"seed"做一次加密哈希运算并从160位转换成一个十六进制字符串 K(1). 它运算 "n" 次然后得到发起密钥 K(n). 这个哈希算法必须是 SHA-1 定义于 [http://tools.ietf.org/html/rfc3174 RFC 3174] [[XEP-0124#附录G:备注|22]] .
 +
 
 +
'''示例19. 创建密钥序列'''
  
 
         K(1) = hex(SHA-1(seed))
 
         K(1) = hex(SHA-1(seed))
第578行: 第590行:
 
         ...
 
         ...
 
         K(n) = hex(SHA-1(K(n-1)))
 
         K(n) = hex(SHA-1(K(n-1)))
     
 
  
===Use of Keys===
+
===使用密钥===
  
The client MUST set the 'newkey' attribute of the first request in the session to the value K(n).
+
客户端必须把该会话中第一个请求的 'newkey' 属性值设为 K(n).
  
'''Example 20. Session Request with Initial Key'''
+
'''示例20. 携带发起密钥的会话请求'''
 
<source lang="xml">
 
<source lang="xml">
 
POST /webclient HTTP/1.1
 
POST /webclient HTTP/1.1
第602行: 第613行:
 
</source>
 
</source>
  
The client MUST set the 'key' attribute of all subsequent requests to the value of the next key in the generated sequence (decrementing from K(n-1) towards K(1) with each request sent).
+
客户端必须把所有接下来的请求的 'key' 属性值设为按生成顺序的下一个密钥 (每个请求发送的值从 K(n-1) K(1) 衰减).
  
'''Example 21. Request with Key'''
+
'''示例21. 携带密钥的请求'''
 
<source lang="xml">
 
<source lang="xml">
 
POST /webclient HTTP/1.1
 
POST /webclient HTTP/1.1
第618行: 第629行:
 
</source>
 
</source>
  
The connection manager MAY verify the key by calculating the SHA-1 hash of the key and comparing it to the 'newkey' attribute of the previous request (or the 'key' attribute if the 'newkey' attribute was not set). If the values do not match (or if it receives a request without a 'key' attribute and the 'newkey' or 'key' attribute of the previous request was set), then the connection manager MUST NOT process the element, MUST terminate the session, and MUST return an 'item-not-found' terminal binding error.
+
连接管理器可以通过运算密钥的 SHA-1 哈希并把它和前一个请求的 'newkey' 属性(或者如果没有'newkey' 属性则为 'key' 属性)进行比较来证实密钥. 如果这个值不匹配 (或者如果接收到一个不带 'key' 属性的请求,以及接收到的是前一个请求所设的 'newkey' 'key' 属性), 那么连接管理器必须不处理该元素, 必须终止该会话, 并且必须返回一个 'item-not-found' 终止绑定错误.
  
'''Example 22. Invalid Key Sequence Error'''
+
'''示例22. 非法的密钥序列错误'''
 
<source lang="xml">
 
<source lang="xml">
 
HTTP/1.1 200 OK
 
HTTP/1.1 200 OK
第631行: 第642行:
 
</source>
 
</source>
  
===Switching to Another Key Sequence===
+
===切换到另一个密钥序列===
  
A client SHOULD choose a high value for "n" when generating the key sequence. However, if the session lasts long enough that the client arrives at the last key in the sequence K(1) then the client MUST switch to a new key sequence.
+
生成密钥序列的时候,客户端应该选择一个高的 "n" . 无论如何, 如果会话太长以至于客户端在序列 K(1) 中达到最后的密钥, 那么客户端必须切换到一个新的密钥序列.
  
The client MUST:
+
客户端必须:
  
1. Choose new values for "seed" and "n".
+
# 选择新的 "seed" "n" .
2. Generate a new key sequence using the algorithm defined above.
+
# 使用上文定义的机制生成一个新的密钥序列.
3. Set the 'key' attribute of the request to the next value in the old sequence (i.e. K(1), the last value).
+
# 把该请求的 'key' 属性设为旧的序列的下一个值 (也就是说 K(1), 最后的值).
4. Set the 'newkey' attribute of the request to the value K(n) from the new sequence.
+
# 把该请求的 'newkey' 属性设为新的序列的值 K(n).
  
'''Example 23. New Key Sequence'''
+
'''示例23. 新密钥序列'''
 
<source lang="xml">
 
<source lang="xml">
 
POST /webclient HTTP/1.1
 
POST /webclient HTTP/1.1
第662行: 第673行:
 
</source>
 
</source>
  
==Multiple Streams==
+
==多重流==
===Introduction===
+
===简介===
  
The OPTIONAL feature described in this section enables multiple XML streams to be contained within a single HTTP session. This feature is essential in runtime environments that prevent HTTP Pipelining, thereby constraining the number of simultaneous HTTP requests a client can make to each connection manager, since clients running in such environments need multi-stream sessions if they are to connect using more than one account at the same time. This feature also reduces network traffic for any client that needs to establish parallel streams over HTTP.
+
本章描述的可选特性允许在一个HTTP会话中包含多重XML流. 这个特性实质上用于那些不允许HTTP流水线的运行时环境中, 此时一个客户端能和每个连接管理器打开的并发HTTP请求的数量是受限的, 如果他们在同一时间使用不止一个帐号连接,那么运行于这类环境下的客户端需要多重流会话. 这个特性对于任何通过HTTP建立了并联流的客户端来说也降低了网络流量.
===Discovery===
+
===查询===
  
If a connection manager supports the multi-streams feature, it MUST include a 'stream' attribute in its Session Creation Response. If a client does not receive the 'stream' attribute then it MUST assume that the connection manager does not support the feature. [23]
+
如果一个连接管理器支持多重流特性, 它必须在它的会话创建应答中包含一个'stream'属性. 如果一个客户端不接受这个'stream'属性,那么它必须假定连接管理器不支持该特性. [[XEP-0124#附录G:备注|23]]
  
The 'stream' attribute identifies the first stream to be opened for the session. The value of each 'stream' attribute MUST be an opaque and unpredictable name that is unique within the context of the connection manager application.
+
这个 'stream' 属性标识该会话打开的第一个流. 每个 'stream' 属性的值必须是一个无意义的不可预知的名字,并且在连接管理器应用的上下文中是唯一的.
  
'''Example 24. Session creation response with stream name'''
+
'''示例24. 携带流名字(stream name)的会话创建应答'''
 
<source lang="xml">
 
<source lang="xml">
 
HTTP/1.1 200 OK
 
HTTP/1.1 200 OK
第693行: 第704行:
 
</source>
 
</source>
  
===Adding Streams To A Session===
+
===添加流到会话===
  
If the connection manager included a 'stream' attribute in its session creation response then the client MAY ask it to open another stream at any time by sending it an empty <body/> element with a 'to' attribute. The request MUST include valid 'sid' and 'rid' [24] attributes, and SHOULD also include an 'xml:lang' attribute. The request MAY include 'route', 'from' and 'secure' attributes (see Session Creation Request), but it SHOULD NOT include 'ver', 'content', 'hold' or 'wait' attributes (since a new session is not being created).
+
如果连接管理器在它的会话创建应答中包含了一个 'stream' 属性,那么客户端可以在任何时间发送一个空的带有'to'属性的<body/>元素来请求它打开另一个流. 请求必须包含合法的'sid''rid' [[XEP-0124#附录G:备注|24]] 属性, 并且也应该包含一个 'xml:lang' 属性. 请求可以包含 'route', 'from' 'secure' 属性 (见 [[XEP-0124#会话创建请求||会话创建请求]] ), 但是它不应该包含 'ver', 'content', 'hold' 'wait' 属性 (因为并没有创建一个新的会话).
  
'''Example 25. Requesting another stream'''
+
'''示例25. 请求另一个流'''
 
<source lang="xml">
 
<source lang="xml">
 
POST /webclient HTTP/1.1
 
POST /webclient HTTP/1.1
第713行: 第724行:
 
</source>
 
</source>
  
If the connection manager did not indicate its support for multiple streams at the start of the session, then it MUST ignore the extra attributes and treat the request as a normal empty request for payloads (see Sending and Receiving XML Payloads). [25] Otherwise it MUST open a new stream with the specified server (see Session Creation Response), generate a new stream name, and respond to the client with the name. The response MAY also include 'from' and 'secure' attributes, but it SHOULD NOT include 'sid', 'requests', 'polling', 'hold', 'inactivity', 'maxpause', 'accept', 'charsets', 'ver' or 'wait' attributes.
+
如果连接管理器没有在会话的开始表示它支持多重流, 那么它必须忽略额外的属性并且和对待普通的用于载荷的空请求一样对待该请求(见 [[XEP-0124#发送和接收XM载荷|发送和接收XM载荷]] ). [[XEP-0124#附录G:备注|25]] 否则它必须打开一个新的流到指定的服务器 (见 [[XEP-0124#会话创建应答|会话创建应答]] ), 生成一个新的流名字, 并以此名字应答客户端. 应答也可以包含 'from' 'secure' 属性, 但是它不应该包含 'sid', 'requests', 'polling', 'hold', 'inactivity', 'maxpause', 'accept', 'charsets', 'ver' 'wait' 属性.
  
'''Example 26. Add stream response'''
+
'''示例26. 添加流应答'''
 
<source lang="xml">
 
<source lang="xml">
 
HTTP/1.1 200 OK
 
HTTP/1.1 200 OK
第726行: 第737行:
 
</source>
 
</source>
  
Note: If the response did not include either 'from' or 'secure' attributes then they MAY be sent in a subsequent response instead (see Session Creation Response). In that case the 'stream' attribute MUST also be specified.
+
注意: 如果应答既不包含 'from' 也不包含 'secure' 属性,那么它们可以留待接下来的应答中被发送 (见 [[XEP-0124#会话创建应答|会话创建应答]] ). 在那种情况下 'stream' 属性也是必须指定的.
===Transmitting Payloads===
+
  
If more than one stream has been opened within a session, then all non-empty <body/> elements sent by the connection manager MUST include a 'stream' attribute that specifies which stream all the payloads it contains belong to. The client SHOULD include a 'stream' attribute for the same purpose. The client MAY omit the 'stream' attribute if it wants the connection manager to broadcast the payloads over all open streams. Note: A <body/> element MUST NOT contain different payloads for different streams.
+
===传送载荷===
  
If a stream name does not correspond to one of the session's open streams, then the receiving connection manager SHOULD return an 'item-not-found' terminal binding error, or the receiving client SHOULD terminate the session. However, if the receiving entity has only just closed the stream (and the sender might not have been aware of that when it sent the payloads), then it MAY instead simply silently ignore any payloads the <body/> element contains.
+
如果在一个会话中不止打开一个流, 那么被连接管理器发送的所有非空的<body/>元素必须包含'stream'属性,它定义所有的载荷属于哪个流. 客户端应该包含一个'stream'属性用于同样的目的. 如果客户端希望连接管理器广播这些载荷给所有打开的流,它可以忽略'stream'属性. 注意: 一个<body/>元素在不同的流中必须不能包含不同的载荷.
  
Note: Empty <body/> elements that do not include a 'from' or 'secure' attribute SHOULD NOT include a 'stream' attribute (since nothing is being transmitted for any stream). If such a <body/> element does include a 'stream' attribute then the receiving entity SHOULD ignore the attribute.
+
如果一个流名字不符合该会话打开的流之一, 那么接收到的连接管理器应该返回一个 'item-not-found' 终止绑定错误, 或者接收到的客户端应该终止这个会话. 无论如何, 如果接收到的实体只是关闭这个流 (并且发送者可能在它发送这个载荷的时候没有留意), 那么它可以简单安静地忽略该<body/>元素包含的任何载荷.
  
'''Example 27. Client sends payload with a stream name'''
+
注意: 不包含'from''secure'属性的空的<body/>元素不应该包含'stream'属性(因为任何流都没有东西正在传送). 如果这样的一个<body/>元素包含了一个'stream'属性,那么接收到的实体应该忽略该属性.
 +
 
 +
'''示例27. 客户端以一个流名字发送载荷'''
 
<source lang="xml">
 
<source lang="xml">
 
POST /webclient HTTP/1.1
 
POST /webclient HTTP/1.1
第754行: 第766行:
 
</source>
 
</source>
  
Note: The value of the 'stream' attribute of the response MAY be different than the corresponding request. [26]
+
注意: 该应答的'stream'属性值可以和响应请求的不同. [[XEP-0124#附录G:备注|26]]
  
'''Example 28. Connection manager responds with a different stream name'''
+
'''示例28. 连接管理器应答一个不同的流名字'''
 
<source lang="xml">
 
<source lang="xml">
 
HTTP/1.1 200 OK
 
HTTP/1.1 200 OK
第772行: 第784行:
 
</source>
 
</source>
  
If no stream name is specified by the connection manager then the client MUST assume the payloads are associated with the first stream (even if the first stream has been closed).
+
如果连接管理器没有指定流名字,那么客户端必须假定载荷是和第一个流相关的(即使第一个流已经关闭了).
  
If no stream name is specified by the client then the connection manager MUST broadcast the payloads over all open streams. [27]
+
如果客户端没有指定一个流名字,那么连接管理器必须广播载荷给所有打开的流. [27]
  
'''Example 29. Client asks for a payload to be broadcast'''
+
'''示例29. 客户端请求一个载荷被广播'''
 
<source lang="xml">
 
<source lang="xml">
 
POST /webclient HTTP/1.1
 
POST /webclient HTTP/1.1
第793行: 第805行:
 
</source>
 
</source>
  
===Closing a Stream===
+
===关闭流===
  
If more than one stream is open within a session, the client MAY close one open stream at any time using the procedure described in the section Terminating the HTTP Session above, taking care to specify the stream name with a 'stream' attribute. If the client closes the last stream the connection manager MUST terminate the session. If the client does not specify a stream name then the connection manager MUST close all open streams (sending any payloads the terminate request contains to all streams), and terminate the session.
+
如果在一个会话中打开了不止一个流, 客户端可以在任何时间使用上文 [[XEP-0124#终止HTTP会话|终止HTTP会话]] 描述的程序关闭一个流, 小心地在'stream'属性指定该流的名字. 如果客户端关闭了最后一个流,连接管理器必须终止该会话. 如果客户端没有指定一个流名字那么连接管理器必须关闭所有打开的流 (发送该终止请求的任何载荷到所有流), 并终止该会话.
  
'''Example 30. Client closes one stream'''
+
'''示例30. 客户端关闭一个流'''
 
<source lang="xml">
 
<source lang="xml">
 
POST /webclient HTTP/1.1
 
POST /webclient HTTP/1.1
第815行: 第827行:
 
</source>
 
</source>
  
===Error Conditions===
+
===错误条件===
  
If more than one stream is open within a session, the connection manager MAY include a 'stream' attribute in a fatal binding error (see Terminal Binding Conditions). If a 'stream' attribute is specified then the stream MUST be closed by both entities but the session SHOULD NOT be terminated.
+
如果在一个会话中不止打开了一个流, 连接管理器可以在致命绑定错误中包含一个'stream'属性(见 [[XEP-0124#终止绑定条件|终止绑定条件]] ). 如果指定了'stream'属性,那么该流必须被双方实体关闭但是会话不应该被终止.
  
'''Example 31. Fatal stream error'''
+
'''示例31. 致命流错误'''
 
<source lang="xml">
 
<source lang="xml">
 
HTTP/1.1 200 OK
 
HTTP/1.1 200 OK
第831行: 第843行:
 
</source>
 
</source>
  
Note: If the connection manager does not include a 'stream' attribute in a fatal binding error then all the session's open streams MUST be closed by both entities and the session MUST be terminated.
+
注意: 如果连接管理器在致命流错误中不包含'stream'属性,那么会话的所有的打开的流都必须被双方实体关闭并且会话必须被终止.
  
==Error and Status Codes==
+
==错误和状态代码==
  
There are four types of error and status reporting in HTTP responses:
+
在HTTP应答中有四种类型的错误和状态报告:
  
'''Table 1: Error Condition Types'''
+
'''表1: 错误条件类型'''
 
{| border="1"
 
{| border="1"
!Condition Type
+
!错误条件
!Description
+
!描述
 
|-
 
|-
|HTTP Conditions (Deprecated)
+
|HTTP条件 (已过时)
|The connection manager responds to an invalid request from a legacy client with a standard HTTP error. These are used for binding syntax errors, possible attacks, etc. Note that constrained clients are unable to differentiate between HTTP errors.
+
|连接管理器应答从传统客户端来的非法请求一个HTTP错误. 这用于绑定语法错误, 可能的攻击, 等等. 注意受约束的客户端不能区分不同的HTTP错误.
 
|-
 
|-
|Terminal Binding Conditions
+
|终止绑定条件
|These error conditions can be read by constrained clients. They are used for connection manager problems, abstracting stream errors, communication problems between the connection manager and the server, and invalid client requests (binding syntax errors, possible attacks, etc.)
+
|这些错误条件可以被受约束的客户端读取. 他们用于连接管理器问题, 抽象流错误, 连接管理器和服务器之间的通讯问题, 以及非法客户端请求 (绑定语法错误, 可能的攻击, 等等.)
 
|-
 
|-
|Recoverable Binding Conditions
+
|可恢复的绑定条件
|These report communication problems between the connection manager and the client. They do not terminate the session. Clients recover from these errors by resending all the preceding <body/> wrappers that have not received responses.
+
|这些报告连接管理器和客户端之间的通讯问题. 它们不终止会话. 客户端通过重新发送前面所有的未收到应答的<body/>封装器来从这些错误恢复.
 
|-
 
|-
|Transported Protocol Conditions
+
|被传输的协议的条件
|Errors relating to the XML payloads within <body/> wrappers are, in general, defined in the documentation of the protocol being transported. They do not terminate the session.
+
|<body/>封装器中的XML载荷有关的错误, 通常定义于被传输的协议的文档中. 它们不终止会话.
 
|}
 
|}
  
Full descriptions are provided below.
+
完整的描述在下面.
===HTTP Conditions===
+
===HTTP条件===
  
Note: All HTTP codes except 200 have been superseded by Terminal Binding Conditions to allow clients to determine whether the source of errors is the connection manager application or an HTTP intermediary.
+
注意: 除了200所有HTTP代码已经被终止绑定条件取代,以使客户端能确定错误的来源是连接管理器应用还是HTTP媒介.
  
A legacy client (or connection manager) is a client (or connection manager) that did not include a 'ver' attribute in its session creation request (or response). A legacy client (or connection manager) will interpret (or respond with) HTTP error codes according to the table below. Non-legacy connection managers SHOULD NOT send HTTP error codes unless they are communicating with a legacy client. Upon receiving an HTTP error (400, 403, 404), a legacy client or any client that is communicating with a legacy connection manager MUST consider the HTTP session to be null and void. A non-legacy client that is communicating with a non-legacy connection manager MAY consider that the session is still active.
+
传统的客户端(或连接管理器)在它的会话创建请求(或应答)中是不包含'ver'属性的. 传统客户端(或连接管理器)将根据下表来解释(或应答) HTTP错误码. 非传统连接管理器应该不发送HTTP错误码,除非它们连接的是一个传统客户端. 在接收到一个HTTP错误(400, 403, 404)之后, 一个传统客户端或任何连接到传统连接管理器的客户端必须认为该会话为空的和无用的(null and void). 一个连接到非传统连接管理器的非传统客户端可以认为该会话仍活跃.
  
'''Table 2: HTTP Error and Status Codes'''
+
'''表2: HTTP错误和状态码'''
 
{| border="1"
 
{| border="1"
!Code
+
!代码
!Name
+
!名称
!Superseded by
+
!被...取代
!Purpose
+
!目的
 
|-
 
|-
 
|200
 
|200
 
|OK
 
|OK
 
|<nowiki>-</nowiki>
 
|<nowiki>-</nowiki>
|Response to valid client request.
+
|应答给合法的客户端请求.
 
|-
 
|-
 
|400
 
|400
 
|Bad Request
 
|Bad Request
 
|bad-request
 
|bad-request
|Inform client that the format of an HTTP header or binding element is unacceptable (e.g., syntax error).
+
|通知客户端一个HTTP头的格式或绑定的元素是不可接受的(例如, 语法错误).
 
|-
 
|-
 
|403
 
|403
 
|Forbidden
 
|Forbidden
 
|policy-violation
 
|policy-violation
|Inform client that it has broken the session rules (polling too frequently, requesting too frequently, too many simultaneous requests).
+
|通知客户端它违反了会话规则(轮询太频繁, 请求太频繁, 太多并发请求).
 
|-
 
|-
 
|404
 
|404
 
|Not Found
 
|Not Found
 
|item-not-found
 
|item-not-found
|Inform client that (1) 'sid' is not valid, (2) 'stream' is not valid, (3) 'rid' is larger than the upper limit of the expected window, (4) connection manager is unable to resend response, (5) 'key' sequence is invalid.
+
|通知客户端 (1) 'sid' 不合法, (2) 'stream' 不合法, (3) 'rid' 大于期望的窗口上限, (4) 连接管理器不能重发应答, (5) 'key' 顺序不合法.
 
|}
 
|}
  
Note: No other HTTP error and status codes were defined in the early versions of BOSH (e.g., Internal Server Error).
+
注意: 没有其他定义在早期版本BOSH里的HTTP错误和状态码 (例如, Internal Server Error).
  
===Terminal Binding Conditions===
+
===终止绑定条件===
  
In any response it sends to the client, the connection manager MAY return a fatal error by setting a 'type' attribute of the <body/> element to "terminate". These binding errors imply that the HTTP session is terminated (unless a 'stream' attribute is specified -- see Multiple Stream Error Conditions).
+
在任何发送到客户端的应答里, 连接管理器可以通过把<body/>元素的'type'属性值设为"terminate"来返回一个致命错误. 这些绑定错误标识该HTTP会话被终止了(除非定义了一个'stream'属性 -- 见 [[XEP-0124#错误条件|多重流错误条件]] ).
  
Note: Although many of these conditions are similar to the XMPP stream error conditions specified in RFC 6120, they are not to be confused with XMPP stream errors. In cases where BOSH is being used to transport XMPP, any fatal XMPP stream error conditions experienced between the connection manager and the XMPP server SHOULD only be reported using the "remote-stream-error" condition as described below.
+
注意: 尽管这些条件中的一部分类似定义于 '''RFC 6120''' 的XMPP流错误条件, 它们不会被XMPP流错误混淆. 在这里BOSH是用于传输XMPP, 在连接管理器和XMPP服务器之间经历的任何致命XMPP流错误条件只会被用下面描述的"remote-stream-error"条件来报告.
  
'''Example 32. Remote connection failed error'''
+
'''示例32. 远程连接失败错误'''
 
<source lang="xml">
 
<source lang="xml">
 
HTTP/1.1 200 OK
 
HTTP/1.1 200 OK
第909行: 第921行:
 
</source>
 
</source>
  
The following values of the 'condition' attribute are defined:
+
'condition'属性的值定义如下:
  
'''Table 3: Terminal Binding Error Conditions'''
+
'''表3: 终止绑定错误条件'''
 
{| border="1"
 
{| border="1"
!Condition
+
!条件
!Purpose
+
!目的
 
|-
 
|-
 
|bad-request*
 
|bad-request*
|The format of an HTTP header or binding element received from the client is unacceptable (e.g., syntax error).
+
|T一个HTTP头或从客户端收到的绑定元素的格式不可接受(例如, 语法错误).
 
|-
 
|-
 
|host-gone
 
|host-gone
|The target domain specified in the 'to' attribute or the target host or port specified in the 'route' attribute is no longer serviced by the connection manager.
+
|连接管理器的'to'属性指定的目标域或'route'属性指定的目标主机或端口不再提供服务.
 
|-
 
|-
 
|host-unknown
 
|host-unknown
|The target domain specified in the 'to' attribute or the target host or port specified in the 'route' attribute is unknown to the connection manager.
+
|连接管理器的'to'属性指定的目标域或'route'属性指定的目标主机或端口是未知的.
 
|-
 
|-
 
|improper-addressing
 
|improper-addressing
|The initialization element lacks a 'to' or 'route' attribute (or the attribute has no value) but the connection manager requires one.
+
|发起元素缺少'to''route'属性(或属性没有值)但是连接管理器需要它.
 
|-
 
|-
 
|internal-server-error
 
|internal-server-error
|The connection manager has experienced an internal error that prevents it from servicing the request.
+
|连接管理器经历了一个内部错误导致它无法为请求提供服务.
 
|-
 
|-
 
|item-not-found*
 
|item-not-found*
|(1) 'sid' is not valid, (2) 'stream' is not valid, (3) 'rid' is larger than the upper limit of the expected window, (4) connection manager is unable to resend response, (5) 'key' sequence is invalid.
+
|(1) 'sid'不合法, (2) 'stream'不合法, (3) 'rid' 大于期望窗口的上限, (4) 连接管理器不能重发应答, (5) 'key' 序列非法.
 
|-
 
|-
 
|other-request
 
|other-request
|Another request being processed at the same time as this request caused the session to terminate.
+
|和这个请求请求想同的另一个请求导致该会话终止.
 
|-
 
|-
 
|policy-violation*
 
|policy-violation*
|The client has broken the session rules (polling too frequently, requesting too frequently, sending too many simultaneous requests).
+
|客户端违反了会话规则(轮询太频繁, 请求太频繁, 发送了过多的并发请求).
 
|-
 
|-
 
|remote-connection-failed
 
|remote-connection-failed
|The connection manager was unable to connect to, or unable to connect securely to, or has lost its connection to, the server.
+
|连接管理器无法连接, 或无法安全地连接, 或已经丢失了它的连接, 到服务器.
 
|-
 
|-
 
|remote-stream-error
 
|remote-stream-error
|Encapsulates an error in the protocol being transported.
+
|封装了一个正在传输的协议的错误.
 
|-
 
|-
 
|see-other-uri
 
|see-other-uri
|The connection manager does not operate at this URI (e.g., the connection manager accepts only SSL or TLS connections at some https: URI rather than the http: URI requested by the client). The client can try POSTing to the URI in the content of the <uri/> child element.
+
|连接管理器不执行这个URI(例如, 连接管理器只接受客户端以类似 https: URI 而不是类似 the http: URI 的请求以SSL或TLS连接). 客户端可以尝试 POSTing <uri/>子元素内含的那个 URI .
 
|-
 
|-
 
|system-shutdown
 
|system-shutdown
|The connection manager is being shut down. All active HTTP sessions are being terminated. No new sessions can be created.
+
|连接管理器正在关闭. 所有激活的HTTP会话正在被终止. 不能创建新的会话.
 
|-
 
|-
 
|undefined-condition
 
|undefined-condition
|The error is not one of those defined herein; the connection manager SHOULD include application-specific information in the content of the <body/> wrapper.
+
|这个错误不是在这里定义的那些错误之一; 连接管理器应该在这个<body/>封装器的内容里包含 应用特有的 信息.
 
|}
 
|}
  
* If the client did not include a 'ver' attribute in its session creation request then the connection manager SHOULD send a deprecated HTTP Error Condition instead of this terminal binding condition. If the connection manager did not include a 'ver' attribute in its session creation response then the client SHOULD expect it to send a deprecated HTTP Error Condition instead of this terminal binding condition.
+
<nowiki>* 如果客户端在它的会话创建请求中未包含一个'ver'属性,那么连接管理器应该发送一个已过时的HTTP错误而不是这个终止绑定错误条件. 如果连接管理器在它的会话创建应答中未包含'ver'属性,那么客户端应该预期它会发送一个已过时的HTTP错误条件而不是这个终止会话绑定条件.
 +
</nowiki>
  
The following is an example of a "see-other-uri" condition:
+
以下是一个 "see-other-uri" 条件的例子:
  
'''Example 33. See other URI error'''
+
'''示例33. 参见另一个URI错误'''
 
<source lang="xml">
 
<source lang="xml">
 
HTTP/1.1 200 OK
 
HTTP/1.1 200 OK
第973行: 第986行:
 
</source>
 
</source>
  
The following is an example including a "remote-stream-error" condition:
+
以下是一个包含"remote-stream-error"条件的例子:
  
'''Example 34. Remote error'''
+
'''示例34. 远程错误'''
 
<source lang="xml">
 
<source lang="xml">
 
HTTP/1.1 200 OK
 
HTTP/1.1 200 OK
第1,001行: 第1,014行:
 
</source>
 
</source>
  
Naturally, the client MAY report binding errors to the connection manager as well, although this is unlikely.
+
自然的, 客户端同样可以报告绑定错误给连接管理器, 尽管这是这是不太可能的.
===Recoverable Binding Conditions===
+
  
In any response it sends to the client, the connection manager MAY return a recoverable error by setting a 'type' attribute of the <body/> element to "error". These errors do not imply that the HTTP session is terminated.
+
===可恢复的绑定条件===
  
If it decides to recover from the error, then the client MUST repeat the HTTP request that resulted in the error, as well as all the preceding HTTP requests that have not received responses. The content of these requests MUST be identical to the <body/> elements of the original requests. This enables the connection manager to recover a session after the previous request was lost due to a communication failure.
+
在任何连接管理器发送给客户端的应答中, 它可以通过设置<body/>元素的'type'属性为"error"来返回一个可恢复的错误. 这些错误不表示HTTP会话被终止.
  
'''Example 35. Recoverable error'''
+
如果客户端决定从这个错误回复, 那么它必须重复那个发生错误的HTTP请求, 以及所有前面没有收到应答的HTTP请求. 这些请求的内容必须和原始请求的<body/>元素相同. 这使连接管理器在前一个请求因为通讯失败而丢失之后能恢复一个会话.
 +
 
 +
'''示例35. 可恢复的错误'''
 
<source lang="xml">
 
<source lang="xml">
 
HTTP/1.1 200 OK
 
HTTP/1.1 200 OK
第1,018行: 第1,032行:
 
</source>
 
</source>
  
===XML Payload Conditions===
+
===XML载荷条件===
 +
 
 +
应用级的错误条件描述请参看正在被传输并通过连接管理器路由到客户端的那个协议的文档. 它们对连接管理器来说是透明的, 所以超过了这里定义的传输绑定的范围.
 +
 
 +
==实现备注==
 +
===HTTP流水线===
  
Application-level error conditions described in the documentation of the protocol being transported are routed to the client through the connection manager. They are transparent to the connection manager, and therefore out of scope for the transport binding defined herein.
+
即使客户端请求HTTP流水线并且连接管理器支持它, 也不保证流水线能成功, 因为它可能不被中间代理支持.
  
==Implementation Notes==
+
客户端能做到最好的是通过设置'hold'属性的值为"1"来请求使用HTTP流水线. 如果HTTP流水线没生效(因为服务器返回 HTTP 1.0 或 connection:close), 那么客户端应该降格为使用多重连接.
===HTTP Pipelining===
+
  
Even if the client requests HTTP Pipelining and the connection manager supports it, there is no guarantee that pipelining will succeed, because it might not be supported by intermediate proxies.
+
==安全事项==
 +
===在客户端和BOSH服务之间连接===
  
The best the client can do is to request the use of HTTP Pipelining by setting the 'hold' attribute to a value of "1". If HTTP Pipelining does not work (because the server returns HTTP 1.0 or connection:close), then the client SHOULD degrade gracefully by using multiple connections.
+
客户端和BOSH服务之间的所有通讯应该发生在加密的HTTP连接之上. 客户端和连接管理器之间的加密应该发生在传输层或HTTP层, 而不是应用层; 这个协商应该遵循定义于 [http://wp.netscape.com/eng/ssl3/draft302.txt SSL] [[XEP-0124#附录G:备注|28]] 的 HTTP/SSL 协议, 当然也可以遵循定义于 [http://tools.ietf.org/html/rfc2818 RFC 2818] [[XEP-0124#附录G:备注|29]] 的 HTTP/TLS 协议或定义于 [http://tools.ietf.org/html/rfc2817 RFC 2817] [[XEP-0124#附录G:备注|30]] 的基于HTTP协议的TLS.
  
==Security Considerations==
+
如果用来发送发起会话请求的HTTP连接是加密的, 那么该会话中使用的所有其他HTTP连接也必须是加密的. 此外, 如果当建立用来发送发起会话请求的加密连接的时候交换了验证证书, 那么客户端 和/或 连接管理器应该确保在该会话接下来的所有连接中使用同一个验证证书. 一旦这样一个 "安全会话" 被建立:
===Connection Between Client and BOSH Service===
+
  
All communications between a client and a BOSH service SHOULD occur over encrypted HTTP connections. Negotiation of encryption between the client and the connection manager SHOULD occur at the transport layer or the HTTP layer, not the application layer; such negotiation SHOULD follow the HTTP/SSL protocol defined in SSL [28], although MAY follow the HTTP/TLS protocol defined in RFC 2818 [29] or the TLS Within HTTP protocol defined in RFC 2817 [30].
+
* 如果连接管理器拒绝简历一个加密连接或提供了不同的证书, 那么客户端应该关闭连接并终止会话而不发送任何更多的请求.
 +
* 如果客户端通过一个未加密的连接或使用了一个不同的证书发送了属于某个"安全会话"一部分的封装元素, 那么连接管理器应该简单地关闭该连接. 连接管理应该不终止该会话,因为那将使拒绝服务攻击更容易.
  
If the HTTP connection used to send the initial session request is encrypted, then all the other HTTP connections used within the session MUST also be encrypted. Furthermore, if authentication certificates are exchanged when establishing the encrypted connection that is used to send the initial session request, then the client and/or connection manager SHOULD ensure that the same authentication certificates are employed for all subsequent connections used by the session. Once such a "secure session" has been established:
+
===BOSH和应用之间的连接===
  
* If the connection manager refuses to establish an encrypted connection or offers a different certificate, then the client SHOULD close the connection and terminate the session without sending any more requests.
+
一个BOSH服务应该使用适当的技术例如安全套接字层(SSL),传输层安全(TLS)以及StartTLS(如果后台程序支持的话) 等等来加密它到后台应用的连接. 另外, BOSH 服务在以下情形中可以被认为安全 (1) 如果它运行在和后台应用同一个物理机上 或 (2) 如果它运行在和后台应用同一个私有网络上并且管理员确信未知的个人或程序不能访问私有网络.
* If the client sends a wrapper element that is part of a "secure session" over a connection that either is not encrypted or uses a different certificate, then the connection manager SHOULD simply close the connection. The connection manager SHOULD NOT terminate the session since that would facilitate denial of service attacks.
+
  
===Connection Between BOSH Service and Application===
+
如果数据隐私是必需的, 客户端应该使用一个应用级别的点对点加密技术来加密它的消息, 因为客户端没办法确信BOSH服务加密了它到该应用的连接; 这些方法超出了本协议的范围.
  
A BOSH service SHOULD encrypt its connection to the backend application using appropriate technologies such as Secure Sockets Layer (SSL), Transport Layer Security (TLS), and StartTLS if supported by the backend application. Alternatively, the BOSH service can be considered secure (1) if it is running on the same physical machine as the backend application or (2) if it running on the same private network as the backend application and the administrators are sure that unknown individuals or processes do not have access to that private network.
+
===不可预测的SID和RID===
  
If data privacy is desired, the client SHOULD encrypt its messages using an application-specific end-to-end encryption technology, because there is no way for the client to be sure that the BOSH service encrypts its connection to the application; methods for doing so are outside the scope of this specification.
+
会话标识符(SID)和发起请求标识符(RID)是安全的关键所以都必须是不可预测的和不重复的(见 [http://tools.ietf.org/html/rfc1750 RFC 1750] [[XEP-01243附录G:备注|31]] 的关于为了安全目的对SIDs和发起RIDs的随机性的建议).
===Unpredictable SID and RID===
+
  
The session identifier (SID) and initial request identifier (RID) are security-critical and therefore MUST be both unpredictable and nonrepeating (see RFC 1750 [31] for recommendations regarding randomness of SIDs and initial RIDs for security purposes).
+
===使用SHA-1===
===Use of SHA-1===
+
  
Recent research has shown that in select cases it is possible to compromise the hashes produced by the SHA-1 hashing algorithm (see RFC 4270 [32]). However, the use to which SHA-1 is put in BOSH will likely minimize the applicability of the attacks described in the literature. Furthermore, current estimates suggest that even with the recently-discovered attack, it would still take one year of computing by a government-sized entity to produce a collision.
+
最近的研究显示,在选定的情况下,使用SHA-1哈希算法来产生哈希值是最有可能的(见 [http://tools.ietf.org/html/rfc4270 RFC 4270] [[XEP-0124#G:备注|32]] ). 无论如何, 在BOSh中使用SHA-1看起来会最小化该文献描述的可能的攻击. 另外, 目前的评估表明,在经常发现的攻击中, 它将耗费政府级实体的运算能力一年才可能出现问题.
  
==IANA Considerations==
+
==IANA事项==
  
TCP port 5280, conventially used for communication between BOSH clients and BOSH connection mangers, is registered with the Internet Assigned Numbers Authority (IANA) [33] in its port registry at IANA Port Numbers Registry [34], with a keyword of "xmpp-bosh". (Although use of this port is OPTIONAL, it is helpful to define this port in a standardized way so that BOSH clients can contact any given XMPP service via BOSH without the need either for DNS TXT records as described in Discovering Alternative XMPP Connection Methods [35] or for more advanced methods such as U-NAPTR.
+
TCP端口5280, 传统上用于BOSH客户端和BOSH连接管理器的通讯, 已经注册到 [http://www.iana.org/ 互联网编号分配机构(IANA)] [[XEP-0124#附录G:备注|33]] 在它的 [http://www.iana.org/assignments/port-numbers IANA端口号码注册表] [[XEP-0124#附录G:备注|34]] 的端口注册表里 , 关键词为 "xmpp-bosh". (尽管这个端口的使用是可选的, 定义这个端口有助于标准化,这样BOSH客户端可以通过BOSH联系任何一个给定的XMPP服务而不需要 [http://xmpp.org/extensions/xep-0156.html 查找替代的XMPP连接方法] [[XEP-0124#附录G:备注|35]] 描述的 DNS TXT 记录或更多先进的方法例如 U-NAPTR.
  
==XMPP Registrar Considerations==
+
==XMPP注册事项==
===Protocol Namespaces===
+
===协议命名空间===
  
The XMPP Registrar includes 'http://jabber.org/protocol/httpbind' in its registry of protocol namespaces.
+
在它的协议命名空间注册项中包含了 'http://jabber.org/protocol/httpbind' 的XMPP注册项.
  
 
==XML Schema==
 
==XML Schema==
第1,151行: 第1,167行:
 
</source>
 
</source>
  
==Acknowledgements==
+
==致谢==
  
Thanks to Mike Cumings, Tomas Karasek, Tobias Markmann, Chris Seymour, Safa Sofuoğlu, Stefan Strigler, Matthew Wild, Kevin Winters, and Christopher Zorn for their feedback.
+
感谢 Mike Cumings, Tomas Karasek, Tobias Markmann, Chris Seymour, Safa Sofuoğlu, Stefan Strigler, Matthew Wild, Kevin Winters, 以及 Christopher Zorn 的反馈.
  
==Appendices==
+
==附录==
===Appendix A: Document Information===
+
===附录A:文档信息===
 +
 
 +
系列:[http://xmpp.org/extensions/ XEP]
 +
 
 +
序号:0124
 +
 
 +
发布者:[http://xmpp.org/xsf/ XMPP标准基金会]
 +
 
 +
状态:[http://xmpp.org/extensions/xep-0001.html#states-Draft 草案]
 +
 
 +
类型:[http://www.xmpp.org/extensions/xep-0001.html#types-Standards%20Track 标准跟踪]
 +
 
 +
版本:1.10
 +
 
 +
最后更新时间:2010-07-02
 +
 
 +
批准机构:[http://xmpp.org/council/ XMPP理事会]
 +
 
 +
依赖标准:RFC 1945, RFC 2616, RFC 3174
 +
 
 +
替代标准:无
 +
 
 +
被替代标准:无
 +
 
 +
缩略名:bosh
  
Series: XEP
 
Number: 0124
 
Publisher: XMPP Standards Foundation
 
Status: Draft
 
Type: Standards Track
 
Version: 1.10
 
Last Updated: 2010-07-02
 
Approving Body: XMPP Council
 
Dependencies: RFC 1945, RFC 2616, RFC 3174
 
Supersedes: None
 
Superseded By: None
 
Short Name: bosh
 
 
Schema: <http://www.xmpp.org/schemas/httpbind.xsd>
 
Schema: <http://www.xmpp.org/schemas/httpbind.xsd>
Source Control: HTML RSS
+
 
This document in other formats: XML PDF
+
原文控制: [http://gitorious.org/xmpp/xmpp/blobs/master/extensions/xep-0124.xml HTML]
 +
 
 +
本文的其它格式: [http://xmpp.org/extensions/xep-0124.xml XML] [http://xmpp.org/extensions/xep-0124.pdf PDF]
 
===Appendix B: Author Information===
 
===Appendix B: Author Information===
Ian Paterson
+
'''Ian Paterson'''
 +
:Email: [mailto:ian.paterson@clientside.co.uk ian.paterson@clientside.co.uk]
 +
:JabberID: ian@zoofy.com
  
Email: ian.paterson@clientside.co.uk
+
'''Dave Smith'''
JabberID: ian@zoofy.com
+
:Email: [mailto:dizzyd@jabber.org dizzyd@jabber.org]
Dave Smith
+
:JabberID: dizzyd@jabber.org
  
Email: dizzyd@jabber.org
+
'''Peter Saint-Andre'''
JabberID: dizzyd@jabber.org
+
:Email: [mailto:stpeter@jabber.org stpeter@jabber.org]
Peter Saint-Andre
+
:JabberID: stpeter@jabber.org
 +
:URI: https://stpeter.im/
  
Email: stpeter@jabber.org
+
'''Jack Moffitt'''
JabberID: stpeter@jabber.org
+
:Email: [mailto:jack@chesspark.com jack@chesspark.com]
URI: https://stpeter.im/
+
:JabberID: jack@chesspark.com
Jack Moffitt
+
  
Email: jack@chesspark.com
 
JabberID: jack@chesspark.com
 
 
===附录C:法律通告===
 
===附录C:法律通告===
 
*版权
 
*版权
第1,217行: 第1,247行:
  
 
以下用于本文的需求关键字的解释见于 [http://www.ietf.org/rfc/rfc2119.txt RFC 2119]: "MUST", "SHALL", "REQUIRED"; "MUST NOT", "SHALL NOT"; "SHOULD", "RECOMMENDED"; "SHOULD NOT", "NOT RECOMMENDED"; "MAY", "OPTIONAL".
 
以下用于本文的需求关键字的解释见于 [http://www.ietf.org/rfc/rfc2119.txt RFC 2119]: "MUST", "SHALL", "REQUIRED"; "MUST NOT", "SHALL NOT"; "SHOULD", "RECOMMENDED"; "SHOULD NOT", "NOT RECOMMENDED"; "MAY", "OPTIONAL".
===Appendix G: Notes===
+
===附录G:备注===
  
1. RFC 793: Transmission Control Protocol <http://tools.ietf.org/html/rfc0793>.
+
# RFC 793: 传输控制协议 <http://tools.ietf.org/html/rfc0793>.
  
2. RFC 1945: Hypertext Transfer Protocol -- HTTP/1.0 <http://tools.ietf.org/html/rfc1945>.
+
# RFC 1945: 超文本传输协议 -- HTTP/1.0 <http://tools.ietf.org/html/rfc1945>.
  
3. RFC 2616: Hypertext Transport Protocol -- HTTP/1.1 <http://tools.ietf.org/html/rfc2616>.
+
# RFC 2616: 超文本传输协议 -- HTTP/1.1 <http://tools.ietf.org/html/rfc2616>.
  
4. Bayeux Protocol <http://svn.cometd.org/trunk/bayeux/bayeux.html>.
+
# Bayeux协议 <http://svn.cometd.org/trunk/bayeux/bayeux.html>.
  
5. The Web Socket Protocol <http://tools.ietf.org/html/draft-hixie-thewebsocketprotocol>.
+
# Web套接字协议 <http://tools.ietf.org/html/draft-hixie-thewebsocketprotocol>.
  
6. Reverse HTTP <http://tools.ietf.org/html/draft-lentczner-rhttp>.
+
# 反向HTTP <http://tools.ietf.org/html/draft-lentczner-rhttp>.
  
7. RFC 2965: HTTP State Management Mechanism <http://tools.ietf.org/html/rfc2965>.
+
# RFC 2965: HTTP状态管理机制 <http://tools.ietf.org/html/rfc2965>.
  
8. Requiring cookies is sub-optimal because several significant computing platforms provide only limited access to underlying HTTP requests/responses; worse, some platforms hide or remove cookie-related headers.
+
# 要求cookies是次优的,因为很多重要的计算平台只提供底层HTTP请求/应答的有限访问; 更坏的是, 一些平台或者移除了cookie相关的头.
  
9. XEP-0025: Jabber HTTP Polling <http://xmpp.org/extensions/xep-0025.html>.
+
# XEP-0025: Jabber HTTP轮询 <http://xmpp.org/extensions/xep-0025.html>.
  
10. RFC 6120: Extensible Messaging and Presence Protocol (XMPP): Core <http://tools.ietf.org/html/rfc6120>.
+
# RFC 6120: 可扩展的消息和出席信息协议 (XMPP): 核心 <http://tools.ietf.org/html/rfc6120>.
  
11. XEP-0206: XMPP Over BOSH <http://xmpp.org/extensions/xep-0206.html>.
+
# XEP-0206: 在BOSH上的XMPP  <http://xmpp.org/extensions/xep-0206.html>.
  
12. In order to reduce network congestion, RFC 2616 recommends that clients SHOULD NOT keep more than two HTTP connections to the same HTTP server open at the same time. Clients running in constrained enviroments typically have no choice but to abide by that recommendation.
+
# 为了减少网络拥塞, RFC 2616 建议客户端在同一时间不应该和同一台HTTP服务器保持超过两个HTTP连接. 运行在受约束的环境的客户端通常没有机会选择而只能遵守该建议.
  
13. If there is no traffic other than the "pings" then bandwidth consumption will be double that of a TCP connection (although double nothing is still nothing). If data is sent in large packets then bandwidth consumption will be almost identical.
+
# 如果没有"pings"之外的流量,那么带宽拥塞将是单个TCP连接的两倍(尽管加倍空仍然是空). 如果被发送的数据是一些大的包,那么带宽拥塞情况也是几乎一致的.
  
14. Extensible Markup Language (XML) 1.0 (Fourth Edition) <http://www.w3.org/TR/REC-xml/>.
+
# 可扩展标记语言 (XML) 1.0 (第四版) <http://www.w3.org/TR/REC-xml/>.
  
15. Namespaces in XML <http://www.w3.org/TR/REC-xml-names/>.
+
# XML的名字空间  <http://www.w3.org/TR/REC-xml-names/>.
  
16. RFC 4627: The application/json Media Type for JavaScript Object Notation (JSON) <http://tools.ietf.org/html/rfc4627>.
+
# RFC 4627: 用于JavaScript对象符号(JSON) 的 应用程序/json 媒体类型  <http://tools.ietf.org/html/rfc4627>.
  
17. Extensible Markup Language (XML) 1.0 (Fourth Edition) <http://www.w3.org/TR/REC-xml/>.
+
# 可扩展的标记语言 (XML) 1.0 (第四版) <http://www.w3.org/TR/REC-xml/>.
  
18. Although the syntax of the 'route' attribute bears a superficial resemblance to a URI or IRI, it is not a URI/IRI and MUST NOT be processed in accordance with the rules specified in RFC 3986, RFC 3987, or (for XMPP) RFC 5122.
+
# 尽管'route'属性的语法粗看起来和一个URI或IRI相似, 它不是一个 URI/IRI 并且不可按照 '''RFC 3986, RFC 3987, (用于XMPP) RFC 5122''' 定义的规则来处理.
  
19. Each character set name (or character encoding name -- we use the terms interchangeably) SHOULD be of type NMTOKEN, where the names are separated by the white space character #x20, resulting in a tokenized attribute type of NMTOKENS (see Section 3.3.1 of XML 1.0 [20]). Strictly speaking, the Character Sets registry maintained by the Internet Assigned Numbers Authority (see <http://www.iana.org/assignments/character-sets>) allows a character set name to contain any printable US-ASCII character, which might include characters not allowed by the NMTOKEN construction of XML 1.0; however, the only existing character set name which includes such a character is "NF_Z_62-010_(1973)".
+
# 每个字符集名称(或字符编码名称 -- 我们使用互换的条款) 应该是类型 NMTOKEN, 这里名称是由空格符号 #x20 分隔的, 造成一个标记话的属性类型 NMTOKENS (见 [http://www.w3.org/TR/REC-xml/ XML 1.0] [[XEP-0124#附录G:备注|20]] 的 3.3.1 章节). 严格地说, 由互联网编号分配机构(<http://www.iana.org/assignments/character-sets>)维护的字符集注册项允许一个字符集名称包含任何可打印的US-ASCII字符串, 它可能包含不被 XML 1.0的NMTOKEN构造所允许的字符串; 无论如何, 仅存的一个字符集名称包含这样的字符串的字符集是 "NF_Z_62-010_(1973)".
  
20. Extensible Markup Language (XML) 1.0 (Fourth Edition) <http://www.w3.org/TR/REC-xml/>.
+
# 可扩展的标记语言 (XML) 1.0 (第四版) <http://www.w3.org/TR/REC-xml/>.
  
21. 9007199254740991 is 253-1. Some weakly typed languages use IEEE Standard 754 Doubles to represent all numbers. These Doubles cannot represent integers above 253 accurately.
+
# 9007199254740991 等于 2的53次方-1. 一些弱类型的语言使用IEEE标准754 Doubles来表达所有数字. 这些 Doubles 不能准确表达所有超过 2的53次方的整数.
  
22. RFC 3174: US Secure Hash Algorithm 1 (SHA1) <http://tools.ietf.org/html/rfc3174>.
+
# RFC 3174: 使用安全哈希算法1 (SHA1) <http://tools.ietf.org/html/rfc3174>.
  
23. Therefore a client and a connection manager will be compatible even if one or the other offers no support for multi-stream sessions.
+
# 因此客户端和连接管理器将兼容,即使其中一个不提供对多流会话的支持.
  
24. The 'rid' attribute is always incremented normally without reference to any 'stream' attribute.
+
# 'rid'属性总是正常增加而不参考任何'stream'属性.
  
25. This helps to ensure backwards-compatibility with older implementations.
+
# 这帮助确保和旧的实现的向后兼容性.
  
26. Each HTTP response MUST belong to the same session as the request that triggered it, but not necessarily to the same stream.
+
# 每个HTTP应答必须属于该请求触发的同一个会话, 但是不需要是同一个流.
  
27. The broadcast payloads can be of any type.
+
# 广播的载荷可以使任何类型.
  
28. SSL V3.0 <http://wp.netscape.com/eng/ssl3/draft302.txt>.
+
# SSL V3.0 <http://wp.netscape.com/eng/ssl3/draft302.txt>.
  
29. RFC 2818: HTTP Over TLS <http://tools.ietf.org/html/rfc2818>.
+
# RFC 2818: 在TLS上的HTTP <http://tools.ietf.org/html/rfc2818>.
  
30. RFC 2817: Upgrading to TLS Within HTTP/1.1 <http://tools.ietf.org/html/rfc2817>.
+
# RFC 2817: 在HTTP/1.1中升级到TLS <http://tools.ietf.org/html/rfc2817>.
  
31. RFC 1750: Randomness Recommendations for Security <http://tools.ietf.org/html/rfc1750>.
+
# RFC 1750: 基于安全的随机性建议 <http://tools.ietf.org/html/rfc1750>.
  
32. RFC 4270: Attacks on Cryptographic Hashes in Internet Protocols <http://tools.ietf.org/html/rfc4270>.
+
# RFC 4270: 在互联网协议里对加密哈希的攻击 <http://tools.ietf.org/html/rfc4270>.
  
33. The Internet Assigned Numbers Authority (IANA) is the central coordinator for the assignment of unique parameter values for Internet protocols, such as port numbers and URI schemes. For further information, see <http://www.iana.org/>.
+
# 互联网编号分配机构 (IANA) 是对互联网协议的唯一参数值,类似端口号和URI规划,的分配的中央协调者. 更多信息, <http://www.iana.org/>.
  
34. IANA registry of port numbers <http://www.iana.org/assignments/port-numbers>.
+
# 端口号的IANA注册 <http://www.iana.org/assignments/port-numbers>.
  
35. XEP-0156: Discovering Alternative XMPP Connection Methods <http://xmpp.org/extensions/xep-0156.html>.
+
# XEP-0156: 查找替代的XMPP连接方法 <http://xmpp.org/extensions/xep-0156.html>.
===Appendix H: Revision History===
+
 
 +
===附录H:修订历史===
 +
 
 +
注意: 本协议的旧版本可能在 http://xmpp.org/extensions/attic/ 还可用
  
Note: Older versions of this specification might be available at http://xmpp.org/extensions/attic/
 
 
;Version 1.10 (2010-07-02)
 
;Version 1.10 (2010-07-02)
  
第1,376行: 第1,408行:
 
:(dss/psa)
 
:(dss/psa)
  
 +
-----
 
结束
 
结束

2013年7月8日 (一) 10:33的最后版本


本文的英文原文来自XEP-0124

XEP-0124: 基于同步HTTP的双向流

摘要: 本协议定义了一个传输协议来模拟两个实体 (例如一个客户端和一个服务器) 之间的长连双向TCP连接的语义,它有效地运用多个同步的HTTP"请求/应答"对,而不需要使用频繁的轮询或者分块响应.
作者: Ian Paterson, Dave Smith, Peter Saint-Andre, Jack Moffitt
版权: © 1999 - 2011 XMPP标准化基金会(XSF). 参见法律通告.
状态: 草案
类型: 标准跟踪
版本: 1.10
最后更新日期: 2010-07-02

注意: 这里定义的协议是XMPP标准化基金会的一个 草案标准 .对本协议的执行是被鼓励的,也适于部署到生产系统,但是在它成为最终标准之前可能还会有一些变动.


目录

简介

传输控制协议 (TCP; RFC 793 1 ) 经常用来建立两个实体之间的面向流的连接. 这些连接可以保持常连,使得实体之间的 "会话" 能够交互式的进行. 无论如何, 有时候设备或网络的性质可能会阻止一个应用程序去维护一个常连的TCP连接到一个服务器或对端. 在这种情况下, 需要使用一个替代的连接方法,使用排序的一系列请求和应答在短连的连接上交换信息来模拟常连的TCP连接. 通过 RFC1945 2RFC2616 3 定义的超文本传输协议(HTTP)可以获得很多可用的合适的 请求-应答 语义.

BOSH, 本文定义的这种技术, 实质上为常连的双向TCP连接提供了一个 "drop-in" 的替代品. 它是一个成熟的, 全功能的技术,自2004年以来已经被广泛实现和布署. 据我们所知它是众多类似技术中的第一个, 它现在包含了正规化的Bayeux协议 4 的 彗星(Comet) 方法(译者注:Comet就是Ajax web应用程序的服务器推送技术的结合),以及 Web Socket协议 5反向HTTP 6.

BOSH被设计成有效地传输任何数据并且在两个方向上都保持最小延迟. 对应用程序来讲那同时需要 "推" 和 "拉" 语义, BOSH显然比其他大多数双向的基于HTTP的传输协议更节省带宽和响应更迅速,这个技术现在通常称为 "Ajax". BOSH通过对多个同步的"HTTP请求/响应对"使用所谓"长轮询"来达到高效. 此外, 通过使用不需要"cookies"而全兼容HTTP 1.0 (见 RFC 2965 7 ) 8 或甚至访问HTTP头,BOSH可以解决受限客户端的需要 .

BOSH原本是由 Jabber/XMPP 社区开发出来替代更早的基于HTTP的技术 Jabber HTTP轮询 9 . 尽管BOSH假定HTTP请求和应答的 "载荷" 是XML, 载荷的格式未受XMPP节 (见 XMPP Core 10 ) 的限制,并且可以包含不同协议定义的命名空间的元素的混合物 (例如, 同时包含 XMPP 和 JSON). 这种混合是必要的,因为一些连接管理者可能不支持多重流,而受限的客户端经常无法访问HTTP流水线 (这限制同一时间只能拥有一个BOSH会话). BOSH连接管理者通常不需要理解它们所传输的XML的任何内容,除了确保每个XML载荷被正确的命名空间所限定.

注意: XMPP Over BOSH 11 记录了一些以前包含在本协议中的XMPP特有的扩展.

需求

以下的设计需求反映了提供接近标准TCP连接的性能的需要.

  1. 和受约束的运行时环境兼容* (例如, 手机和基于浏览器的客户端).
  2. 和缓冲了部分HTTP应答的代理兼容.
  3. 高效的通过那些限制HTTP响应时间的代理.
  4. 完全兼容HTTP/1.0.
  5. 兼容受限的网络连接 (例如, 防火墙, 代理, 以及网关).
  6. 容错 (例如, 在HTTP请求的任何阶段,底层TCP连接中断之后,会话恢复).
  7. 可扩展.
  8. 带宽消耗显著低于基于轮询的协议.
  9. 比基于轮询的协议显著快速响应 (低延迟).
  10. 支持轮询 (支持那些限制同一时间只有一个HTTP连接的客户端轮询).
  11. 顺序递送数据.
  12. 防范未经授权的用户会话注入HTTP请求.
  13. 防止拒绝服务攻击.
  14. 复用数据流.
  • 注意: 和受约束的运行环境兼容意味着以下限制:
  1. 客户端不需要编程访问每个HTTP请求和应答的头 (例如, cookies 或 状态码).
  2. 每个HTTP请求和应答的 body 是一个可解析的根元素的XML.
  3. 客户端可以指定它们接收的HTTP应答的 Content-Type.

架构假设

本文假定大部分实现使用专门的连接管理者 ("CM") 来处理HTTP连接,而非有关应用的本地连接类型 (例如, XMPP里的TCP连接). 为了效率, 这样一个连接管理者是一个专门的HTTP服务器,用来把这里定义的HTTP请求和应答和与之通讯的服务器实现的数据流(或API)之间进行翻译, 因此使得客户端能通过HTTP的80或443端口连接到一个服务器而不是一个特定应用的端口. 我们可以图形说明如下:

     服务器
       |
       |  [未封装的数据流]
       |
    HTTP连接管理器
       |
       |  [HTTP + <body/> 封装器]
       |
     客户端
   

本协议仅涵盖了客户端和连接管理器的通讯. 没有涉及连接管理器和服务器之间的通讯, 因为这类通讯是和特定实现相关的 (例如, 服务器可能原生支持HTTP绑定, 在这种情况下连接管理器是一个逻辑实体而不是物理实体; 另外连接管理器可以是独立翻译代理,这样该服务器认为它在直接和客户端通过TCP交谈; 或者连接管理器和服务器可能使用组件协议或服务器定义的API).

此外, 本协议并没有限定只用于客户端和服务器之间的通讯. 例如, 它可以用于服务器之间的通讯,如果有关的应用(例如, 在XMPP里)发生了这样的通讯. 无论如何, 本文只专注于那些无法和服务器随时维护持久的TCP连接的客户端传输的使用. 我们假定服务器和组件不受那些限制,并且因此相关的应用将使用原生的连接传输. (无论如何, 在一些不可靠的网络中, BOSH可以让服务器之间的通讯更加稳定.)

BOSH技术

因为HTTP是一个同步请求/应答协议, 传统的通过HTTP模拟双向流的解决方案是让客户端HTTP间歇性地轮询连接管理器来查询是否有任何等待发送给客户端的数据. 当没有数据需要传输的时候,这种幼稚的做法在轮询的时候浪费了很多网络带宽. 它也降低了应用程序的响应,因为数据要花时间排队直到连接管理器从客户端接收下一次轮询 (HTTP 请求) . 这导致了响应速度和带宽之间难免顾此失彼, 因为增加轮询频率将在减少延迟的同时增加带宽消耗 (如果轮询频率降低的话,反之亦然).

BOSH使用的技术通过鼓励连接管理器在它确实有数据发送给客户端之前不去应答请求,同时达到低延迟和低带宽消耗的目的. 一旦客户端从连接管理器接收到一个应答,它发送另一个请求, 从而确保连接管理器 (几乎) 总是持有一个可以用来 "推送" 数据给客户端的请求.

如果客户端需要发送一些数据给连接管理器,那么它只要简单地发送第二个包含数据的请求. 不幸的是大部分受约束的客户端不支持HTTP流水线 (通过单个的连接的并发请求), 所以客户端通常需要通过第二个HTTP连接发送这个数据. 连接管理器总是应答它持有的第一个连接的请求,一旦从客户端接收到一个新的请求 -- 甚至即使没有数据发送给客户端. 它这么做可以确保客户端能在必要的时候立刻发送更多数据. (客户端同一时间不应该打开超过两个HTTP连接到连接管理器, 12 ,否则它不得不等待连接管理器应答请求中的一个.)

即使网络情况迫使每个HTTP请求都要通过不同的TCP连接,BOSH也会可靠地工作. 无论如何, 如果经常发生这种情况, 客户端可以使用HTTP/1.1, 然后 (假定网络情况稳定) 一个会话中的所有请求将在同样的两个持久TCP连接上通过. 几乎任何时候 (见下文) 客户端都可以推送数据到这两个连接中的一个, 而连接管理器能推送数据到另一个连接 (所以延迟和一个标准的TCP连接一样低). 有意思的是,注意这两个连接的角色每当客户端发送数据到连接管理器的时候就会互换.

如果在一个规定时间内(通常是几分钟)两个方向上都没有流量, 那么连接管理器以无数据来应答客户端, 并且那个应答立即触发一个新的客户端请求. 连接管理器这么做来确认是否网络连接已经中断,并且双方都在一个合理的时间内明白到这一点. 这一交换类似大部分持久TCP连接中的通用的 "keep-alive" 或 "ping" . 因为BOSH技术未使用轮询, 带宽消耗不会比标准TCP连接大很多. 13

大部分时候数据可以被立刻推送. 无论如何, 如果其中一个端点刚推送了一些数据,在它再次推送之前将不得不等待网络往返. 如果客户端可以使用HTTP流水线,那么就可以拥有多个并发的请求了. 这样客户端就总能立刻推送数据了. 它也能保证连接管理器总是持有足够的请求,这样甚至在连续发送的时候它也绝不需要在发送数据之前等待. 此外, 如果连接管理器持有的请求池太大, 那么客户端从连接管理器接收数据之后在压力之下将不能立刻发送一个新的空请求. 它只能等待,除非需要发送数据. 所以, 如果随着时间的推移,客户端接收和发出的流量平衡了, 带宽消耗将和使用标准的TCP连接相同.

连接管理器推送的每一个数据块都是一个完整的HTTP应答. 所以, 和Comet技术不像, BOSH技术是通过中间代理缓冲部分HTTP请求来工作的. 它也完全兼容HTTP/1.0 -- 不提供分块传输编码.

HTTP概述

所有信息被编码到标准的HTTP POST请求和应答的body中. 每个HTTP body包含一个单独的 <body/> 封装器用来封装被传输的XML元素 (见 XEP-0124#<body/>封装器元素 ).

客户端应该使用HTTP流水线通过一个持久的HTTP/1.1连接发送所有的HTTP请求. 不过, 客户端也可以用任何 RFC 1945RFC 2616 允许的方式递送这些POST请求. 例如, 受约束的客户端可能期望打开不止多个持久连接而不是使用HTTP流水线, 或者在某些情况下打开一个新的HTTP/1.0连接来发送每个请求. 无论如何, 客户端和连接管理器不应该使用分块传输编码, 因为中间代理可能缓冲每部分的HTTP请求或应答并且在可以发送的时候只传输完整的请求或应答.

客户端可以在任何请求中包含一个HTTP Accept-Encoding头. 如果连接管理器接收到一个拥有Accept-Encoding头的请求, 它可以在应答中包含一个HTTP Content-Encoding头 (指定请求中说明的编码之一) 并据此压缩应答body.

请求和应答可以包含未在本文提到的HTTP头. 接收者应该忽略那些HTTP头.

每个BOSH会话可以分享其他用途的HTTP流量的HTTP连接, 包括其他BOSH会话以及和本协议完全无关的HTTP请求和应答 (例如, web页面下载). 无论如何, 使用HTTP流水线通过同一个连接对不是本会话一部分的请求的应答(或同一个连接中的发送队列)可能会导致对于本会话的一部分的请求的应答的延迟 (因为连接管理器必须以和接收到的请求相同的顺序来发送它的应答, 并且连接管理器通常会延迟它的某些应答).

所有客户端请求的HTTP Content-Type头应该是 "text/xml; charset=utf-8". 无论如何, 如果客户端受到某些约束,它们也可以指定其他的值 (例如, "application/x-www-form-urlencoded" 或 "text/plain"). 客户端和连接管理器应该忽略所有接收到的HTTP Content-Type头.

<body/>封装器元素

每个HTTP请求和应答的body包含一个单独的由 'http://jabber.org/protocol/httpbind' 命名空间限定的<body/>封装器元素. 这个封装器的内容就是被传输的数据. <body/>元素和它的内容都必须符合 XML 1.0 14 的一系列规格. 它们也应该符合 Namespaces in XML 15. 内容必须不包含任何以下的东西 (都定义于 XML 1.0 ):

  • 部分XML元素
  • XML注释
  • XML处理指令
  • 内部或外部DTD亚群
  • 内部或外部实体引用 (预定义的实体除外)

<body/>封装器必须不包含任何XML字符串数据, 尽管它的子元素可以包含字符串数据. <body/>封装器必须包含零或多个完整的XML直接子元素(本文称为 "载荷" , 例如, 定义于 RFC 6120 的XMPP节或使用定义于 RFC 4627 16 的JSON数据交换格式来代表对象的包含XML字符串数据的元素).每个<body/>封装器可以包含各种广泛的命名空间限定的载荷.

每个客户端请求的<body/>元素必须拥有一个通过'rid'属性封装的顺序的请求ID; 具体信息, 参考本文的 请求IDs 章节.

发起BOSH会话

会话创建请求

从客户端到连接管理器的第一个请求是请求一个新的会话.

第一个请求的<body/>元素应该拥有以下属性 (它们应该不被包含在其他请求中,除非在 添加流到一个会话 时候指定):

  • 'to' -- 这个属性指定第一个流的目标域.
  • 'xml:lang' -- 这个属性 (定义于 XML 1.0 17 的2.12) 指定会话期间发送或接收的任何人类可读的字符串数据的缺省语言.
  • 'ver' -- 这个属性指定客户端支持的BOSH协议的最高版本. 编号方案是 "<主版本号>.<小版本号>" (这里小版本号可以递增到不止一位数子, 所以它必须被当成一个单独的整数来处理). 注意: 'ver' 属性应该不被误解成任何正被传输的协议的版本.
  • 'wait' -- 这个属性指定连接管理器在会话中应答任何请求之前被允许的等待时间(以秒计数). 这使客户端能限制它察觉任何网络失败之前的延迟, 并且阻止它的HTTP/TCP连接因为不活跃而过期.
  • 'hold' -- 这个属性指定连接管理器在会话中被允许同时保持的请求的最大数量. 如果客户端不能使用HTTP流水线那么它应该设为 "1".

注意: 仅支持轮询会话的客户端可以通过设置'wait' 或 'hold' 为 "0" 来阻止连接管理器等待. 无论如何, 轮询是不推荐的,因为带宽消耗的增加和响应能力的降低都会达到一到两个数量级!

连接管理器可以被配置成允许在不同的域里和多个服务器进行会话. 当以一个"代理"连接管理器请求一个会话的时候, 客户端应该包含一个'route'属性来指定它想通讯的服务器的协议, 主机名, 和端口, 格式为 "proto:host:port" (例如, "xmpp:example.com:9999"). 18 一个配置成只和一个 (或只和预定义的域列表以及服务于那些域的相关主机和端口列表的) 服务器配合工作的连接管理器可以忽略 'route' 属性. (注意 'to' 属性指定服务的域, 而不是服务于那个域的机器的主机名.)

第一个请求的 <body/> 元素也可以拥有 'from' 属性, 它指定第一个流的发起者并允许连接管理器转发发起者实体的身份到应用服务器 (例如, 连接到一个XMPP服务器上的实体的 JabberID ; 见 XEP-0206 ).

客户端可以包含一个 'ack' 属性 (设为 "1") 来指示它将在会话中始终使用确认机制并且任何请求中缺少'ack'属性都是有特定意义的 (见 确认 ).

一些客户端被约束只能接受特定Content-Types (例如, "text/html")的HTTP应答. 第一个请求的<body/>元素可以拥有一个'content'属性. 它指定在会话期间必须在所有连接管理器的应答中出现的HTTP Content-Type头的值. 如果该客户端请求没有'content'属性, 那么应答的HTTP Content-Type头必须是"text/xml; charset=utf-8".

示例1. 请求一个BOSH会话

POST /webclient HTTP/1.1
Host: httpcm.example.com
Accept-Encoding: gzip, deflate
Content-Type: text/xml; charset=utf-8
Content-Length: 104
 
<body content='text/xml; charset=utf-8'
      from='user@example.com'
      hold='1'
      rid='1573741820'
      to='example.com'
      route='xmpp:example.com:9999'
      ver='1.6'
      wait='60'
      ack='1'
      xml:lang='en'
      xmlns='http://jabber.org/protocol/httpbind'/>

注意: 在第一个之后的所有请求必须包含一个有效的'sid'属性 (由连接管理器在会话创建应答中提供). 发起方请求是唯一的,在那个<body/>元素中必须没有'sid'属性.

会话创建应答

在接收到到一个新的会话请求之后, 连接管理器必须生成一个不透明的不可预测的会话标识符 (或称为 SID). 这个SID在该连接管理器应用中的上下文中必须是唯一的. 该连接管理器对客户端的会话创建请求的应答中的 <body/> 元素必须拥有以下属性 (它们应该不被包含在任何其他应答中):

  • 'sid' -- 该属性指定SID
  • 'wait' -- 这是连接管理器在会话期间应答任何请求之前等待的最长时间 (以秒计数) . 这个时间必须小于或等于该会话请求的指定的值.

<body/>元素也应该包含以下属性 (它们应该不被包含在任何其他应答中):

  • 'ver' -- 这个属性指定连接管理器支持的BOSH协议的最高版本, 或客户端在它的请求中指定的版本, 取其中较低的版本.
  • 'polling' -- 这个属性指定最小可允许的轮询间隔(以秒计数). 这使得客户端不需要以超出预期的频率发送空的请求元素 (见 轮询会话过度活跃 ).
  • 'inactivity' -- 这个属性指定最长可允许的闲置期时间(以秒计数). 这使客户端能确保没有请求待发的时间段永远不会太长 (见 轮询会话闲置 ).
  • 'requests' -- 这个属性使得连接管理器能限制客户端产生的并发请求的数量 (见 过度活跃轮询会话 ). 推荐的值是 "2" 或者比会话请求中指定的'hold' 属性值大一.
  • 'hold' -- 这个属性通知客户端连接管理器在会话期间的任何时间将会保持等待的请求的最大数量. 这个值必须不大于客户端在会话请求中指定的值.
  • 'to' -- 这个属性指定客户端尝试连接的后台服务器的通讯身份.

连接管理器可以在会话创建应答元素中包含一个'accept'属性, 来指定一个以空格分隔的可被解压的内容编码的列表. 在接收到一个带有'accept'属性的会话创建应答之后, 客户端可以在随后的请求中包含一个HTTP Content-Encoding头 (指示 'accept' 属性指定的编码之一) 并且据此压缩该请求的bodies.

连接管理器可以包含一个'ack'属性 (值设为会话创建请求中的'rid'属性值) 来指示它将在该会话中始终使用确认机制,并且任何应答中缺少'ack'属性都是有特定意义的 (见 确认 ).

如果连接管理器支持会话暂停 (见 闲置 ) 那么它应该通过在会话创建应答元素中包含一个'maxpause'属性来向客户端声明. 这个属性的值指示客户端可以请求的一个临时会话暂停的最大长度(以秒计数) .

对请求和应答都一样, <body/>元素和它的内容应该以UTF-8编码. 如果请求/应答的HTTP Content-Type头指定了一个不同于UTF-8的字符编码, 那么连接管理器可以在UTF-8和该字符编码之间转换. 无论如何, 即使在这种情况下, 连接管理器转换编码也是可选的. 连接管理器可以通知客户端哪些编码它能够转换,通过在会话创建应答元素中设置可选的'charsets'属性为以空格分隔的编码列表. 19

一旦连接管理器建立了一个连接到服务器并发现它的身份, 它可以在应答中包含一个'from'属性来转发这个身份给客户端, 要么在它的会话创建应答中, 要么 (如果那个时候它还没有从服务器接收到它的身份) 任何随后给客户端的应答中. 如果它建立了一个安全连接到服务器 (定义于 发起BOSH会话 ), 那么在同一个应答中连接管理器也应该包含'secure'属性并把值设为 "true" 或 "1".

示例2. 会话创建应答

HTTP/1.1 200 OK
Content-Type: text/xml; charset=utf-8
Content-Length: 128
 
<body wait='60'
      inactivity='30'
      polling='5'
      requests='2'
      hold='1'
      ack='1573741820'
      accept='deflate,gzip'
      maxpause='120'
      sid='SomeSID'
      charsets='ISO_8859-1 ISO-2022-JP'
      ver='1.6'
      from='example.com'
      xmlns='http://jabber.org/protocol/httpbind'/>

示例3. 随后的包含'from'和'secure'属性的应答

HTTP/1.1 200 OK
Content-Type: text/xml; charset=utf-8
Content-Length: 128
 
<body from='example.com'
      xmlns='http://jabber.org/protocol/httpbind'/>

发送和接收XML载荷

客户端成功完成所有必需的前提条件之后, 它就可以通过HTTP绑定来发送和接收XML载荷了.

示例4. 传输载荷

POST /webclient HTTP/1.1
Host: httpcm.example.com
Accept-Encoding: gzip, deflate
Content-Type: text/xml; charset=utf-8
Content-Length: 188
 
<body rid='1249243562'
      sid='SomeSID'
      xmlns='http://jabber.org/protocol/httpbind'>
  <message to='contact@example.com'
           xmlns='jabber:client'>
    <body>Good morning!</body>
  </message>
  <message to='friend@example.com'
           xmlns='jabber:client'>
    <body>Hey, what&apos;s up?</body>
  </message>
</body>

在收到一个请求之后,一旦有可能连接管理器应该转发<body/>元素的内容到服务器. 在任何情况下它必须按照它们的'rid'属性指定的顺序来从不同的请求转发内容.

连接管理器也必须在<body/>元素中返回一个HTTP 200 OK应答给客户端. 注意: 这并不表示载荷已经被成功发送到应用服务器.

建议连接管理器在载荷已经从服务器到达客户端之前不要返回HTTP结果. 无论如何, 连接管理器不应该让等待时间超过客户在它的会话创建请求中指定的'wait'属性的值 , 而且在同一时间它保持的HTTP请求数量不应该多于会话创建请求中的'hold'属性的值. 任何情况下它必须以它们的'rid'属性指定的顺序来应答请求.

如果在等待周期里没有载荷等待或准备好发送, 那么连接管理器应该在HTTP结果中包含一个空的<body/>元素:

示例5. 空应答

HTTP/1.1 200 OK
Content-Type: text/xml; charset=utf-8
Content-Length: 64
 
<body xmlns='http://jabber.org/protocol/httpbind'/>

如果连接管理器已经从应用服务器收到一个或多个载荷要发送给客户端, 那么在它从服务器收到它们之后一旦有可能它应该立即在它的应答的body中返回这些载荷. 以下这个例子包含被不同命名空间限定的载荷:

示例6. 排队节的应答

HTTP/1.1 200 OK
Content-Type: text/xml; charset=utf-8
Content-Length: 185
 
<body xmlns='http://jabber.org/protocol/httpbind'
      xmlns:json='http://json.org/'>
  <message from='contact@example.com'
           to='user@example.com'
           xmlns='jabber:client'>
    <body>Good morning to you!</body>
  </message>
  <message from='friend@example.com'
           to='user@example.com'
           xmlns='jabber:client'>
    <body>Not much, how about with you?</body>
  </message>
  <json:json>
  [
    {
      "precision": "zip",
      "Latitude":  37.7668,
      "Longitude": -122.3959,
      "Address":   "",
      "City":      "SAN FRANCISCO",
      "State":     "CA",
      "Zip":       "94107",
      "Country":   "US"
    },
    {
      "precision": "zip",
      "Latitude":  37.371991,
      "Longitude": -122.026020,
      "Address":   "",
      "City":      "SUNNYVALE",
      "State":     "CA",
      "Zip":       "94085",
      "Country":   "US"
    }
  ]
  </json:json>
</body>

客户端可以通过发送空的<body/>元素来轮询连接管理器的输入节.

示例7. 请求XML载荷

POST /webclient HTTP/1.1
Host: httpcm.example.com
Accept-Encoding: gzip, deflate
Content-Type: text/xml; charset=utf-8
Content-Length: 88
 
<body rid='1249243563'
      sid='SomeSID'
      xmlns='http://jabber.org/protocol/httpbind'/>

连接管理器必须以和它从客户端接收载荷同样的方法等待并回应.

确认

请求确认

当应答一个保持的请求时, 如果连接管理器发现它已经接收了另一个更高'rid'属性的请求(通常此时它正在保持第一个请求), 那么它可以向客户端确认已收到. 当连接管理器也接收了所有更低的'rid'属性的请求时,它可以设置任何应答的 'ack' 属性高于它已经接收到的最高的'rid'属性.

示例8. 应答请求的确认

HTTP/1.1 200 OK
Content-Type: text/xml; charset=utf-8
Content-Length: 64
 
<body ack='1249243564'
      xmlns='http://jabber.org/protocol/httpbind'/>

如果连接管理器在一个会话过程中将要包含'ack'属性, 那么它必须在它的会话创建应答中包含一个'ack'属性, 并且在会话过程中始终设置应答的'ack'属性. 唯一的例外是, 在它的会话创建应答之后, 如果这个值和任何要应答的请求的'rid'值相同,连接管理器不应该包含一个'ack'属性在应答之中.

如果连接管理器被允许同一时间保持多个请求, 那么从连接管理器收到低于预期的'ack'值(或意外的缺少'ack'属性)可以给客户端一个可能发生网络失败的早期预警(例如, 如果客户端认为连接管理在它应答的时候应该已经接收到了另一个请求).

应答确认

客户端可以同样通过把任何请求的'ack'属性值设为它已经接收到的的应答的最高'rid'值(此时它也已经接收了所有拥有更低'rid'值的应答)来通知连接管理器它已经收到了应答. 如果客户端在一个会话中要在请求中包含'ack'属性, 那么它必须在它的会话创建请求中包含一个'ack'属性(值为'1'), 并且在会话中始终设置请求的'ack'属性. 唯一的例外是, 在它的会话创建请求之后, 如果客户端已经接收到所有在它之前的请求的应答,那么客户端不应该包含一个'ack'属性到任何请求.

示例9. 请求应答确认

POST /webclient HTTP/1.1
Host: httpcm.example.com
Accept-Encoding: gzip, deflate
Content-Type: text/xml; charset=utf-8
Content-Length: 88
 
<body rid='1249243566'
      sid='SomeSID'
      ack='1249243564'
      xmlns='http://jabber.org/protocol/httpbind'/>

在接收到一个'ack'值低于最后一个已应答请求的'rid'值的请求时, 连接管理器可以通过立即发送它的下一个应答而不是等到它有需要发送给客户端的载荷的时候才发送应答(例如, 假如从它应答的时候到现在已经过了一段时间),以此告知客户端这种情况. 在这种情况下它应该包含一个'report'属性并把值设为高于它从客户端接收到的'ack'属性, 而'time'属性则设为它发送'report'相关应答的时间,以毫秒计数.

示例10. 应答报告

HTTP/1.1 200 OK
Content-Type: text/xml; charset=utf-8
Content-Length: 64
 
<body report='1249243565'
      time='852'
      xmlns='http://jabber.org/protocol/httpbind'/>

在收到一个拥有'report'和'time'属性的应答之后, 如果客户端仍未收到'report'属性指定的请求id相关的应答, 那么它可以选择重发这个丢失的应答相关的请求 (见 断开的连接 ).

闲置

从连接管理器接收到一个应答之后, 如果没有客户端请求继续被连接管理器保持 (并且如果会话不是一个轮询会话), 客户端应该一有可能就制造一个新的请求. 在任何情况下, 如果没有请求被hold住, 客户端必须在最大闲置时间过期之前制造一个新的请求. 这个时间段(以秒计数) 是在会话创建应答中的'inactivity'属性定义的.

如果连接管理器已经应答了一个会话中它所接收到的所有请求并且从最后一次应答到当前的时间超过最大闲置时间段, 那么它应该假定客户端已经失去连接并且不通知客户端就终止这个会话. 如果接下来客户端再制造另一个请求, 那么连接管理器应该像这个会话不存在一样来应答.

如果连接管理器在会话创建应答里没有指定一个最大闲置时间, 那么它应该允许客户端选择它的闲置时间.

如果会话不是轮询会话那么连接管理器应该指定一个相对短的闲置时间来确保尽可能快的发现断链. 建议的时间应该比连接管理器和客户端在困难的网络条件下一次顺利的网络往返的秒数多一点 (因为可以期待客户端立刻制造一个新请求 -- 见上文).

如果客户端遇到意外的临时状况,在此期间它将不能在最大闲置时间之内发送请求到连接管理器(例如, 当运行时环境从一个web页面变成另一个页面), 并且如果连接管理器在它的会话创建应答中包含了'maxpause'属性, 那么客户端可以通过在一个请求中包含'pause'属性来请求临时增加最大闲置时间的. 注意: 如果连接管理器没有在会话开始的时候定义一个'maxpause'属性那么客户端不能在会话期间发送'pause'属性.

示例11. 请求会话暂停

POST /webclient HTTP/1.1
Host: httpcm.example.com
Accept-Encoding: gzip, deflate
Content-Type: text/xml; charset=utf-8
Content-Length: 98
 
<body rid='1249243564'
      sid='SomeSID'
      pause='60'
      xmlns='http://jabber.org/protocol/httpbind'/>

接收到一个会话暂停请求之后, 如果请求的时间段不超过最大允许时间, 那么连接管理器应该立刻应答所有未决的请求(包括暂停请求)并临时增加最大限制时间到请求的时间. 注意: 对暂停请求的应答不能包含任何载荷.

注意: 如果客户端简单地希望连接管理器返回所有它保持住的请求,那么它可以把'pause'属性值设为连接管理器的会话请求应答中的'inactivity'属性值. (如果客户端认为它有无限期断线的危险,那么它甚至可以通过指定一个小于'inactivity'值的'pause'值来请求临时减少闲置时间, 这样使得连接管理器能快速发现接下来的断链.)

连接管理器应该在从客户端接到下一个请求之前(假定连接管理器尚未终止该会话)把闲置时间设回正常.

过度活跃

客户端不应该制造超过连接管理器的会话创建应答中的'requests'属性定义数量的并发请求. 无论如何,如果客户端暂停或终止一个会话,它可以制造一个额外的请求.

如果在任何时间段客户端发送系列的新请求(也就是说请求的rid属性是增长的, 而不是重复的请求)超过了'requests'属性指定的数量, 并且如果连接管理器尚未应答这些请求中的任何一个, 并且如果最后一次请求既不包含一个'pause'属性也不包含一个值为"terminate"的'type'属性, 那么连接管理器应该认为客户端正在制造过多的并发请求, 并且发一个'policy-violation'终止绑定错误给客户端来终止该HTTP会话. 注意: 这个行为同时适用于普通和轮询会话.

示例12. 过多并发请求应答

HTTP/1.1 200 OK
Content-Type: text/xml; charset=utf-8
Content-Length: 68
 
<body type='terminate'
      condition='policy-violation'
      xmlns='http://jabber.org/protocol/httpbind'/>

注意: 如果连接管理器在会话创建应答中没有指定一个'requests'属性, 那么它必须允许客户端按它选择的数量来发送并发请求.

如果在任何时间段客户端发送系列新请求等于'requests'属性指定的数量, 并且如果连接管理器尚未应答这些请求中的任何一个, 并且如果最后一次请求既不包含一个'pause'属性也不包含一个值为"terminate"的'type'属性, 并且最后两个请求到达的时间差小于创建会话应答中的'polling'属性定义的值, 那么连接管理器应该认为客户端正在制造超过它允许的频率的请求并且发一个'policy-violation'终止绑定错误给客户端来终止该HTTP会话. 注意: 这个行为对于轮询会话略有不同.

示例13. 过于频繁的请求应答

HTTP/1.1 200 OK
Content-Type: text/xml; charset=utf-8
Content-Length: 68
 
<body type='terminate'
      condition='policy-violation'
      xmlns='http://jabber.org/protocol/httpbind'/>

注意: 如果连接管理器在会话创建应答中未定义'polling'属性, 那么它必须允许客户端按它选择的频率来发送请求.

轮询会话

对一个受约束的客户端来说不一定总是能使用HTTP流水线或在同一时间和连接管理器打开多个HTTP连接. 在这种情况下客户端应该在它的会话创建请求中把'wait' 和/或 'hold' 属性值设为"0"来通知连接管理器, 并且然后在会话中始终有规律地"轮询"连接管理器来获得它可能从服务器收到的载荷. 注意: 即使客户端不请求一个轮询会话, 连接管理器可以通过设置它的 会话创建应答 的'requests'属性(它指定客户端能制造的并发请求的数量)为"1"来要求一个客户端使用轮询, 无论如何这是不推荐的.

如果一个会话将使用轮询, 连接管理器应在它的会话创建应答中指定一个高于普通值的'inactivity'属性(见 闲置 ) . 这个增加值应该大于它指定的'polling'属性值.

如果客户端在一个低于会话创建应答中'polling'属性(允许的最短轮询间隔)指定的秒数的时间段内发送两个连续的空的新请求(也就是说请求的rid属性是增加的, 而不是重复的请求), 并且如果连接管理器应答的第一个请求不包含载荷, 那么在收到第二个请求之后连接管理器应该终止HTTP会话并返回一个'policy-violation'终止绑定错误给客户端.

示例14. 过于频繁的轮询应答

HTTP/1.1 200 OK
Content-Type: text/xml; charset=utf-8
Content-Length: 68
 
<body type='terminate'
      condition='policy-violation'
      xmlns='http://jabber.org/protocol/httpbind'/>

注意: 如果连接管理器在会话创建应答中未指定'polling'属性, 那么它必须允许客户端按它选择的频率来轮询.

终止HTTP会话

任何时候, 客户端可以发送一个'type'属性为"terminate"的<body/>元素来正常地终止会话. 终止请求可以包含一个或多个载荷,连接管理器必须转发给服务器以确保正常的注销登录.

示例15. 来自客户端的会话终止

POST /webclient HTTP/1.1
Host: httpcm.example.com
Accept-Encoding: gzip, deflate
Content-Type: text/xml; charset=utf-8
Content-Length: 153
 
<body rid='1249243565'
      sid='SomeSID'
      type='terminate'
      xmlns='http://jabber.org/protocol/httpbind'>
  <presence type='unavailable'
            xmlns='jabber:client'/>
</body>

连接管理器应该用一个包含空的<body/>元素的HTTP 200 OK来应答这个请求 .

示例16. 连接管理器确认终止

HTTP/1.1 200 OK
Content-Type: text/xml; charset=utf-8
Content-Length: 72
 
<body type='terminate'
      xmlns='http://jabber.org/protocol/httpbind'/>

在接收到该应答后, 客户端必须认为该HTTP会话已经被终止.

请求IDs

生成

客户端必须生成一个大的, 随机的, 正整数用于初始的'rid' (见 安全事项 ) ,并且随后的每个请求的rid做加一的处理. 客户端必须小心选择一个初始的'rid',在整个会话中它的值不能够加到超过 9007199254740991 21 . 在实践中, 一个会话可能被迫变得非常长 (或涉及到非常多的包交换) 以至于超过定义的限制.

顺序的消息转发

当一个客户端制造了并发请求, 连接管理器可能没能按顺序接收到它们. 连接管理器必须按照'rid'属性指定的顺序来转发载荷到服务器并应答客户端的这些请求. 客户端必须按照请求的顺序来处理从连接管理器接收到的应答.

连接管理器应该期望'rid'属性值在一个大于前一个请求的数值窗内. 这个数值窗等于连接管理器允许的最大并发请求数量. 如果它接收到的请求的'rid'大于这个数值窗, 那么连接管理器必须以一个错误来终止会话:

示例17. 意外的rid错误

HTTP/1.1 200 OK
Content-Type: text/xml; charset=utf-8
Content-Length: 68
 
<body type='terminate'
      condition='item-not-found'
      xmlns='http://jabber.org/protocol/httpbind'/>

断开的连接

不可靠的网络通讯或客户端约束可能造成断开的连接. 连接管理器应该记住'rid'以及相应的那些客户端的非暂停请求(见 [[XEP-0124#闲置|闲置]] )和非HTTP或绑定错误的请求的HTTP应答. 保持在缓冲之中的对于非暂停请求的应答的数量应该和连接管理器允许的并发请求数量相同, 或者,如果使用了确认机制, 则和还未确认的应答数量相同.

如果网络连接中断或在客户端接收到连接管理器对于某个请求的应答之前关闭了, 那么客户端刻一重新发送一个原请求的精确副本. 任何时候连接管理器发现收到的请求的'rid已经接收过, 它应该返回一个包含缓冲区的原有XML应答的 HTTP 200 (OK) 应答给客户端 (也就是说, 一个封装了了拥有适当属性以及可选的包含一个或多个XML载荷的<body/>). 如果原有的应答不可用 (例如, 它已经不在缓冲区了), 那么连接管理器必须返回一个 'item-not-found' 终止绑定错误:

示例18. 应答不在缓冲区错误

HTTP/1.1 200 OK
Content-Type: text/xml; charset=utf-8
Content-Length: 68
 
<body type='terminate'
      condition='item-not-found'
      xmlns='http://jabber.org/protocol/httpbind'/>

注意: 无论这个'rid'是过大还是过小,错误都是一样的. 这使得攻击者更难搜索到可接受的值.

保护不安全的会话

适用性

如果客户端和连接管理器之间的会话不安全,可以使用这里描述的可选的密钥序列机制. 只有所有客户端请求都是通过 SSL(或 TLS) HTTP连接并且连接管理器生成了一个不可预知的会话ID,该会话才应该被认为是安全的. 如果会话是安全的, 则不需要使用这个密钥序列机制.

即使会话不安全, 本文前述章节定义的意外会话和请求IDs已经通过把连接绑定到一对持久TCP/IP连接的方法来提供了一个类似级别的保护,并且因此提供了防止'盲'绑定的足够保护. 无论如何, 在某些环境下, 以下定义的密钥序列机制帮助抵御了更多确定的和有知识的攻击者.

重要的是要认识到以下定义的密钥序列机制只帮助我们保护抵御一个能在一个序列的不安全会话中看到所有请求或应答但不能修改那些请求的内容(在这种情况下, 这个机制阻止攻击者插入HTTP请求到会话, 例如, 终止请求或应答)的攻击者. 无论如何, 当攻击者能修改不安全的请求或应答的内容时,密钥序列机制不提供任何保护.

简述

每个会话的HTTP请求可以通过一系列不同的socket连接来散播. 这将使得一个未经授权的收到该会话ID和会话请求ID的用户能够使用他们自己的socket连接来插入<body/>请求元素到会话中并接收相应的应答.

以下的密钥序列机制通过允许连接管理器探查第三方插入的<body/>请求元素来抵御这类攻击.

生成密钥序列

在请求一个新的会话之前, 客户端必须选择一个不可预知的计数器 ("n") 和一个不可预知的值 ("seed"). 然后客户端通过把这个"seed"做一次加密哈希运算并从160位转换成一个十六进制字符串 K(1). 它运算 "n" 次然后得到发起密钥 K(n). 这个哈希算法必须是 SHA-1 定义于 RFC 3174 22 .

示例19. 创建密钥序列

       K(1) = hex(SHA-1(seed))
       K(2) = hex(SHA-1(K(1)))
       ...
       K(n) = hex(SHA-1(K(n-1)))

使用密钥

客户端必须把该会话中第一个请求的 'newkey' 属性值设为 K(n).

示例20. 携带发起密钥的会话请求

POST /webclient HTTP/1.1
Host: httpcm.example.com
Accept-Encoding: gzip, deflate
Content-Type: text/xml; charset=utf-8
Content-Length: 104
 
<body content='text/xml; charset=utf-8'
      hold='1'
      rid='1573741820'
      to='example.com'
      wait='60'
      xml:lang='en'
      newkey='ca393b51b682f61f98e7877d61146407f3d0a770'
      xmlns='http://jabber.org/protocol/httpbind'/>

客户端必须把所有接下来的请求的 'key' 属性值设为按生成顺序的下一个密钥 (每个请求发送的值从 K(n-1) 向 K(1) 衰减).

示例21. 携带密钥的请求

POST /webclient HTTP/1.1
Host: httpcm.example.com
Accept-Encoding: gzip, deflate
Content-Type: text/xml; charset=utf-8
Content-Length: 88
 
<body rid='1573741821'
      sid='SomeSID'
      key='bfb06a6f113cd6fd3838ab9d300fdb4fe3da2f7d'
      xmlns='http://jabber.org/protocol/httpbind'/>

连接管理器可以通过运算密钥的 SHA-1 哈希并把它和前一个请求的 'newkey' 属性(或者如果没有'newkey' 属性则为 'key' 属性)进行比较来证实密钥. 如果这个值不匹配 (或者如果接收到一个不带 'key' 属性的请求,以及接收到的是前一个请求所设的 'newkey' 或 'key' 属性), 那么连接管理器必须不处理该元素, 必须终止该会话, 并且必须返回一个 'item-not-found' 终止绑定错误.

示例22. 非法的密钥序列错误

HTTP/1.1 200 OK
Content-Type: text/xml; charset=utf-8
Content-Length: 68
 
<body type='terminate'
      condition='item-not-found'
      xmlns='http://jabber.org/protocol/httpbind'/>

切换到另一个密钥序列

生成密钥序列的时候,客户端应该选择一个高的 "n" 值. 无论如何, 如果会话太长以至于客户端在序列 K(1) 中达到最后的密钥, 那么客户端必须切换到一个新的密钥序列.

客户端必须:

  1. 选择新的 "seed" 和 "n" 值.
  2. 使用上文定义的机制生成一个新的密钥序列.
  3. 把该请求的 'key' 属性设为旧的序列的下一个值 (也就是说 K(1), 最后的值).
  4. 把该请求的 'newkey' 属性设为新的序列的值 K(n).

示例23. 新密钥序列

POST /webclient HTTP/1.1
Host: httpcm.example.com
Accept-Encoding: gzip, deflate
Content-Type: text/xml; charset=utf-8
Content-Length: 188
 
<body rid='1573741822'
      sid='SomeSID'
      key='6f825e81f4532b2c5fa2d12457d8a1f22e8f838e'
      newkey='113f58a37245ec9637266cf2fb6e48bfeaf7964e'
      xmlns='http://jabber.org/protocol/httpbind'>
  <message to='contact@example.com'
           xmlns='jabber:client'>
    <body>I said "Hi!"</body>
  </message>
</body>

多重流

简介

本章描述的可选特性允许在一个HTTP会话中包含多重XML流. 这个特性实质上用于那些不允许HTTP流水线的运行时环境中, 此时一个客户端能和每个连接管理器打开的并发HTTP请求的数量是受限的, 如果他们在同一时间使用不止一个帐号连接,那么运行于这类环境下的客户端需要多重流会话. 这个特性对于任何通过HTTP建立了并联流的客户端来说也降低了网络流量.

查询

如果一个连接管理器支持多重流特性, 它必须在它的会话创建应答中包含一个'stream'属性. 如果一个客户端不接受这个'stream'属性,那么它必须假定连接管理器不支持该特性. 23

这个 'stream' 属性标识该会话打开的第一个流. 每个 'stream' 属性的值必须是一个无意义的不可预知的名字,并且在连接管理器应用的上下文中是唯一的.

示例24. 携带流名字(stream name)的会话创建应答

HTTP/1.1 200 OK
Content-Type: text/xml; charset=utf-8
Content-Length: 128
 
<body wait='60'
      inactivity='30'
      polling='5'
      requests='2'
      hold='1'
      accept='deflate,gzip'
      stream='firstStreamName'
      maxpause='120'
      sid='SomeSID'
      charsets='ISO_8859-1 ISO-2022-JP'
      ver='1.6'
      from='example.com'
      xmlns='http://jabber.org/protocol/httpbind'/>

添加流到会话

如果连接管理器在它的会话创建应答中包含了一个 'stream' 属性,那么客户端可以在任何时间发送一个空的带有'to'属性的<body/>元素来请求它打开另一个流. 请求必须包含合法的'sid'和'rid' 24 属性, 并且也应该包含一个 'xml:lang' 属性. 请求可以包含 'route', 'from' 和 'secure' 属性 (见 |会话创建请求 ), 但是它不应该包含 'ver', 'content', 'hold' 或 'wait' 属性 (因为并没有创建一个新的会话).

示例25. 请求另一个流

POST /webclient HTTP/1.1
Host: httpcm.example.com
Accept-Encoding: gzip, deflate
Content-Type: text/xml; charset=utf-8
Content-Length: 104
 
<body sid='SomeSID'
      rid='1573741820'
      to='example.com'
      route='xmpp:example.com:9999'
      xml:lang='en'
      xmlns='http://jabber.org/protocol/httpbind'/>

如果连接管理器没有在会话的开始表示它支持多重流, 那么它必须忽略额外的属性并且和对待普通的用于载荷的空请求一样对待该请求(见 发送和接收XM载荷 ). 25 否则它必须打开一个新的流到指定的服务器 (见 会话创建应答 ), 生成一个新的流名字, 并以此名字应答客户端. 应答也可以包含 'from' 和 'secure' 属性, 但是它不应该包含 'sid', 'requests', 'polling', 'hold', 'inactivity', 'maxpause', 'accept', 'charsets', 'ver' 或 'wait' 属性.

示例26. 添加流应答

HTTP/1.1 200 OK
Content-Type: text/xml; charset=utf-8
Content-Length: 128
 
<body stream='secondStreamName'
      from='example.com'
      xmlns='http://jabber.org/protocol/httpbind'/>

注意: 如果应答既不包含 'from' 也不包含 'secure' 属性,那么它们可以留待接下来的应答中被发送 (见 会话创建应答 ). 在那种情况下 'stream' 属性也是必须指定的.

传送载荷

如果在一个会话中不止打开一个流, 那么被连接管理器发送的所有非空的<body/>元素必须包含'stream'属性,它定义所有的载荷属于哪个流. 客户端应该包含一个'stream'属性用于同样的目的. 如果客户端希望连接管理器广播这些载荷给所有打开的流,它可以忽略'stream'属性. 注意: 一个<body/>元素在不同的流中必须不能包含不同的载荷.

如果一个流名字不符合该会话打开的流之一, 那么接收到的连接管理器应该返回一个 'item-not-found' 终止绑定错误, 或者接收到的客户端应该终止这个会话. 无论如何, 如果接收到的实体只是关闭这个流 (并且发送者可能在它发送这个载荷的时候没有留意), 那么它可以简单安静地忽略该<body/>元素包含的任何载荷.

注意: 不包含'from'或'secure'属性的空的<body/>元素不应该包含'stream'属性(因为任何流都没有东西正在传送). 如果这样的一个<body/>元素包含了一个'stream'属性,那么接收到的实体应该忽略该属性.

示例27. 客户端以一个流名字发送载荷

POST /webclient HTTP/1.1
Host: httpcm.example.com
Accept-Encoding: gzip, deflate
Content-Type: text/xml; charset=utf-8
Content-Length: 188
 
<body rid='1249243562'
      sid='SomeSID'
      stream='secondStreamName'
      xmlns='http://jabber.org/protocol/httpbind'>
  <message to='contact@example.com'
           xmlns='jabber:client'>
    <body>I said hello.</body>
  </message>
</body>

注意: 该应答的'stream'属性值可以和响应请求的不同. 26

示例28. 连接管理器应答一个不同的流名字

HTTP/1.1 200 OK
Content-Type: text/xml; charset=utf-8
Content-Length: 185
 
<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>

如果连接管理器没有指定流名字,那么客户端必须假定载荷是和第一个流相关的(即使第一个流已经关闭了).

如果客户端没有指定一个流名字,那么连接管理器必须广播载荷给所有打开的流. [27]

示例29. 客户端请求一个载荷被广播

POST /webclient HTTP/1.1
Host: httpcm.example.com
Accept-Encoding: gzip, deflate
Content-Type: text/xml; charset=utf-8
Content-Length: 188
 
<body rid='1249243562'
      sid='SomeSID'
      xmlns='http://jabber.org/protocol/httpbind'>
  <presence xmlns='jabber:client'>
    <show>away</show>
  </presence>
</body>

关闭流

如果在一个会话中打开了不止一个流, 客户端可以在任何时间使用上文 终止HTTP会话 描述的程序关闭一个流, 小心地在'stream'属性指定该流的名字. 如果客户端关闭了最后一个流,连接管理器必须终止该会话. 如果客户端没有指定一个流名字那么连接管理器必须关闭所有打开的流 (发送该终止请求的任何载荷到所有流), 并终止该会话.

示例30. 客户端关闭一个流

POST /webclient HTTP/1.1
Host: httpcm.example.com
Accept-Encoding: gzip, deflate
Content-Type: text/xml; charset=utf-8
Content-Length: 153
 
<body rid='1249243564'
      sid='SomeSID'
      stream='secondStreamName'
      type='terminate'
      xmlns='http://jabber.org/protocol/httpbind'>
  <presence type='unavailable'
            xmlns='jabber:client'/>
</body>

错误条件

如果在一个会话中不止打开了一个流, 连接管理器可以在致命绑定错误中包含一个'stream'属性(见 终止绑定条件 ). 如果指定了'stream'属性,那么该流必须被双方实体关闭但是会话不应该被终止.

示例31. 致命流错误

HTTP/1.1 200 OK
Content-Type: text/xml; charset=utf-8
Content-Length: 68
 
<body type='terminate'
      condition='remote-connection-failed'
      stream='secondStreamName'
      xmlns='http://jabber.org/protocol/httpbind'/>

注意: 如果连接管理器在致命流错误中不包含'stream'属性,那么会话的所有的打开的流都必须被双方实体关闭并且会话必须被终止.

错误和状态代码

在HTTP应答中有四种类型的错误和状态报告:

表1: 错误条件类型

错误条件 描述
HTTP条件 (已过时) 连接管理器应答从传统客户端来的非法请求一个HTTP错误. 这用于绑定语法错误, 可能的攻击, 等等. 注意受约束的客户端不能区分不同的HTTP错误.
终止绑定条件 这些错误条件可以被受约束的客户端读取. 他们用于连接管理器问题, 抽象流错误, 连接管理器和服务器之间的通讯问题, 以及非法客户端请求 (绑定语法错误, 可能的攻击, 等等.)
可恢复的绑定条件 这些报告连接管理器和客户端之间的通讯问题. 它们不终止会话. 客户端通过重新发送前面所有的未收到应答的<body/>封装器来从这些错误恢复.
被传输的协议的条件 和<body/>封装器中的XML载荷有关的错误, 通常定义于被传输的协议的文档中. 它们不终止会话.

完整的描述在下面.

HTTP条件

注意: 除了200所有HTTP代码已经被终止绑定条件取代,以使客户端能确定错误的来源是连接管理器应用还是HTTP媒介.

传统的客户端(或连接管理器)在它的会话创建请求(或应答)中是不包含'ver'属性的. 传统客户端(或连接管理器)将根据下表来解释(或应答) HTTP错误码. 非传统连接管理器应该不发送HTTP错误码,除非它们连接的是一个传统客户端. 在接收到一个HTTP错误(400, 403, 404)之后, 一个传统客户端或任何连接到传统连接管理器的客户端必须认为该会话为空的和无用的(null and void). 一个连接到非传统连接管理器的非传统客户端可以认为该会话仍活跃.

表2: HTTP错误和状态码

代码 名称 被...取代 目的
200 OK - 应答给合法的客户端请求.
400 Bad Request bad-request 通知客户端一个HTTP头的格式或绑定的元素是不可接受的(例如, 语法错误).
403 Forbidden policy-violation 通知客户端它违反了会话规则(轮询太频繁, 请求太频繁, 太多并发请求).
404 Not Found item-not-found 通知客户端 (1) 'sid' 不合法, (2) 'stream' 不合法, (3) 'rid' 大于期望的窗口上限, (4) 连接管理器不能重发应答, (5) 'key' 顺序不合法.

注意: 没有其他定义在早期版本BOSH里的HTTP错误和状态码 (例如, Internal Server Error).

终止绑定条件

在任何发送到客户端的应答里, 连接管理器可以通过把<body/>元素的'type'属性值设为"terminate"来返回一个致命错误. 这些绑定错误标识该HTTP会话被终止了(除非定义了一个'stream'属性 -- 见 多重流错误条件 ).

注意: 尽管这些条件中的一部分类似定义于 RFC 6120 的XMPP流错误条件, 它们不会被XMPP流错误混淆. 在这里BOSH是用于传输XMPP, 在连接管理器和XMPP服务器之间经历的任何致命XMPP流错误条件只会被用下面描述的"remote-stream-error"条件来报告.

示例32. 远程连接失败错误

HTTP/1.1 200 OK
Content-Type: text/xml; charset=utf-8
Content-Length: 68
 
<body type='terminate'
      condition='remote-connection-failed'
      xmlns='http://jabber.org/protocol/httpbind'/>

'condition'属性的值定义如下:

表3: 终止绑定错误条件

条件 目的
bad-request* T一个HTTP头或从客户端收到的绑定元素的格式不可接受(例如, 语法错误).
host-gone 连接管理器的'to'属性指定的目标域或'route'属性指定的目标主机或端口不再提供服务.
host-unknown 连接管理器的'to'属性指定的目标域或'route'属性指定的目标主机或端口是未知的.
improper-addressing 发起元素缺少'to'或'route'属性(或属性没有值)但是连接管理器需要它.
internal-server-error 连接管理器经历了一个内部错误导致它无法为请求提供服务.
item-not-found* (1) 'sid'不合法, (2) 'stream'不合法, (3) 'rid' 大于期望窗口的上限, (4) 连接管理器不能重发应答, (5) 'key' 序列非法.
other-request 和这个请求请求想同的另一个请求导致该会话终止.
policy-violation* 客户端违反了会话规则(轮询太频繁, 请求太频繁, 发送了过多的并发请求).
remote-connection-failed 连接管理器无法连接, 或无法安全地连接, 或已经丢失了它的连接, 到服务器.
remote-stream-error 封装了一个正在传输的协议的错误.
see-other-uri 连接管理器不执行这个URI(例如, 连接管理器只接受客户端以类似 https: URI 而不是类似 the http: URI 的请求以SSL或TLS连接). 客户端可以尝试 POSTing 到<uri/>子元素内含的那个 URI .
system-shutdown 连接管理器正在关闭. 所有激活的HTTP会话正在被终止. 不能创建新的会话.
undefined-condition 这个错误不是在这里定义的那些错误之一; 连接管理器应该在这个<body/>封装器的内容里包含 应用特有的 信息.

* 如果客户端在它的会话创建请求中未包含一个'ver'属性,那么连接管理器应该发送一个已过时的HTTP错误而不是这个终止绑定错误条件. 如果连接管理器在它的会话创建应答中未包含'ver'属性,那么客户端应该预期它会发送一个已过时的HTTP错误条件而不是这个终止会话绑定条件.

以下是一个 "see-other-uri" 条件的例子:

示例33. 参见另一个URI错误

HTTP/1.1 200 OK
Content-Type: text/xml; charset=utf-8
Content-Length: 68
 
<body condition='see-other-uri'
      type='terminate'
      xmlns='http://jabber.org/protocol/httpbind'>
  <uri>https://secure.jabber.org/xmppcm</uri>
</body>

以下是一个包含"remote-stream-error"条件的例子:

示例34. 远程错误

HTTP/1.1 200 OK
Content-Type: text/xml; charset=utf-8
Content-Length: 68
 
<body condition='remote-stream-error'
      type='terminate'
      xmlns='http://jabber.org/protocol/httpbind'
      xmlns:stream='http://etherx.jabber.org/streams'>
  <message from='contact@example.com'
           to='user@example.com'
           xmlns='jabber:client'>
    <body>I said "Hi!"</body>
  </message>
  <stream:error>
    <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'/>
  </stream:error>
</body>

自然的, 客户端同样可以报告绑定错误给连接管理器, 尽管这是这是不太可能的.

可恢复的绑定条件

在任何连接管理器发送给客户端的应答中, 它可以通过设置<body/>元素的'type'属性为"error"来返回一个可恢复的错误. 这些错误不表示HTTP会话被终止.

如果客户端决定从这个错误回复, 那么它必须重复那个发生错误的HTTP请求, 以及所有前面没有收到应答的HTTP请求. 这些请求的内容必须和原始请求的<body/>元素相同. 这使连接管理器在前一个请求因为通讯失败而丢失之后能恢复一个会话.

示例35. 可恢复的错误

HTTP/1.1 200 OK
Content-Type: text/xml; charset=utf-8
Content-Length: 68
 
<body type='error'
      xmlns='http://jabber.org/protocol/httpbind'/>

XML载荷条件

应用级的错误条件描述请参看正在被传输并通过连接管理器路由到客户端的那个协议的文档. 它们对连接管理器来说是透明的, 所以超过了这里定义的传输绑定的范围.

实现备注

HTTP流水线

即使客户端请求HTTP流水线并且连接管理器支持它, 也不保证流水线能成功, 因为它可能不被中间代理支持.

客户端能做到最好的是通过设置'hold'属性的值为"1"来请求使用HTTP流水线. 如果HTTP流水线没生效(因为服务器返回 HTTP 1.0 或 connection:close), 那么客户端应该降格为使用多重连接.

安全事项

在客户端和BOSH服务之间连接

客户端和BOSH服务之间的所有通讯应该发生在加密的HTTP连接之上. 客户端和连接管理器之间的加密应该发生在传输层或HTTP层, 而不是应用层; 这个协商应该遵循定义于 SSL 28 的 HTTP/SSL 协议, 当然也可以遵循定义于 RFC 2818 29 的 HTTP/TLS 协议或定义于 RFC 2817 30 的基于HTTP协议的TLS.

如果用来发送发起会话请求的HTTP连接是加密的, 那么该会话中使用的所有其他HTTP连接也必须是加密的. 此外, 如果当建立用来发送发起会话请求的加密连接的时候交换了验证证书, 那么客户端 和/或 连接管理器应该确保在该会话接下来的所有连接中使用同一个验证证书. 一旦这样一个 "安全会话" 被建立:

  • 如果连接管理器拒绝简历一个加密连接或提供了不同的证书, 那么客户端应该关闭连接并终止会话而不发送任何更多的请求.
  • 如果客户端通过一个未加密的连接或使用了一个不同的证书发送了属于某个"安全会话"一部分的封装元素, 那么连接管理器应该简单地关闭该连接. 连接管理应该不终止该会话,因为那将使拒绝服务攻击更容易.

BOSH和应用之间的连接

一个BOSH服务应该使用适当的技术例如安全套接字层(SSL),传输层安全(TLS)以及StartTLS(如果后台程序支持的话) 等等来加密它到后台应用的连接. 另外, BOSH 服务在以下情形中可以被认为安全 (1) 如果它运行在和后台应用同一个物理机上 或 (2) 如果它运行在和后台应用同一个私有网络上并且管理员确信未知的个人或程序不能访问私有网络.

如果数据隐私是必需的, 客户端应该使用一个应用级别的点对点加密技术来加密它的消息, 因为客户端没办法确信BOSH服务加密了它到该应用的连接; 这些方法超出了本协议的范围.

不可预测的SID和RID

会话标识符(SID)和发起请求标识符(RID)是安全的关键所以都必须是不可预测的和不重复的(见 RFC 1750 31 的关于为了安全目的对SIDs和发起RIDs的随机性的建议).

使用SHA-1

最近的研究显示,在选定的情况下,使用SHA-1哈希算法来产生哈希值是最有可能的(见 RFC 4270 32 ). 无论如何, 在BOSh中使用SHA-1看起来会最小化该文献描述的可能的攻击. 另外, 目前的评估表明,在经常发现的攻击中, 它将耗费政府级实体的运算能力一年才可能出现问题.

IANA事项

TCP端口5280, 传统上用于BOSH客户端和BOSH连接管理器的通讯, 已经注册到 互联网编号分配机构(IANA) 33 在它的 IANA端口号码注册表 34 的端口注册表里 , 关键词为 "xmpp-bosh". (尽管这个端口的使用是可选的, 定义这个端口有助于标准化,这样BOSH客户端可以通过BOSH联系任何一个给定的XMPP服务而不需要 查找替代的XMPP连接方法 35 描述的 DNS TXT 记录或更多先进的方法例如 U-NAPTR.

XMPP注册事项

协议命名空间

在它的协议命名空间注册项中包含了 'http://jabber.org/protocol/httpbind' 的XMPP注册项.

XML Schema

<?xml version='1.0' encoding='UTF-8'?>
 
<xs:schema
    xmlns:xs='http://www.w3.org/2001/XMLSchema'
    xmlns:stream='http://etherx.jabber.org/streams'
    targetNamespace='http://jabber.org/protocol/httpbind'
    xmlns='http://jabber.org/protocol/httpbind'
    elementFormDefault='qualified'>
 
  <xs:annotation>
    <xs:documentation>
      The protocol documented by this schema is defined in
      XEP-0124: http://www.xmpp.org/extensions/xep-0124.html
    </xs:documentation>
  </xs:annotation>
 
  <xs:import namespace='http://www.w3.org/XML/1998/namespace'
             schemaLocation='http://www.w3.org/2001/03/xml.xsd'/>
 
  <xs:element name='body'>
    <xs:complexType>
      <xs:choice>
        <xs:element name='uri'
                minOccurs='0'
                maxOccurs='1'
                type='xs:string'/>
        <xs:any namespace='##other'
                minOccurs='0'
                maxOccurs='unbounded'
                processContents='lax'/>
      </xs:choice>
      <xs:attribute name='accept' type='xs:string' use='optional'/>
      <xs:attribute name='ack' type='xs:positiveInteger' use='optional'/>
      <xs:attribute name='authid' type='xs:string' use='optional'/>
      <xs:attribute name='charsets' type='xs:NMTOKENS' use='optional'/>
      <xs:attribute name='condition' use='optional'>
        <xs:simpleType>
          <xs:restriction base='xs:NCName'>
            <xs:enumeration value='bad-request'/>
            <xs:enumeration value='host-gone'/>
            <xs:enumeration value='host-unknown'/>
            <xs:enumeration value='improper-addressing'/>
            <xs:enumeration value='internal-server-error'/>
            <xs:enumeration value='item-not-found'/>
            <xs:enumeration value='other-request'/>
            <xs:enumeration value='policy-violation'/>
            <xs:enumeration value='remote-connection-failed'/>
            <xs:enumeration value='remote-stream-error'/>
            <xs:enumeration value='see-other-uri'/>
            <xs:enumeration value='system-shutdown'/>
            <xs:enumeration value='undefined-condition'/>
          </xs:restriction>
        </xs:simpleType>
      </xs:attribute>
      <xs:attribute name='content' type='xs:string' use='optional'/>
      <xs:attribute name='from' type='xs:string' use='optional'/>
      <xs:attribute name='hold' type='xs:unsignedByte' use='optional'/>
      <xs:attribute name='inactivity' type='xs:unsignedShort' use='optional'/>
      <xs:attribute name='key' type='xs:string' use='optional'/>
      <xs:attribute name='maxpause' type='xs:unsignedShort' use='optional'/>
      <xs:attribute name='newkey' type='xs:string' use='optional'/>
      <xs:attribute name='pause' type='xs:unsignedShort' use='optional'/>
      <xs:attribute name='polling' type='xs:unsignedShort' use='optional'/>
      <xs:attribute name='report' type='xs:positiveInteger' use='optional'/>
      <xs:attribute name='requests' type='xs:unsignedByte' use='optional'/>
      <xs:attribute name='rid' type='xs:positiveInteger' use='optional'/>
      <xs:attribute name='route' type='xs:string' use='optional'/>
      <xs:attribute name='sid' type='xs:string' use='optional'/>
      <xs:attribute name='stream' type='xs:string' use='optional'/>
      <xs:attribute name='time' type='xs:unsignedShort' use='optional'/>
      <xs:attribute name='to' type='xs:string' use='optional'/>
      <xs:attribute name='type' use='optional'>
        <xs:simpleType>
          <xs:restriction base='xs:NCName'>
            <xs:enumeration value='error'/>
            <xs:enumeration value='terminate'/>
          </xs:restriction>
        </xs:simpleType>
      </xs:attribute>
      <xs:attribute name='ver' type='xs:string' use='optional'/>
      <xs:attribute name='wait' type='xs:unsignedShort' use='optional'/>
      <xs:attribute ref='xml:lang' use='optional'/>
      <xs:anyAttribute namespace='##other' processContents='lax'/>
    </xs:complexType>
  </xs:element>
 
</xs:schema>

致谢

感谢 Mike Cumings, Tomas Karasek, Tobias Markmann, Chris Seymour, Safa Sofuoğlu, Stefan Strigler, Matthew Wild, Kevin Winters, 以及 Christopher Zorn 的反馈.

附录

附录A:文档信息

系列:XEP

序号:0124

发布者:XMPP标准基金会

状态:草案

类型:标准跟踪

版本:1.10

最后更新时间:2010-07-02

批准机构:XMPP理事会

依赖标准:RFC 1945, RFC 2616, RFC 3174

替代标准:无

被替代标准:无

缩略名:bosh

Schema: <http://www.xmpp.org/schemas/httpbind.xsd>

原文控制: HTML

本文的其它格式: XML PDF

Appendix B: Author Information

Ian Paterson

Email: ian.paterson@clientside.co.uk
JabberID: ian@zoofy.com

Dave Smith

Email: dizzyd@jabber.org
JabberID: dizzyd@jabber.org

Peter Saint-Andre

Email: stpeter@jabber.org
JabberID: stpeter@jabber.org
URI: https://stpeter.im/

Jack Moffitt

Email: jack@chesspark.com
JabberID: jack@chesspark.com

附录C:法律通告

  • 版权
XMPP扩展协议的版权(1999 - 2011)归XMPP标准化基金会(XSF)所有.
  • 权限
特此授权,费用全免,对任何获得本协议副本的人,对使用本协议没有限制,包括不限制在软件程序中实现本协议,不限制在网络服务中布署本协议,不限制拷贝,修改,合并,发行,翻译,分发,转授,或销售本协议的副本,被允许使用本协议做了以上工作的人士,应接受前述的版权声明和本许可通知并且必须包含在所有的副本或实质性部分的规格中.除非单独的许可,被重新分发的修改工作,不得含有关于作者,标题,编号,或出版者的规格的误导性资料,并不得宣称修改工作是由本文的作者,作者所属的任何组织或项目,或XMPP标准基金会签注。
  • 免责声明
##特别注意:本协议是提供的“原样”的基础,没有担保或任何形式的条件,明示或暗示,包括,但不限于任何担保或关于名称,非侵权性,适销性或适合作某一特定目的的条件. ##
  • 责任限制
在任何情况下以及没有任何法律规定时,不论是侵权行为(包括疏忽),合同或其它方面,除非根据适用法律的要求(如蓄意和有严重疏忽行为)或以书面形式同意,XMPP标准基金会或任何作者不对本协议所造成的损失承担责任,包括任何直接,间接,特殊,偶发,或任何从本协议出,入,连接的字符产生的或实现,布署或其他对本协议的使用导致的相应的损害赔偿(包括但不限于善意的损失,停止作业,电脑失灵或故障,或任何和所有其他商业损害或损失) ,即使XMPP标准基金会或作者已被告知此类损害的可能性。
  • 知识产权的一致性
XMPP扩展协议完全遵守XSF的知识产权策略(可在<http://www.xmpp.org/extensions/ipr-policy.shtml>找到副本或写信给XMPP标准基金会, 1899 Wynkoop Street, Suite 600, Denver, CO 80202 USA).

附录D:和XMPP的关系

可扩展的消息和出席信息协议 (XMPP) 定义于 XMPP Core (RFC 3920) 和 XMPP IM (RFC 3921) 规范里,由 XMPP标准基金会贡献到由依据RFC 2026成立的互联网工程人物组管理的互联网标准流程 Internet Standards Process. 本文定义的任何协议已在互联网标准流程之外开发,并且被理解为 XMPP 的扩展而不是一个XMPP本身的演化, 开发, 或修改.

附录E:讨论地点

主要的XMPP扩展协议讨论地点是 <standards@xmpp.org> 讨论列表.

在 xmpp.org 的其它讨论列表中的讨论可能也有合适的; 所有的列表见 <http://xmpp.org/about/discuss.shtml> .

Given that this XMPP Extension Protocol normatively references IETF technologies, discussion on the <xsf-ietf@xmpp.org> list might also be appropriate.

勘误表可以发送邮件到 <editor@xmpp.org>.

附录F:需求一致性

以下用于本文的需求关键字的解释见于 RFC 2119: "MUST", "SHALL", "REQUIRED"; "MUST NOT", "SHALL NOT"; "SHOULD", "RECOMMENDED"; "SHOULD NOT", "NOT RECOMMENDED"; "MAY", "OPTIONAL".

附录G:备注

  1. RFC 793: 传输控制协议 <http://tools.ietf.org/html/rfc0793>.
  1. RFC 1945: 超文本传输协议 -- HTTP/1.0 <http://tools.ietf.org/html/rfc1945>.
  1. RFC 2616: 超文本传输协议 -- HTTP/1.1 <http://tools.ietf.org/html/rfc2616>.
  1. Bayeux协议 <http://svn.cometd.org/trunk/bayeux/bayeux.html>.
  1. Web套接字协议 <http://tools.ietf.org/html/draft-hixie-thewebsocketprotocol>.
  1. 反向HTTP <http://tools.ietf.org/html/draft-lentczner-rhttp>.
  1. RFC 2965: HTTP状态管理机制 <http://tools.ietf.org/html/rfc2965>.
  1. 要求cookies是次优的,因为很多重要的计算平台只提供底层HTTP请求/应答的有限访问; 更坏的是, 一些平台或者移除了cookie相关的头.
  1. XEP-0025: Jabber HTTP轮询 <http://xmpp.org/extensions/xep-0025.html>.
  1. RFC 6120: 可扩展的消息和出席信息协议 (XMPP): 核心 <http://tools.ietf.org/html/rfc6120>.
  1. XEP-0206: 在BOSH上的XMPP <http://xmpp.org/extensions/xep-0206.html>.
  1. 为了减少网络拥塞, RFC 2616 建议客户端在同一时间不应该和同一台HTTP服务器保持超过两个HTTP连接. 运行在受约束的环境的客户端通常没有机会选择而只能遵守该建议.
  1. 如果没有"pings"之外的流量,那么带宽拥塞将是单个TCP连接的两倍(尽管加倍空仍然是空). 如果被发送的数据是一些大的包,那么带宽拥塞情况也是几乎一致的.
  1. 可扩展标记语言 (XML) 1.0 (第四版) <http://www.w3.org/TR/REC-xml/>.
  1. XML的名字空间 <http://www.w3.org/TR/REC-xml-names/>.
  1. RFC 4627: 用于JavaScript对象符号(JSON) 的 应用程序/json 媒体类型 <http://tools.ietf.org/html/rfc4627>.
  1. 可扩展的标记语言 (XML) 1.0 (第四版) <http://www.w3.org/TR/REC-xml/>.
  1. 尽管'route'属性的语法粗看起来和一个URI或IRI相似, 它不是一个 URI/IRI 并且不可按照 RFC 3986, RFC 3987, 或 (用于XMPP) RFC 5122 定义的规则来处理.
  1. 每个字符集名称(或字符编码名称 -- 我们使用互换的条款) 应该是类型 NMTOKEN, 这里名称是由空格符号 #x20 分隔的, 造成一个标记话的属性类型 NMTOKENS (见 XML 1.0 20 的 3.3.1 章节). 严格地说, 由互联网编号分配机构(见 <http://www.iana.org/assignments/character-sets>)维护的字符集注册项允许一个字符集名称包含任何可打印的US-ASCII字符串, 它可能包含不被 XML 1.0的NMTOKEN构造所允许的字符串; 无论如何, 仅存的一个字符集名称包含这样的字符串的字符集是 "NF_Z_62-010_(1973)".
  1. 可扩展的标记语言 (XML) 1.0 (第四版) <http://www.w3.org/TR/REC-xml/>.
  1. 9007199254740991 等于 2的53次方-1. 一些弱类型的语言使用IEEE标准754 Doubles来表达所有数字. 这些 Doubles 不能准确表达所有超过 2的53次方的整数.
  1. RFC 3174: 使用安全哈希算法1 (SHA1) <http://tools.ietf.org/html/rfc3174>.
  1. 因此客户端和连接管理器将兼容,即使其中一个不提供对多流会话的支持.
  1. 'rid'属性总是正常增加而不参考任何'stream'属性.
  1. 这帮助确保和旧的实现的向后兼容性.
  1. 每个HTTP应答必须属于该请求触发的同一个会话, 但是不需要是同一个流.
  1. 广播的载荷可以使任何类型.
  1. SSL V3.0 <http://wp.netscape.com/eng/ssl3/draft302.txt>.
  1. RFC 2818: 在TLS上的HTTP <http://tools.ietf.org/html/rfc2818>.
  1. RFC 2817: 在HTTP/1.1中升级到TLS <http://tools.ietf.org/html/rfc2817>.
  1. RFC 1750: 基于安全的随机性建议 <http://tools.ietf.org/html/rfc1750>.
  1. RFC 4270: 在互联网协议里对加密哈希的攻击 <http://tools.ietf.org/html/rfc4270>.
  1. 互联网编号分配机构 (IANA) 是对互联网协议的唯一参数值,类似端口号和URI规划,的分配的中央协调者. 更多信息, 见 <http://www.iana.org/>.
  1. 端口号的IANA注册 <http://www.iana.org/assignments/port-numbers>.
  1. XEP-0156: 查找替代的XMPP连接方法 <http://xmpp.org/extensions/xep-0156.html>.

附录H:修订历史

注意: 本协议的旧版本可能在 http://xmpp.org/extensions/attic/ 还可用

Version 1.10 (2010-07-02)
Further clarified use of 'from' and 'to' attributes; added missing condition values to the schema.
(psa)
Version 1.9 (2009-11-06)
Added information for registration of port 5280 with IANA.
(psa)
Version 1.8 (2009-04-30)
Removed secure attribute because it did not solve the problem it was intended to solve; added security consideration regarding link between connection manager and application server; changed "stanza" to "payload" for disambiguation with XMPP; clarified design objectives and relationship to similar technologies; corrected several errors in the schema.
(psa/jm)
Version 1.7 (2008-10-29)
Moved alternative script syntax to historical specification; added implementation note about HTTP Pipelining; adjusted architectural description.
(psa)
Version 1.6 (2007-02-21)
Multiple clarifications and restructuring without changes to protocol itself; changed title to BOSH; added section that fully explains the technique underlying the protocol; separated XMPP-specific features into new XEP-0206; added optional new Script Syntax and session pauses; added Acknowledgements section; added from and ver attributes; added hold attribute to session creation response; clarified polling too-frequently error; recommended that clients use HTTP Pipelining.
(ip)
Version 1.5 (2006-04-28)
Added optional Multiple Streams section; added security considerations about encrypted HTTP connections; recommended use of SSL rather than HTTP over TLS; specified that request ID values must not exceed 9007199254740991; corrected datatypes of inactivity, polling, rid, and wait attributes in the schema; added <any/> and <anyAttribute/> elements to schema to optionally support non-XMPP XML elements and attributes; deprecated HTTP error codes in favor of new terminal binding conditions.
(ip/psa)
Version 1.4 (2005-12-14)
Modified syntax of route attribute to be proto:host:port rather than XMPP URI/IRI.
(psa)
Version 1.3 (2005-11-02)
Corrected stream:features namespace and the Recoverable Binding Conditions section; recommended that connection manager shall return secure attribute to client; recommended end-to-end encryption through proxy connection managers.
(ip)
Version 1.2 (2005-06-16)
Specified optional use of route and secure attributes in session request. Minor correction: the stream features element should be included in the response that contains the authid attribute (this is not necessarily the session creation response).
(ip)
Version 1.1 (2005-06-02)
Specified optional use of HTTP Accept-Encoding and Content-Encoding headers for compression at HTTP binding level.
(ip)
Version 1.0 (2005-03-03)
Per a vote of the Jabber Council, advanced status to Draft.
(psa)
Version 0.10 (2004-11-08)
Changed HTTP 401 errors to HTTP 404.
(ip)
Version 0.9 (2004-10-26)
Added charset attribute.
(ip/psa)
Version 0.8 (2004-10-26)
Specified that wait attribute must be included in the session creation response.
(ip)
Version 0.7 (2004-08-12)
Defined appropriate XMPP stanza error conditions.
(psa/ip)
Version 0.6 (2004-07-19)
Added xml:lang attribute to the session request; added recoverable binding error conditions.
(ip)
Version 0.5 (2004-05-07)
Protocol refactored to enable simultaneous requests (request identifier attribute, wait attribute, hold attribute, requests attribute) and recovery of broken connections; added content attribute; removed all wrapper types except 'terminate'; updated error handling; made key mechanism optional (should use SSL/TLS instead).
(ip/psa)
Version 0.4 (2004-02-23)
Fixed typos; removed "resource-constraint" binding error; added HTTP 403 error to table.
(psa/ip)
Version 0.3 (2004-02-19)
Added 'authid' attribute to enable communication of XMPP stream ID (used in digest authentication); specified that Content-Types other than "text/xml" are allowed to support older HTTP clients; specified business rule for connection manager queueing of client requests; changed <packet/> to <body/> to support older HTTP clients; changed 'to' attribute on initialization element from MAY to SHOULD; recommended inclusion of unavailable presence in termination element sent from client; described architectural assumptions; specified binding-specific error handling.
(psa/ip)
Version 0.2 (2004-01-13)
Added 'to' attribute on the initialization element; specified that 'text/html' is allowable for backwards-compatibility.
(dss/psa/ip)
Version 0.1 (2003-11-06)
Initial version.
(dss/psa)

结束

个人工具