require("socket")
require("copas")
indexes = {}
binarytypes = {}
dofile("config.lua")
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")
CURRENTCLIENT:send(response)
file:close()
else
local file = io.open("errors/unknown.html", "r")
local response = file:read("*a")
sendheaders("errors/unknown.html")
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 sendheaders(path)
CURRENTCLIENT:send("HTTP/1.x 200 OK\r\n")
CURRENTCLIENT:send("Server: Paradiso\r\n")
local temptable = table.explode(".",path)
local ftype = temptable[#temptable]
printparadiso(ftype)
if ftype == "html" then
CURRENTCLIENT:send("Content-Type: text/html\r\n")
elseif ftype == "htm" then
CURRENTCLIENT:send("Content-Type: text/html\r\n")
elseif ftype == "lua" then
CURRENTCLIENT:send("Content-Type: text/html\r\n")
elseif ftype == "bmp" then
CURRENTCLIENT:send("Content-Type: text/bmp\r\n")
elseif ftype == "jpg" then
CURRENTCLIENT:send("Content-Type: text/jpg\r\n")
else
CURRENTCLIENT:send("Content-Type: text/plain\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
printparadiso("Binary-type file")
return true
end
end
if foundtype == false then
printparadiso("Text-type file")
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)
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)
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 filetype = getfiletype(path)
if filetype == true then
local file = io.open(ROOTPATH.."/"..path, "rb")
else
local file = io.open(ROOTPATH.."/"..path, "r")
end
if file ~= nil then
local response = file:read("*a")
sendheaders(path)
client:send(response)
file:close()
else
doerror(404)
end
end
end
copas.addserver(socket.bind("*", PORT), ClientHandler)
printparadiso("Project Paradiso is running, active on port "..PORT.."!")
copas.loop()