local ffi = require "ffi" local openssl = require "openssl" local utils = {} utils.errors = { [400] = "bad_request", [401] = "unauthorized", [403] = "forbidden", [404] = "not_found", [405] = "method_not_allowed", [408] = "request_timeout", [409] = "conflict", [410] = "gone", [411] = "length_required", [413] = "payload_too_large", [414] = "uri_too_long", [415] = "unsupported_media_type", [418] = "im_a_teapot", [429] = "too_many_requests", [500] = "internal_server_error", [501] = "not_implemented", [502] = "bad_gateway", [503] = "service_unavailable", [504] = "gateway_timeout", [505] = "http_version_not_supported" } -- TODO: REWRITE utils.random = function(min, max) local buf = ffi.new("uint8_t[4]") ffi.copy(buf, openssl.random(4), 4) local num = 0 for i = 0, 3 do num = bit.bor(bit.lshift(num, 8), buf[i]) end return min + (num % (max - min + 1)) end utils.pin = function() local o = "" for i = 1, 4 do o = o .. tostring(utils.random(0, 9)) end return o end utils.uuid = function() local template = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx' return string.gsub(template, '[xy]', function(c) local v = (c == 'x') and utils.random(0, 0xf) or utils.random(8, 0xb) return string.format('%x', v) end) end utils.hash = function(data) return openssl.digest.digest("sha256", data) end utils.decode_url = function(str) str = str:gsub('+', ' ') -- Convert + to space return str:gsub("%%(%x%x)", function(hex) return string.char(tonumber(hex, 16)) end) end utils.parse_form = function(data) local result = {} for pair in data:gmatch("[^&]+") do local key, value = pair:match("([^=]+)=?(.*)") if key then result[utils.decode_url(key)] = utils.decode_url(value) end end return result end utils.parse_cookies = function(header) local cookies = {} if not header or header == "" then return cookies end for pair in header:gmatch("[^;]+") do local key, value = pair:match("%s*(.-)%s*=%s*(.*)") if key and value then cookies[key] = value end end return cookies end utils.is_valid_handle = function(handle) return #handle > 0 and #handle <= 32 and not handle:match("[^0-9A-Za-z._-]") end utils.is_valid_password = function(password) return #password >= 8 and #password <= 32 and password:match("%d") and password:match("%l") and password:match("%u") and password:match("[@$!%%*?&]") end utils.forms = function(req, res, go) if req.headers["content-type"] == "application/x-www-form-urlencoded" then req.form = utils.parse_form(req.body) end go() end package.preload["./utils"] = utils return utils