写在前面
这篇主要是分析一下WebSocket协议在Tomcat容器中的源码实现,方便大家在后面能够更好的了解下一篇Websocket型内存马的原理。
这个也是内存马系列第七篇
Websocket
什么是websocket?
首先来了解一下什么是websocket
WebSocket
全双工通信协议,在客户端和服务端建立连接后,可以持续双向通信,和HTTP同属于应用层协议,并且都依赖于传输层的TCP/IP
协议。
虽然WebSocket
有别于HTTP,是一种新协议,但是RFC 6455中规定:
it is designed to work over HTTP ports 80 and 443 as well as to support HTTP
proxies and intermediaries.
-
WebSocket
通过HTTP端口80和443进行工作,并支持HTTP代理和中介,从而使其与HTTP协议兼容。 -
为了实现兼容性,
WebSocket
握手使用HTTPUpgrade
头从HTTP协议更改为WebSocket
协议。 -
Websocket
使用ws
或wss
的统一资源标志符(URI),分别对应明文和加密连接。
建立连接
在双向通信之前,必须通过握手建立连接。Websocket通过 HTTP/1.1
协议的101状态码进行握手,首先客户端(如浏览器)发出带有特殊消息头(Upgrade、Connection)的请求到服务器,服务器判断是否支持升级,支持则返回响应状态码101,表示协议升级成功,对于WebSocket就是握手成功。
请求头实例
GET /test HTTP/1.1
Host: server.example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: tFGdnEL/5fXMS9yKwBjllg==
Origin: http://example.com
Sec-WebSocket-Protocol: v10.stomp, v11.stomp, v12.stomp
Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits
Sec-WebSocket-Version: 13
-
Connection
必须设置Upgrade
,表示客户端希望连接升级。 -
Upgrade: websocket表明协议升级为websocket。
-
Sec-WebSocket-Key
字段内记录着握手过程中必不可少的键值,由客户端(浏览器)生成,可以尽量避免普通HTTP请求被误认为Websocket
协议。 -
Sec-WebSocket-Version
表示支持的Websocket
版本。RFC6455要求使用的版本是13。 -
Origin
字段是必须的。如果缺少origin
字段,WebSocket
服务器需要回复HTTP403
状态码(禁止访问),通过Origin
可以做安全校验。
响应头实例
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: HaA6EjhHRejpHyuO0yBnY4J4n3A=
Sec-WebSocket-Extensions: permessage-deflate;client_max_window_bits=15
Sec-WebSocket-Protocol: v12.stomp
Sec-WebSocket-Accept
的字段值是由握手请求中的Sec-WebSocket- Key