require("socket")
require("copas")
indexes = {}
binarytypes = {}
mimetypes = {}
function printparadiso(text)
print("Paradiso: "..text)
end
function table.explode(div,str)
if (div=='') then return false end
local pos,arr = 0,{}
-- for each divider found
for st,sp in function() return string.find(str,div,pos,true) end do
table.insert(arr,string.sub(str,pos,st-1)) -- Attach chars left of current divider
pos = sp + 1 -- Jump past current divider
end
table.insert(arr,string.sub(str,pos)) -- Attach chars right of last divider
return arr
end
function output(data)
if CURRENTCLIENT ~= nil then
CURRENTCLIENT:send(data)
else
printparadiso("Attempt to process lua page for non-existent client, did you set CURRENTCLIENT?")
end
end
function doerror(code)
if code == 404 then
local file = io.open("errors/404.html", "r")
local response = file:read("*a")
sendheaders("errors/404.html",#response)
CURRENTCLIENT:send(response)
file:close()
else
local file = io.open("errors/unknown.html", "r")
local response = file:read("*a")
sendheaders("errors/unknown.html",#response)
CURRENTCLIENT:send(response)
file:close()
end
end
function parsepath(request)
local _,start = string.find(request, 'GET ')
local final,_ = string.find(request, ' HTTP', start)
return string.sub(request, start+1, final-1);
end
function addmimetype(ext,t)
mimetypes[ext] = t
end
function sendheaders(path,length)
CURRENTCLIENT:send("HTTP/1.x 200 OK\r\n")
CURRENTCLIENT:send("Server: Paradiso\r\n")
CURRENTCLIENT:send("Content-length: "..length.."\r\n")
local temptable = table.explode(".",path)
local ftype = temptable[#temptable]
if mimetypes[ftype] == nil then
CURRENTCLIENT:send("Content-Type: text/plain\r\n")
else
CURRENTCLIENT:send("Content-Type: "..mimetypes[ftype].."\r\n")
end
CURRENTCLIENT:send("Connection: close\r\n\r\n")
end
function getfiletype(path)
local foundtype = false
local temptable = table.explode(".",path)
for k,v in pairs(binarytypes) do
if v == temptable[#temptable] then
foundtype = true
return true
end
end
if foundtype == false then
return false
end
end
function ClientHandler(client)
client = copas.wrap(client)
local request = client:receive("*l")
local path = parsepath(request)
printparadiso("Requested "..path)
CURRENTCLIENT = client
local responded = false
if path == "/" or path == "" then
for k,v in pairs(indexes) do
if responded == false then
local filetype = getfiletype(path)
if filetype == true then
local file = io.open(ROOTPATH.."/"..v, "rb")
else
local file = io.open(ROOTPATH.."/"..v, "r")
end
if file ~= nil then
if string.sub(v,string.len(v)-3) == ".lua" then
file:close()
dofile(ROOTPATH.."/"..path.."/"..v)
else
local response = file:read("*a")
sendheaders(path,#response)
client:send(response)
file:close()
end
responded = true
end
end
end
if responded == false then
doerror(404)
end
elseif string.find(path,"%.") == nil then
for k,v in pairs(indexes) do
if responded == false then
local filetype = getfiletype(path)
if filetype == true then
local file = io.open(ROOTPATH.."/"..path.."/"..v, "rb")
else
local file = io.open(ROOTPATH.."/"..path.."/"..v, "r")
end
if file ~= nil then
if string.sub(v,string.len(v)-3) == ".lua" then
file:close()
dofile(ROOTPATH.."/"..path.."/"..v)
else
local response = file:read("*a")
sendheaders(path,#response)
client:send(response)
file:close()
end
responded = true
end
end
end
if responded == false then
doerror(404)
end
elseif string.sub(path,string.len(path)-3) == ".lua" then
local file = io.open(ROOTPATH.."/"..path, "r")
if file ~= nil then
file:close()
dofile(ROOTPATH..path)
else
doerror(404)
end
else
local file
local filetype = getfiletype(path)
if filetype == true then
file = io.open(ROOTPATH.."/"..path, "rb")
else
file = io.open(ROOTPATH.."/"..path, "r")
end
if file ~= nil then
local response = file:read("*a")
sendheaders(path,#response)
client:send(response)
file:close()
else
doerror(404)
end
end
end
dofile("config.lua")
copas.addserver(socket.bind("*", PORT), ClientHandler)
printparadiso("Project Paradiso is running, active on port "..PORT.."!")
copas.loop()