Chromium没有解释就关闭WebSocket。
2011-9-29 6:8:43
收藏:0
阅读:151
评论:1
我有 Chromium 12.0.742.112 (90304),并尝试在其中设置一个简单的 WebSocket 服务器。我收到了一个握手请求,如下所示:
Upgrade: WebSocket
Connection: Upgrade
Host: akira:22222
Origin: http://akira:22222
Sec-WebSocket-Key1: ;39LP*eC48 n /r0P6 v6548
Sec-WebSocket-Key2: 1 0 r 362547 4 4 G
紧随其后,8 个密钥字节,在这种情况下是 88 09 F9 EE 21 13 F4 0D。我已经验证这些是 Chromium 在网络控制台选项卡中显示的相同密钥。我计算前两个密钥如下:
Key1: 3948066548 / 4 = 987016637
Key2: 1036254744 / 12 = 86354562
并发送我的响应:
000001 48 54 54 50 2F 31 2E 31 20 31 30 31 20 57 65 62 HTTP/1.1 101 Web
000011 20 53 6F 63 6B 65 74 20 50 72 6F 74 6F 63 6F 6C Socket Protocol
000021 20 48 61 6E 64 73 68 61 6B 65 0D 0A 55 70 67 72 Handshake..Upgr
000031 61 64 65 3A 20 57 65 62 53 6F 63 6B 65 74 0D 0A ade: WebSocket..
000041 43 6F 6E 6E 65 63 74 69 6F 6E 3A 20 55 70 67 72 Connection: Upgr
000051 61 64 65 0D 0A 53 65 63 2D 57 65 62 53 6F 63 6B ade..Sec-WebSock
000061 65 74 2D 4F 72 69 67 69 6E 3A 20 68 74 74 70 3A et-Origin: http:
000071 2F 2F 61 6B 69 72 61 3A 32 32 32 32 32 0D 0A 53 //akira:22222..S
000081 65 63 2D 57 65 62 53 6F 63 6B 65 74 2D 4C 6F 63 ec-WebSocket-Loc
000091 61 74 69 6F 6E 3A 20 77 73 3A 2F 2F 61 6B 69 72 ation: ws://akir
0000A1 61 3A 32 32 32 32 32 2F 73 6F 63 6B 65 74 0D 0A a:22222/socket..
0000B1 0D 0A FF F4 2E 12 9D DC 12 C2 56 40 B8 09 F3 84 ..........V@....
0000C1 CA EF .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..##############
Chromium 只是关闭套接字,甚至没有在 JS 控制台中打印任何消息。我无法确定我哪里出错了?
服务器端代码使用 Lua(这就是为什么上面的十六进制转储从 1 开始索引):
require('crypto')
local handshake = {
"HTTP/1.1 101 Web Socket Protocol Handshake",
"Upgrade: WebSocket",
"Connection: Upgrade",
"Sec-WebSocket-Origin: " .. request.header.origin,
"Sec-WebSocket-Location: " ..
request.header.origin:gsub('http:', 'ws:') .. "/socket",
'\r\n'}
log.debug("Request header:\n%s\n", table.concat(request.rawheader, '\n'))
local client = response.socket
client:settimeout(10)
local keys =
{request.header.sec_websocket_key1, request.header.sec_websocket_key2}
local sum = {}
for i, k in ipairs(keys) do
local nspc = 0
sum[i] = ''
k:gsub('%d', function(n) sum[i] = sum[i] ..n end)
k:gsub(' ', function() nspc = nspc + 1 end)
log.debug("Key%d: %s / %d = ", i, sum[i], nspc)
sum[i] = tostring(tonumber(sum[i]) / nspc)
log.debug("%s\n", sum[i])
end
local key = assert(client:receive(8))
local bytes = {key:byte(1, #key)}
local keydump = {}
for i = 1, #bytes do keydump[i] = ('%02X'):format(bytes[i]) end
log.debug("Key3: %s\n", table.concat(keydump, ' '))
local resp = crypto.evp.digest('md5', table.concat(sum) .. key, true)
handshake = table.concat(handshake, '\r\n') .. resp
client:settimeout(0.1)
log.debug("Send handshake:\n%s\n", rena.debug.hexdump(handshake))
client:send(handshake)
repeat
local res, err = client:receive('*l')
if res then log.debug("R: %s\n", res) end
local res, err = client:send("Test " .. tostring(os.time()) .. '\n')
if res then socket.sleep(1)
elseif err == 'timeout' then log.debug("WS: Timed out\n")
elseif err == 'closed' then log.debug("WS: Closed\n")
else log.error("WS: Error: %s\n", tostring(err))
end
until not res
(这个脚本是由服务器脚本加载的,它预设了一些变量,例如 request 和 response,并使用 LuaCrypto 进行 MD5)。一切看起来都很正确(尽管我注意到所有的示例都显示二进制密钥的漂亮 ASCII 字符,而我的大部分都是不可打印的),但它只是关闭了套接字。
不幸的是,Chromium 是我唯一一个支持 WebSocket 的浏览器(除非有办法在 Firefox 6 中启用它?),因此我无法在任何其他浏览器中进行检查。
原文链接 https://stackoverflow.com/questions/7593169
点赞
评论区的留言会收到邮件通知哦~
推荐文章
- 如何在roblox studio中1:1导入真实世界的地形?
- 求解,lua_resume的第二次调用继续执行协程问题。
- 【上海普陀区】内向猫网络招募【Skynet游戏框架Lua后端程序员】
- SF爱好求教:如何用lua实现游戏内调用数据库函数实现账号密码注册?
- Lua实现网站后台开发
- LUA错误显式返回,社区常见的规约是怎么样的
- lua5.3下载库失败
- 请问如何实现文本框内容和某个网页搜索框内容连接,并把网页输出来的结果反馈到另外一个文本框上
- lua lanes多线程使用
- 一个kv数据库
- openresty 有没有比较轻量的 docker 镜像
- 想问一下,有大佬用过luacurl吗
- 在Lua执行过程中使用Load函数出现问题
- 为什么 neovim 里没有显示一些特殊字符?
- Lua比较两个表的值(不考虑键的顺序)
- 有个lua简单的项目,外包,有意者加微信 liuheng600456详谈,最好在成都
- 如何在 Visual Studio 2022 中运行 Lua 代码?
- addEventListener 返回 nil Lua
- Lua中获取用户配置主目录的跨平台方法
- 如何编写 Lua 模式将字符串(嵌套数组)转换为真正的数组?
我找到了问题。前两个密钥应该作为32位整数连接 (变成64位整数),而不是 ASCII 字符串:
- sum[i] = tostring(tonumber(sum[i]) / nspc) + sum[i] = ('%08X'):format(tonumber(sum[i]) / nspc) - local resp = crypto.evp.digest('md5', table.concat(sum) .. key, true) - handshake = table.concat(handshake, '\r\n') .. resp + local challenge = '' + (sum[1] .. sum[2]):gsub('..', function(byte) + challenge = challenge .. string.char(tonumber(byte, 16)) + end) + + challenge = challenge .. key + log.debug("Ch: %s\n", challenge:tohex()) + + local resp = crypto.evp.digest('md5', challenge, true) + handshake = table.concat(handshake, '\r\n') .. resp
用这个改动后,Chromium 能够接受连接了。我已经提交了一个 bug 来抱怨当哈希值不正确时缺少错误信息。