Skip to content

Lua Scripts

Flussonic has a built-in experimental feature to execute scripts written in the Lua scripting language. Flussonic uses luerl as Lua interpreter, so error messages might be different from the standard one.

Important. All functionalities described in this section are experimental and can be changed without notice.


In addition to the standard lua library, Flussonic adds some features to scripts:

HTTP client

http.get(url) http.get(url, headers) http.get(url, headers, body) http.get(url, headers, timeout) http.get(url, headers, body, timeout) An HTTP GET request is sent. A table with keys: code, headers, body is sent as the reply. An HTTP POSt request is sent. The arguments and answer are like those in http.get.

http.qs_encode(table) The table is encoded into a query string.

JSON module

json.encode(table) The table is translated into JSON

json.decode(text) JSON is translated into the table

Flussonic API

flussonic.config() partial configuration is returned

flussonic.streams() current list of streams

flussonic.files() current list of open files

flussonic.caches() current list of disk caches

flussonic.clients() flussonic.clients(stream) current list either of all sessions or of specific sessions of the stream

flussonic.log(text) output into the log by means of Flussonic

flussonic.debug(text) debugging output into the log by means of Flussonic current time UTC

flussonic.uuid() uuid is generated

table.tostring(table) returns the table as text

Comet server

comet.create_channel("channel") comet.create_channel("channel", 100) a channel in the inner comet server is created. Channel is optionally specified

comet.send("channel", "message") a message is sent via the comet server internal channel

SWIFT client

auth_info = swift.auth("http://proxy-server/", "account", "password") authorization data for further access is returned

swift.list_containers(auth_info) the list of containers of the authorized account

swift.create_container(auth_info, 'videos') swift.create_container(auth_info, 'videos', {}) a container, possibly with a meta-date, is created

swift.delete_container(auth_info, 'videos') deleting the container

swift.list_objects(auth_info, 'videos') list of objects in the container

swift.create_object(auth_info, 'videos', 'file.txt', 'contents') creating an object

swift.upload_file(auth_info, 'videos', 'remote_path.mp4', 'local_path.mp4') swift.upload_file(auth_info, 'videos', 'remote_path.mp4', 'local_path.mp4', 'local_callback_name') downloading a file. The name of the local function can also be specified as a line that will be invoked upon booting for indicating load on the server

FTP client

ftp.list("ftp://user:password@host/path") The list of files in the directory

ftp.upload("local.mp4", "ftp://user:password@host/path/remote.mp4") function progress(p) end ftp.upload("local.mp4", "ftp://user:password@host/path/remote.mp4", "progress") the local file is uploaded to ftp. Optionally, a callback is invoked for the download status

Crypto API

crypto.md5("Hi") md5 in hex format

crypto.sha1("Hi") sha1 in hex format

crypto.sha256("Hi") sha256 in hex format

Login using Lua

The login backend in Lua is an ordinary script that returns the result with the return operator. The script receives an additional global table req with the following fields, some of which are optional:

  • token - token from the query string or automatically generated
  • ip - IP address of the user
  • name - stream/file name
  • referer - the optional referrer of the player (the address of the page it was inserted into)

The answer should look like: return true, {user_id = 15, unique = true}, return "redirect", "http://someotherserver/path" or return false, {code = 403}

Event handlers

An example of using Lua for filtering and sending internal Flussonic events is provided in section Events API.

Web scripts

Lua can be used to generate web pages using the Flussonic infrastructure.

To do so, specify in the config:

web_script mytest priv/myscripts;

After that, when referring to the address, a lua script priv/myscripts/web.lua will be called, and the http_handler.counter(req) function will be called in it:

http_handler = {}

http_handler.counter = function(req)
  if not req.cookies.flusession then
    session_id = flussonic.uuid()
    headers = {}
    headers["Set-Cookie"] = "flusession="..session_id
    headers["Location"] = "/mytest/counter"
    return "http", 302, headers, "auth\n"
    session_id = req.cookies.flusession
    value = flussonic.session.get(session_id, "key1")
    if not value or value == "undefined" then
      flussonic.session.set(session_id, "key1", 1)
    value = flussonic.session.get(session_id, "key1")
    flussonic.session.set(session_id, "key1", value + 1)
    return "http", 200, {}, tostring(value).."\n"

Now this script should be invoked:

$ curl -v http://localhost:80/mytest/counter
< HTTP/1.1 302 Found
< Connection: keep-alive
< Server: Cowboy
< Date: Fri, 06 Mar 2015 10:20:13 GMT
< Content-Length: 5
< Location: /mytest/counter
< Set-Cookie: flusession=4a41cc61-b089-4cd5-9c4a-28402c6db525
$ curl -s http://localhost:80/mytest/counter -H 'Cookie: flusession=4a41cc61-b089-4cd5-9c4a-28402c6db525'
$ curl -s http://localhost:80/mytest/counter -H 'Cookie: flusession=4a41cc61-b089-4cd5-9c4a-28402c6db525'
$ curl -s http://localhost:80/mytest/counter -H 'Cookie: flusession=4a41cc61-b089-4cd5-9c4a-28402c6db525'
$ curl -s http://localhost:80/mytest/counter -H 'Cookie: flusession=4a41cc61-b089-4cd5-9c4a-28402c6db525'

In this script, all the functions described above will be available. Also, the table req is available:

  • req.query - parsed query string
  • req.headers - HTTP headers
  • req.method - HTTP method in uppercase letters
  • req.body - body of the HTTP header. If the body is in the www-form-encoded format, it should be parsed in lua on its own with the use of http.qs_decode:

if req.method == "POST" then
  post = http.qs_decode(req.body)

The lua script can return the following responses:

  • return 'http', 200, {["Content-Type"] = "text/plain"}, "Hello, world!\n" - the http response can be sent directly
  • return "json", {key = "value"} - the table will be packed into JSON
  • return "template", {var1 = "value1", var2 = "value2"} - in this case, Flussonic will take the file called priv/cameras/list.html that should be a valid DTL template, where the values from the script

  • return "template" will be substituted, {headers = {}}, {var1 = "value1"} the same but with the possibility to set headers


Sometimes, it is needed to disable authorization for secondary servers, i.e., for multiple IP addresses. In order to avoid adding this logic to the back-end, one can write their own authorization script:

if req.ip == "" then
  return true, {}

reply = http.get("http://backend/script.php")

if not reply.code == 200 then
  return false, {code = reply.code}

opts = {}
if reply.headers["x-userid"] then
  opts.user_id = reply.headers["x-userid"]

if reply.headers["x-unique"] then
  opts.unique = true

return true, opts