All pastes #728917 Raw Edit

Someone

public text v1 · immutable
·published 2007-10-07 14:19 UTC
rendered paste body
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()