# signature { license=0, seed=457995617, key="aa21be7af248b1042f542c1b2e0067d7" }
--
-- cgi library
--
-- used to operate the WebPRO cgi mechanism on NEC PBX systems 
-- 
if not CGI then return end
require "socket" -- brings GCI.socket to life
if CGI.sslsocket then require "ssl" end -- inits GCI injected SSL connection

local cgi = CGI
local sock = cgi.socket
local closed = false
local tostring,concat,format,char,gsub = tostring,table.concat,string.format,string.char,string.gsub

cgi._VERSION = "cgi 1.5.0"	

cgi.reset = function()
	cgi.status = "200 OK"
	cgi.headers = { ["Content-Type"] = "text/html; charset=UTF-8"; ["Connection"]="close";}
	cgi.content = {}
	closed = false
end

cgi.header = function( name, value)
	CGI.headers[ name ] = tostring(value or "")
end

cgi.print = function(...)
	local args = { ... }
	for i = 1, select("#",...) do
		args[i] = tostring(args[i])
	end
	cgi.content[1+#cgi.content] = table.concat(args)
end

cgi.printf = function( formatstring, ... )
	cgi.print( format( formatstring, ...))
end

--
-- disables further output
--
cgi.close = function() closed = true end

--
-- sends out all HTTP response headers and content
--
cgi.flush = function()
	if closed then return end
	local H = concat( cgi.content )
	cgi.header( "Content-Length", #H)	

	sock:send( format( "HTTP/1.1 %s\r\n", cgi.status))
	for k,v in pairs( cgi.headers ) do
		sock:send( format("%s: %s\r\n", k, v))
	end
	sock:send( "\r\n")
	sock:send( H)
end

cgi.commit = function()
	cgi.flush()
	cgi.reset()
	-- new in 1.1 remove previously read request headers
	-- (all fields with capital keys)
	for k in next, cgi do
		if string.find( k, "^%u") then cgi[k] = nil end
	end
end

cgi.send   = function(...) return sock:send(...)    end
cgi.receive= function(...) return sock:receive(...) end

--
-- read the header lines and add the contained data to the cgi table
--
cgi.begin = function()
	-- if the WebPRO called the script, REQUEST_METHOD is already set,
	-- so we skip reading the request line
	if not cgi.REQUEST_METHOD then
		local s = sock:receive()   -- read request line
		if not s then return end
		-- match it against: (uppercase word) ' ' (non-'?') optional '?' (non-' ') ' '
		cgi.REQUEST_METHOD, cgi.REQUEST_URI, cgi.QUERY_STRING = s:match("^(%u+) ([^?]*)%??(%S*) ")
	end
	
	-- read HTTP header lines, stop at first empty line
	repeat
		local s = sock:receive()
		if not s then break end
	
		local k,v = string.match(s,"^(.-):%s*(.*)$") -- split at :
		if k then
			k = gsub( string.upper(k), "[-]", "_")
			cgi[k] = v
		end
	until s==""
	
	-- set default response headers and status
	cgi.reset()
	return true
end

local function unescape(s)  
    return gsub( s, "%%(%x%x)", function(hex) return char(tonumber(hex, 16)) end )
end
cgi.unescape = unescape

cgi.urldecode = function( s )
	local T = {}
	s = gsub( s, "+", " " )
	gsub( s, "([^=]+)=([^&]*)&?", function(k,v) T[ unescape(k) ] = unescape(v) end )
	return T
end

--
-- initalise CGI by reading all headers etc
--
cgi.begin()           

--
-- on program end, send all stuff to client
--
setmetatable( cgi, {__gc = cgi.flush })

return cgi
