All pastes #728887 Raw Edit

Unnamed

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