summaryrefslogtreecommitdiffstatshomepage
path: root/plugins/websocket-codec/init.lua
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/websocket-codec/init.lua')
-rw-r--r--plugins/websocket-codec/init.lua261
1 files changed, 0 insertions, 261 deletions
diff --git a/plugins/websocket-codec/init.lua b/plugins/websocket-codec/init.lua
deleted file mode 100644
index 8a7da7f9190..00000000000
--- a/plugins/websocket-codec/init.lua
+++ /dev/null
@@ -1,261 +0,0 @@
-local exports = {}
-
-exports.name = "creationix/websocket-codec"
-exports.version = "1.0.7"
-exports.homepage = "https://github.com/luvit/lit/blob/master/deps/websocket-codec.lua"
-exports.description = "A codec implementing websocket framing and helpers for handshakeing"
-exports.tags = {"http", "websocket", "codec"}
-exports.license = "MIT"
-exports.author = { name = "Tim Caswell" }
-
-local digest = require('openssl').digest.digest
-local base64 = require('openssl').base64
-local random = require('openssl').random
-local bit = require('bit')
-
-local band = bit.band
-local bor = bit.bor
-local bxor = bit.bxor
-local rshift = bit.rshift
-local lshift = bit.lshift
-local char = string.char
-local byte = string.byte
-local sub = string.sub
-local gmatch = string.gmatch
-local lower = string.lower
-local gsub = string.gsub
-local concat = table.concat
-
-local function applyMask(data, mask)
- local bytes = {
- [0] = byte(mask, 1),
- [1] = byte(mask, 2),
- [2] = byte(mask, 3),
- [3] = byte(mask, 4)
- }
- local out = {}
- for i = 1, #data do
- out[i] = char(
- bxor(byte(data, i), bytes[(i - 1) % 4])
- )
- end
- return concat(out)
-end
-
-function exports.decode(chunk)
- if #chunk < 2 then return end
- local second = byte(chunk, 2)
- local len = band(second, 0x7f)
- local offset
- if len == 126 then
- if #chunk < 4 then return end
- len = bor(
- lshift(byte(chunk, 3), 8),
- byte(chunk, 4))
- offset = 4
- elseif len == 127 then
- if #chunk < 10 then return end
- len = bor(
- lshift(byte(chunk, 3), 56),
- lshift(byte(chunk, 4), 48),
- lshift(byte(chunk, 5), 40),
- lshift(byte(chunk, 6), 32),
- lshift(byte(chunk, 7), 24),
- lshift(byte(chunk, 8), 16),
- lshift(byte(chunk, 9), 8),
- byte(chunk, 10))
- offset = 10
- else
- offset = 2
- end
- local mask = band(second, 0x80) > 0
- if mask then
- offset = offset + 4
- end
- if #chunk < offset + len then return end
-
- local first = byte(chunk, 1)
- local payload = sub(chunk, offset + 1, offset + len)
- assert(#payload == len, "Length mismatch")
- if mask then
- payload = applyMask(payload, sub(chunk, offset - 3, offset))
- end
- local extra = sub(chunk, offset + len + 1)
- return {
- fin = band(first, 0x80) > 0,
- rsv1 = band(first, 0x40) > 0,
- rsv2 = band(first, 0x20) > 0,
- rsv3 = band(first, 0x10) > 0,
- opcode = band(first, 0xf),
- mask = mask,
- len = len,
- payload = payload
- }, extra
-end
-
-function exports.encode(item)
- if type(item) == "string" then
- item = {
- opcode = 2,
- payload = item
- }
- end
- local payload = item.payload
- assert(type(payload) == "string", "payload must be string")
- local len = #payload
- local fin = item.fin
- if fin == nil then fin = true end
- local rsv1 = item.rsv1
- local rsv2 = item.rsv2
- local rsv3 = item.rsv3
- local opcode = item.opcode or 2
- local mask = item.mask
- local chars = {
- char(bor(
- fin and 0x80 or 0,
- rsv1 and 0x40 or 0,
- rsv2 and 0x20 or 0,
- rsv3 and 0x10 or 0,
- opcode
- )),
- char(bor(
- mask and 0x80 or 0,
- len < 126 and len or (len < 0x10000) and 126 or 127
- ))
- }
- if len >= 0x10000 then
- chars[3] = char(band(rshift(len, 56), 0xff))
- chars[4] = char(band(rshift(len, 48), 0xff))
- chars[5] = char(band(rshift(len, 40), 0xff))
- chars[6] = char(band(rshift(len, 32), 0xff))
- chars[7] = char(band(rshift(len, 24), 0xff))
- chars[8] = char(band(rshift(len, 16), 0xff))
- chars[9] = char(band(rshift(len, 8), 0xff))
- chars[10] = char(band(len, 0xff))
- elseif len >= 126 then
- chars[3] = char(band(rshift(len, 8), 0xff))
- chars[4] = char(band(len, 0xff))
- end
- if mask then
- local key = random(4)
- return concat(chars) .. key .. applyMask(payload, key)
- end
- return concat(chars) .. payload
-end
-
-local websocketGuid = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"
-
-function exports.acceptKey(key)
- return gsub(base64(digest("sha1", key .. websocketGuid, true)), "\n", "")
-end
-local acceptKey = exports.acceptKey
-
--- Make a client handshake connection
-function exports.handshake(options, request)
- local key = gsub(base64(random(20)), "\n", "")
- local host = options.host
- local path = options.path or "/"
- local protocol = options.protocol
- local req = {
- method = "GET",
- path = path,
- {"Connection", "Upgrade"},
- {"Upgrade", "websocket"},
- {"Sec-WebSocket-Version", "13"},
- {"Sec-WebSocket-Key", key},
- }
- for i = 1, #options do
- req[#req + 1] = options[i]
- end
- if host then
- req[#req + 1] = {"Host", host}
- end
- if protocol then
- req[#req + 1] = {"Sec-WebSocket-Protocol", protocol}
- end
- local res = request(req)
- if not res then
- return nil, "Missing response from server"
- end
- -- Parse the headers for quick reading
- if res.code ~= 101 then
- return nil, "response must be code 101"
- end
-
- local headers = {}
- for i = 1, #res do
- local name, value = unpack(res[i])
- headers[lower(name)] = value
- end
-
- if not headers.connection or lower(headers.connection) ~= "upgrade" then
- return nil, "Invalid or missing connection upgrade header in response"
- end
- if headers["sec-websocket-accept"] ~= acceptKey(key) then
- return nil, "challenge key missing or mismatched"
- end
- if protocol and headers["sec-websocket-protocol"] ~= protocol then
- return nil, "protocol missing or mistmatched"
- end
- return true
-end
-
-function exports.handleHandshake(head, protocol)
-
- -- WebSocket connections must be GET requests
- if not head.method == "GET" then return end
-
- -- Parse the headers for quick reading
- local headers = {}
- for i = 1, #head do
- local name, value = unpack(head[i])
- headers[lower(name)] = value
- end
-
- -- Must have 'Upgrade: websocket' and 'Connection: Upgrade' headers
- if not (headers.connection and headers.upgrade and
- headers.connection:lower():find("upgrade", 1, true) and
- headers.upgrade:lower():find("websocket", 1, true)) then return end
-
- -- Make sure it's a new client speaking v13 of the protocol
- if tonumber(headers["sec-websocket-version"]) < 13 then
- return nil, "only websocket protocol v13 supported"
- end
-
- local key = headers["sec-websocket-key"]
- if not key then
- return nil, "websocket security key missing"
- end
-
- -- If the server wants a specified protocol, check for it.
- if protocol then
- local foundProtocol = false
- local list = headers["sec-websocket-protocol"]
- if list then
- for item in gmatch(list, "[^, ]+") do
- if item == protocol then
- foundProtocol = true
- break
- end
- end
- end
- if not foundProtocol then
- return nil, "specified protocol missing in request"
- end
- end
-
- local accept = acceptKey(key)
-
- local res = {
- code = 101,
- {"Upgrade", "websocket"},
- {"Connection", "Upgrade"},
- {"Sec-WebSocket-Accept", accept},
- }
- if protocol then
- res[#res + 1] = {"Sec-WebSocket-Protocol", protocol}
- end
-
- return res
-end
-return exports