summaryrefslogtreecommitdiffstatshomepage
path: root/plugins/weblit/websocket.lua
diff options
context:
space:
mode:
author Miodrag Milanovic <mmicko@gmail.com>2016-02-14 10:58:18 +0100
committer Miodrag Milanovic <mmicko@gmail.com>2016-02-14 10:58:18 +0100
commitccae0382bb750c1deded19e05b34933a8303465e (patch)
tree1a2f0ae972163e6c1c76611b464d4257947c003e /plugins/weblit/websocket.lua
parent2db49088141b6238e92aecc4c073076a02c73065 (diff)
Added plugins and boot.lua as startup script [Miodrag Milanovic]
Diffstat (limited to 'plugins/weblit/websocket.lua')
-rw-r--r--plugins/weblit/websocket.lua82
1 files changed, 82 insertions, 0 deletions
diff --git a/plugins/weblit/websocket.lua b/plugins/weblit/websocket.lua
new file mode 100644
index 00000000000..d5dfe572ea6
--- /dev/null
+++ b/plugins/weblit/websocket.lua
@@ -0,0 +1,82 @@
+
+local websocketCodec = require('websocket-codec')
+
+local function websocketHandler(options, handler)
+ return function (req, res, go)
+ -- Websocket connections must be GET requests
+ -- with 'Upgrade: websocket'
+ -- and 'Connection: Upgrade' headers
+ local headers = req.headers
+ local connection = headers.connection
+ local upgrade = headers.upgrade
+ if not (
+ req.method == "GET" and
+ upgrade and upgrade:lower():find("websocket", 1, true) and
+ connection and connection:lower():find("upgrade", 1, true)
+ ) then
+ return go()
+ end
+
+ if options.filter and not options.filter(req) then
+ return go()
+ end
+
+ -- If there is a sub-protocol specified, filter on it.
+ local protocol = options.protocol
+ if protocol then
+ local list = headers["sec-websocket-protocol"]
+ local foundProtocol
+ if list then
+ for item in list:gmatch("[^, ]+") do
+ if item == protocol then
+ foundProtocol = true
+ break
+ end
+ end
+ end
+ if not foundProtocol then
+ return go()
+ end
+ end
+
+ -- Make sure it's a new client speaking v13 of the protocol
+ assert(tonumber(headers["sec-websocket-version"]) >= 13, "only websocket protocol v13 supported")
+
+ -- Get the security key
+ local key = assert(headers["sec-websocket-key"], "websocket security required")
+
+ res.code = 101
+ headers = res.headers
+ headers.Upgrade = "websocket"
+ headers.Connection = "Upgrade"
+ headers["Sec-WebSocket-Accept"] = websocketCodec.acceptKey(key)
+ if protocol then
+ headers["Sec-WebSocket-Protocol"] = protocol
+ end
+ function res.upgrade(read, write, updateDecoder, updateEncoder)
+ updateDecoder(websocketCodec.decode)
+ updateEncoder(websocketCodec.encode)
+ local success, err = pcall(handler, req, read, write)
+ if not success then
+ print(err)
+ write({
+ opcode = 1,
+ payload = err,
+ })
+ return write()
+ end
+ end
+ end
+end
+
+local server = require('weblit-app')
+function server.websocket(options, handler)
+ server.route({
+ method = "GET",
+ path = options.path,
+ host = options.host,
+ }, websocketHandler(options, handler))
+ return server
+end
+
+return websocketHandler