Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
#! /home/stuserbot/bin/lua
local rt = {}
local getenv = os.getenv
local strupper = string.upper
local strlower = string.lower
local format = string.format
local gsub = string.gsub
local setmetatable = setmetatable
local write = io.write
local pcall = pcall
do --server------------------------------------------------------------
local servars = {"software", "name", "port",
"protocol"} --todo: replace url_scheme in the spec with this
rt.server = {}
for i=1, #servars do
local var = servars[i]
rt.server[var] = getenv("SERVER_"..strupper(var))
end
local cgiver = getenv "GATEWAY_INTERFACE" or ""
rt.server.connector = format("lasi.cgi/0.3.0 (%s)",cgiver)
end
do --headers-----------------------------------------------------------
local http_headers = {
"Accept",
"User-Agent",
"Connection",
"Referer",
"Cookie",
"Host"
}
local function normalize(name)
name = gsub(name,"%-","%_")
return strlower(name)
end
local function get_header_var(header)
return getenv("HTTP_"..strupper(header))
end
rt.headers = {}
rt.headers.content_length = getenv "CONTENT_LENGTH"
rt.headers.content_type = getenv "CONTENT_TYPE"
for i=1, #http_headers do
local header = normalize(http_headers[i])
rt.headers[header] = get_header_var(header)
end
--add index metamethod to catch any other headers
local metamethods = {}
function metamethods:__index(header)
local header = normalize(header)
if not self[header] then
self[header]= get_header_var(header)
end
return self[header]
end
setmetatable(rt.headers,metamethods)
end
do --others------------------------------------------------------------
rt.method = getenv "REQUEST_METHOD"
rt.query = getenv "QUERY_STRING"
rt.prefix = getenv "SCRIPT_NAME"
rt.path = getenv "PATH_INFO"
end
--run------------------------------------------------------------------
local function respond(code, headers,msg)
local function normalize(name)
--todo: non-alphanumeric/hyphen characters?
return gsub(name,"%_","%-")
end
write('Status: ',code,'\n')
for k,v in pairs(headers) do
--todo: sanitize values
write(normalize(k),': ',v,'\n')
end
write'\n'
if rt.method ~= "HEAD" then
--todo: support for non-string messages
write(msg)
end
end
local function resperr(msg)
respond(500,{["Content-Type"]="text/plain"},msg)
end
local script = getenv "PATH_TRANSLATED"
if not script then
print "PATH_TRANSLATED environment variable not defined."
print "(Is this being called as a CGI handler?)"
else
local scr, err = io.open(script)
if scr then
success, coderr, headers, msg =
pcall(scr)
if success then
respond(coderr, headers, msg)
else
resperr(coderr)
end
else
resperr(coderr)
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment