WebSocket 协议RFC6455中文翻译版word版.docx
《WebSocket 协议RFC6455中文翻译版word版.docx》由会员分享,可在线阅读,更多相关《WebSocket 协议RFC6455中文翻译版word版.docx(25页珍藏版)》请在冰豆网上搜索。
WebSocket协议RFC6455中文翻译版word版
WebSocket协议(RFC6455)中文翻译版(word版)
翻译自:
http:
//tools.ietf.org/rfc/rfc6455.txt
InternetEngineeringTaskForce(IETF)I.Fette
RequestforComments:
6455Google,Inc.
Category:
StandardsTrackA.Melnikov
ISSN:
2070-1721IsodeLtd.December2011
WebSocket协议
摘要
WebSocket协议使在控制环境下运行不受信任代码的客户端和能够选择与那些代码通信的远程主机之间能够双向通信。
用于这个的安全模型是以origin为基础的安全模型,一般被浏览器使用。
协议包含打开握手,其次是基本消息框架,在TCP之上。
这项技术的目的是为基于浏览器的、需要与服务器双向通信的应用程序提供一种不依赖于打开多个HTTP连接的机制(例如,使用XMLHttpRequest或
本备忘录的状态
这是一个Internet标准跟踪文件。
这个文档是因特网工程师任务组(IETF)的一个产品。
它代表了IETF社区的共识。
它已接受公众审查,因特网工程指导组(IESG)证明可出版。
关于互联网标准的进一步信息在RFC5741的第2章节。
关于本文档当前状态的信息、勘误表和如何提供反馈,可以在http:
//www.rfc-editor.org/info/rfc6455找到。
版权声明
Copyright(c)2011IETFTrustandthepersonsidentifiedasthedocumentauthors.Allrightsreserved.
ThisdocumentissubjecttoBCP78andtheIETFTrust’sLegalProvisionsRelatingtoIETFDocuments(http:
//trustee.ietf.org/license-info)ineffectonthedateofpublicationofthisdocument.Pleasereviewthesedocumentscarefully,astheydescribeyourrightsandrestrictionswithrespecttothisdocument.CodeComponentsextractedfromthisdocumentmustincludeSimplifiedBSDLicensetextasdescribedinSection4.eoftheTrustLegalProvisionsandareprovidedwithoutwarrantyasdescribedintheSimplifiedBSDLicense.
1介绍
1.1背景
这部分是不规范的。
历史上,创建需要在客户端和服务器间双向通信的网络应用程序(如即时消息和游戏程序)要求滥用HTTP来轮询服务器来获得更新,通过不同HTTP请求来发送上行通知。
这导致各种问题:
•服务器被迫为每个客户端使用一些不同的底层TCP连接:
一个用来向客户端发送消息,为每个到来的消息使用一个新的。
•通信(wire)协议具有很高的开销,因为每个客户端到服务器的消息有HTTP头。
•客户端侧的脚本被迫维护输出连接到输入连接的映射来追踪响应。
一个简单的解决方法是为双向传输使用单一的TCP连接。
这是WebSocket协议提供的。
结合WebSocketAPI(WSAPI),它为web页面到远程服务器的双向通信提供了HTTP轮询的替代方案。
同样的技术也可用于各种web应用程序:
游戏,股票行情,多用户协同编辑的应用程序,用户界面实时展示服务器侧服务等。
WebSocket协议设计用来取代使用HTTP作为传输层的双向通信技术,并从现有的基础设施(代理、过滤、认证)受益。
这些技术作为效率与可靠性的平衡而实现,因为HTTP最初并不是用于双向通信的(见RFC6202有多更讨论)。
WebSocket尝试解决在现有HTTP基础设施的环境下现有HTTP双向通信技术的目标;像这样,它设计来工作于HTTP80、443端口上,并支持HTTP代理和中间设施,即使这意味着增加现有环境的一些复杂性。
然而,设计并没有将WebSocket局限于HTTP,未来的实现可以在特定的端口上使用更简单的握手,而不需要重新发明整个协议。
最后一点是重要的,因为交互式消息的传输模式并不紧密符合标准的HTTP传输,会在一些部件上引起异常的负载。
1.2协议概览
这部分是不规范的。
WebSocket协议有两部分:
握手和数据传输。
来自客户端的握手开起来像下面:
来自服务器的握手开起来像下面:
来自客户端的引导行遵从Request-Line格式,来自服务器的引导行遵从Status-Line格式。
Request-Line和Status-Line在RFC2616定义。
在两种情况下,引导行后面跟着一组未排序的头域。
这些头域的意义在本文档的第4章指定。
额外的头域也可能出现,如cookieRFC6265。
头的格式和解析在RFC2616定义。
一旦客户端和服务器都发送了他们的握手,如果握手成功,传输数据部分开始。
这是一个双向传输通道,每个端都能独立、随意发送数据。
在成功握手后,客户端和服务器来回传输数据是以消息message为概念单位的。
在传输介质上(onthewire),一个消息由一个或多个帧frame组成。
WebSocket消息不需要对应到特定网络层的帧,因为分帧后的消息可能被中间设施合并或拆分。
一帧都有一个关联的类型。
属于同一个消息的帧拥有相同的数据类型,广义地说,有文本数据(解释为UTF-8RFC3629文本)、二进制数据(它的解释留给了应用程序)和控制帧(不打算携带应用数据,携带的是协议层的信号,如连接关闭信号)类型。
这个版本的协议定义了6种帧类型,并保留了10种为以后使用。
1.3打开握手
这部分是不规范的。
打开握手为了兼容基于HTTP的服务器端软件和中间设施,使同一个端口能够接受HTTP客户端和WebSocket客户端,为了这个目的,WebSocket客户端的握手是HTTP请求的升级。
为了兼容RFC2616,客户端握手里的头域可能以任意的顺序发送,因此不同头域接收到的顺序是不重要的。
GET方法(RFC2616)的Request-URI用于识别WebSocket连接的终端,允许一个IP地址服务多个域domain,和允许单个服务器提供多个WebSocket终端。
客户端在握手的Host头域里包含主机名,这样,客户端和服务器能够验证他们同意使用哪个主机。
额外的头域用于选择WebSocket协议的选项。
此版本中典型的可用选项有子协议选择器Sec-WebSocket-Protocol,Sec-WebSocket-Protocol列出客户端支持的扩展,Origin头域等等。
Sec-WebSocket-Protocol请求头域可用来表明客户端可接受的子协议(WebSocket协议之上的应用程序层协议)。
服务器选择1个或0个可接受的协议,输出到它的握手,来指明它选择了那个协议。
Sec-WebSocket-Protocol:
chat
Origin头域(RFC6454)用于保护WebSocket服务器不被未授权的运行在浏览器的脚本跨源使用WebSocketAPI。
如果服务器不想接受来自这个源的连接,它可以拒绝连接,并发送一个合适的HTTP错误码。
这个头域由浏览器客户端发送;对于非浏览器客户端,这个头域可能发送,如果它在客户端上下文环境中有意义。
最后,服务器得向客户端证明它接收到了客户端的WebSocket握手,为使服务器不接受非WebSocket连接。
这防止攻击者通过XMLHttpRequest发送或表单提交精心构造的包来欺骗WebSocket服务器。
为了证明握手被接收,服务器把两块信息合并来形成响应。
第一块信息来自客户端握手头域Sec-WebSocket-Key,如Sec-WebSocket-Key:
dGhlIHNhbXBsZSBub25jZQ==对于这个头域,服务器取头的值(由于出现在头域,例如,base64编码[RFC4648]后的版本,消除任何前面后面的空白符),以字符串的形式拼接全局唯一的(GUID,[RFC4122])标识:
258EAFA5-E914-47DA-95CA-C5AB0DC85B11,此值不大可能被不明白WebSocket协议的网络终端使用。
然后进行SHA-1hash(160位)编码,再进行base64编码,将结果作为服务器的握手返回。
具体如下:
请求头:
Sec-WebSocket-Key:
dGhlIHNhbXBsZSBub25jZQ==
取值,字符串拼接后得到:
"dGhlIHNhbXBsZSBub25jZQ==258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
SHA-1后得到:
0xb30x7a0x4f0x2c0xc00x620x4f0x160x900xf60x460x060xcf0x380x590x450xb20xbe0xc40xea
Base64后得到:
s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
最后的结果值作为响应头Sec-WebSocket-Accept的值。
来自服务器的握手比客户端的简单很多。
首先是HTTP状态行,状态码是101:
HTTP/1.1101SwitchingProtocols任何非101的状态码表示WebSocket握手还没有完成,HTTP语义仍然生效。
Connection和Upgrade头域完成HTTP升级。
Sec-WebSocket-Accept头表明服务器是否愿意接受连接。
如果有,值必须是前面提到的算法得到的值,否则不能解释为服务器接受连接。
这些字段由WebSocket客户端为脚本页面检测,如果Sec-WebSocket-Accept的值不符合预期的值,如果头缺失,或HTTP状态码不是101,连接不会建立,WebSocket帧不会发送。
还可以包含一些可选字段。
在协议的这个版本里,主要的可选字段是Sec-WebSocket-Protocol,表示服务器选择的子协议。
WebSocket客户端验证服务器选择了一个客户端握手中指定的值。
支持多个子协议的服务器必须确保它选择了一个基于客户端握手并在它自己的握手里指定了它。
服务器也可以设置cookie有关的可选头。
1.4关闭握手
这部分是不规范的。
关闭握手远比打开握手简单。
任何一端都可以发送带有指定控制序号的数据的帧来开始关闭握手(详细在5.5.1节)。
当接收到这样的帧时,如果还没有发送,另一端发送一个关闭帧(B)作为响应。
当接收到那个(B)帧时,第一个端关闭连接,因为知道没有更多的数据需要传输。
发送表明关闭连接的控制帧后,端不应该再发数据;接收到表示应该关闭连接的控制帧后,端丢弃后面接收的所有数据。
两端都可以安全地同时开始关闭握手。
这个关闭握手想补充TCP的关闭握手(FIN/ACK),依据是,TCP关闭握手不总是端到端可靠的,特别是出现拦截代理和其他的中间设施。
通过发送一个关闭帧并等待返回关闭帧响应,可以避免一些数据丢失的特殊情况。
例如,在一些平台上,如果一个套接字关闭时有数据在接收队列,RST包发送后,将导致recv()失败,因为接收到RST,即使仍有数据等待读取。
1.5设计哲学
这部分是不规范的。
WebSocket协议的设计原则就是最小化框架(唯一的框架就是协议是基于帧的,而不是基于流的,并且支持区分Unicode文本和二进制帧的)。
它希望元数据放在WebSocket上面的应用程序层。
概念上,WebSocket确实只是TCP上面的一层,做下面的工作:
为浏览器添加web的origin-based的安全模型。
添加定位和协议命名机制来支持在同一个端口上提供多个服务和同一个IP上有多个主机名。
在TCP上实现帧机制,来回到IP包机制,而没有长度限制。
在带内包含额外的关闭握手,是为了能在有代理和其他中间设施的地方工作。
除了这些,WebSocket没有再添加任何东西。
基本上,它想尽可能暴露原始的TCP给脚本,又给web约束。
它还设计以这样的方式,它的服务器能和HTTP服务器共享同一个端口,通过使它的请求是一个合法的HTTP升级请求。
在概念上可以使用其他的协议来建立客户端-服务器消息机制,但WebSocket的目的是提供一个相当简单的协议,能够与HTTP和已部署的HTTP基础设施共存(如代理),尽可能接近TCP,通过给定安全模型在现有基础设施上安全使用,伴随简化使用和使简单事情保持简单的额外目标。
协议考虑到可扩展,未来的版本很可能引入额外的概念,如multiplexing。
1.6安全模型
这部分是不规范的。
WebSocket协议使用起源模型(originmodel),浏览器用来限制哪些网页能够接触WebSocket服务器。
当专用的客户端直接使用WebSocket协议时,起源模型没用了,因为客户端能够提供任意的origin字符串。
这个协议目的是不和现有协议(如SMTP、HTTP)的服务器建立连接,如果要求,允许HTTP服务器可选地支持此协议。
这个通过一个严格的、精心制作的握手和在握手完成前限制数据进入连接来做到的。
类似地,当其他协议的数据发送到WebSocket时,使连接失败。
这主要是通过要求服务器证明它读取了握手,在只有当握手含有适当的部分时,这些部分只能由WebSocket客户端发送。
特别是,在写这个规范时,以Sec-开头的头不能被来自浏览器的攻击者使用HTML和JavaScriptAPI如XMLHttpRequest发送。
1.7与TCP和HTTP的关系
这部分是不规范的。
WebSocket协议是独立的、基于TCP的协议。
与HTTP的唯一关系是它的握手可以被HTTP服务器解释为一个升级请求。
默认地,WebSocket协议为常规连接使用80端口,为基于传输层安全(TLS)的连接使用443端口。
1.8建立连接
这部分是不规范的。
当一个连接连接到被HTTP服务器共享的端口(对于端口80和443是很可能发生的场景),连接将展示给HTTP服务器的将是一个伴有Upgrade的、常规的GET请求。
在只有一个IP地址和单个服务器对应所有传输到单个主机的相对简单的设置,这将允许特殊的方法来部署基于系统的WebSocket协议。
在更复杂的设置下,一组用于WebSocket连接的主机从HTTP服务器分离是更容易管理的。
在写这篇规范的时候,应当指出,在端口80和443上连接有显著的成功率,
1.9使用WebSocket协议的子协议
这部分是不规范的。
客户端可以通过在它的握手包含Sec-WebSocket-Protocol头来要求服务器使用指定的子协议。
如果指定了,为建立连接,服务器需要包含一个同样的头和一个选择了的子协议在它的响应。
这些子协议的命名要按照11.5节注册。
为了避免潜在的冲突,推荐使用带有子协议发起人的域名的ASCII版本号的名字。
例如,Excaple集团准备创建一个聊天子协议,由web上的一些服务器来实现,它可以命名为。
如果Example组织命名他们的竞争子协议为chat.example.org,那么两种子协议都能背服务器同时实现,由服务器根据客户端发送的数据动态选择使用子协议。
子协议的版本可以是向后不兼容的,通过改变子协议的名字,如从到。
这些子协议可以认为完全独立于WebSocket客户端的。
向后兼容的版本可通过复用同样的协议字符串来实现,但小心设计协议来支持扩展。
2一致性要求
Alldiagrams,examples,andnotesinthisspecificationarenonnormative,asareallsectionsexplicitlymarkednon-normative.Everythingelseinthisspecificationisnormative.
Thekeywords"MUST","MUSTNOT","REQUIRED","SHALL","SHALLNOT","SHOULD","SHOULDNOT","RECOMMENDED","MAY",and"OPTIONAL"inthisdocumentaretobeinterpretedasdescribedin[RFC2119].
Requirementsphrasedintheimperativeaspartofalgorithms(suchas"stripanyleadingspacecharacters"or"returnfalseandabortthesesteps")aretobeinterpretedwiththemeaningofthekeyword("MUST","SHOULD","MAY",etc.)usedinintroducingthealgorithm.
2.1TerminologyandOtherConventions
ASCIIshallmeanthecharacter-encodingschemedefinedin[ANSI.X3-4.1986].
ThisdocumentmakesreferencetoUTF-8valuesandusesUTF-8notationalformatsasdefinedinSTD63[RFC3629].
Keytermssuchasnamedalgorithmsordefinitionsareindicatedlikethis.
Namesofheaderfieldsorvariablesareindicatedlike|this|.
Variablevaluesareindicatedlike/this/.
ThisdocumentreferencestheproceduretoFailtheWebSocketConnection.ThisprocedureisdefinedinSection7.1.7.
ConvertingastringtoASCIIlowercasemeansreplacingallcharactersintherangeU+0041toU+005A(i.e.,LATINCAPITALLETTERAtoLATINCAPITALLETTERZ)withthecorrespondingcharactersintherangeU+0061toU+007A(i.e.,LATINSMALLLETTERAtoLATINSMALLLETTERZ).
ComparingtwostringsinanASCIIcase-insensitivemannermeanscomparingthemexactly,codepointforcodepoint,exceptthatthecharactersintherangeU+0041toU+005A(i.e.,LATINCAPITALLETTERAtoLATINCAPITALLETTERZ)andthecorrespondingcharactersintherangeU+0061toU+007A(i.e.,LATINSMALLLETTERAtoLATINSMALLLETTERZ)areconsideredtoalsomatch.
Theterm"URI"isusedinthisdocumentasdefinedin[RFC3986].
WhenanimplementationisrequiredtosenddataaspartoftheWebSocketProtocol,theimplementationMAYdelaytheactualtransmissionarbitrarily,e.g.,bufferingdatasoastosendfewerIPpackets.
Notethatthisdocumentusesboth[RFC5234]and[RFC2616]variantsofABNFindifferentsections.
3WebSocketURI
本规范定义了两种URI方案,使用在RFC5234定义的ABNF语法、术语和在RFC3986定义的URI规范的ABNF成果。
port部分是可选的;ws默认的端口是80,wss默认是443。
如果scheme部分匹配大小写不敏感的wss,那么URI就被称作是“安全的”。
resource-name可以由下面部分的拼接组成:
•"/"如果path部分是空的
•path部分
•?
如果query部分不为空
•空的query部分
片段(fragment)标识符在WebSocketURI环境是没意义的,不允许在这些URI中使用。
与任何的URI方案一样,当字符“#”不表示片段的开始时,必须转义为%23。
4打开握手
4.1客户端要求
为建立WebSocket连接,客户端打开一个(TCP)连接并发送一个在这个章节里定义的握手。
一个连接最初定义为CONNECTING状态。
客户端需要提供WebSocketURI的部件:
host、port、resourcename和secure标志,这些都是第3章里讨论的WebSocketURI的组件,伴随使用一些协议和扩展。
另外,如果客户端是个web浏览器,它提供origin。
客户端运行在受限环境,如连接到特定关卡的移动手持设备上的浏览器,可能把连接的管理卸载给另一个网络代理。
在这种情况下,用于本规范目的的客户端包括手持设备软件和任意的这类代理。
当客户端准备用建立WebSocket连接,给定的一组(host,port,resourcename,secure标记),连同使用一序列协议和扩展,和在浏览器情况下有个origin,它必须打开一个(TCP)连接,发送一个打开握手,从响应里读取服务器的握手。
(TCP)连接应该如何打开的准确要求,在打开握手应该发送什么,服务器响应应该如何解释,将在下面的章节里。
在下面的文本里,我们将使用使用第3章里的名字,如/host/和/secure/flag。
1.传递给这个算法(/host/,/port/,/resourcename.,and/secure/flag)的WebSocket