diff options
Diffstat (limited to 'common/cgi.lua')
-rw-r--r-- | common/cgi.lua | 234 |
1 files changed, 0 insertions, 234 deletions
diff --git a/common/cgi.lua b/common/cgi.lua deleted file mode 100644 index 8f2acef..0000000 --- a/common/cgi.lua +++ /dev/null @@ -1,234 +0,0 @@ -cgi = {} - -cgi.none = "None" -cgi.lax = "Lax" -cgi.strict = "Strict" - --- global helpers -function string.split(self, sep) - if not sep then sep = "%s" end - - local t = {} - for match in (self .. sep):gmatch("(.-)" .. sep) do - table.insert(t, match) - end - - return t -end - -function string.fromhex(self) - return (self:gsub("..", function(cc) - return string.char(tonumber(cc, 16)) - end)) -end - -function string.tohex(self) - return (self:gsub(".", function(c) - return string.format("%02x", string.byte(c)) - end)) -end - -function cgi.encode_uri(str) - if str then - str = str:gsub("\n", "\r\n") - str = str:gsub("([^%w _ %- . ~])", - function(c) return string.format("%%%02X", string.byte(c)) end) - str = str:gsub(" ", "+") - end - - return str -end - -function cgi.decode_uri(str) - if str then - str = str:gsub("+", " ") - str = str:gsub("%%(%x%x)", - function(hex) return string.char(tonumber(hex, 16)) end) - end - - return str -end - -local function parse_params(dst, src) - for _, pair in ipairs(src:split("&")) do - local kv = pair:split("=") - local key = kv[1] - local value = kv[2] - - dst[key] = cgi.decode_uri(value) - end -end - -local function params_tostring(src) - local dst = "" - for k, v in pairs(src) do - local kv = k .. "=" .. cgi.encode_uri(v) - dst = dst .. kv .. "&" - end - - return dst:sub(1, #dst - 1) -end - -local function parse_cookies(dst, src) - for _, pair in ipairs(src:split("; ")) do - local kv = pair:split("=") - local key = kv[1] - local value = kv[2] - - dst[key] = cgi.decode_uri(value) - end -end - --- method -cgi.method = os.getenv("REQUEST_METHOD") - --- GET/POST params -cgi.get = {} -cgi.post = {} - -if cgi.method == "GET" then - local get_params = os.getenv("QUERY_STRING") - if get_params then - parse_params(cgi.get, get_params) - end -elseif cgi.method == "POST" then - local post_params = io.read("*a") - if post_params then - parse_params(cgi.post, post_params) - end -end - --- cookies -local cookies = {} - -local cookie = os.getenv("HTTP_COOKIE") -if cookie then - local c = {} - parse_cookies(c, cookie) - - for k, v in pairs(c) do - cookies[k] = {value = v} - end -end - -function cgi.get_cookie(name) - if not cookies[name] then return nil end - return cookies[name].value -end - -function cgi.set_cookie(name, cookie) - cookie._modified = true - cookies[name] = cookie -end - --- custom headers -function cgi.request_header(name) - return os.getenv("HTTP_" .. name:upper()) -end - -local resp_headers = {} -local headers_complete = false -function cgi.header(key, value) - if not value then - return false - end - - if not headers_complete then - resp_headers[key] = value - print(key .. ": " .. value) - end - - return not headers_complete -end - --- set cookies on exit -local function set_cookies() - for name, c in pairs(cookies) do - if c._modified then - local cookie = name .. "=" .. cgi.encode_uri(c.value or "") - - if c.domain then - cookie = cookie .. "; Domain=" .. c.domain - end - if c.path then - cookie = cookie .. "; Path=" .. c.path - end - if c.expires then - cookie = cookie .. "; Expires=" .. c.expires - end - if c.http_only then - cookie = cookie .. "; HttpOnly" - end - if c.https_only then - cookie = cookie .. "; Secure" - end - if c.same_site then - cookie = cookie .. "; SameSite=" .. c.same_site - end - - cgi.header("Set-Cookie", cookie) - end - end -end - --- special date format -function cgi.date(t) - return os.date("!%a, %d %b %Y %H:%M:%S GMT", t) -end - --- (custom) content -function cgi.content(data) - if not headers_complete then - set_cookies() - print() - headers_complete = true - end - - if data then - print(data) - end - - return not not data -end - -function cgi.serve(data) - if data then - cgi.content(data) - else - cgi.status(500) - end - - cgi.done() -end - --- finish response -function cgi.done() - if not headers_complete then - local body - - local status = tonumber(resp_headers["Status"]) - if status and status >= 400 and status < 600 then - -- error but no content: display error page - local f = io.open("/var/www/html/error/" .. tostring(status) .. ".html") - if f then - body = f:read("*a") - f:close() - end - end - - cgi.content(body) - end - - os.exit(0) -end - --- frequently used header utilities -function cgi.content_type(type) - return cgi.header("Content-Type", type) -end - -function cgi.status(code) - return cgi.header("Status", tostring(code)) -end - -return cgi |