parent
a9c402a861
commit
dbe3f4e153
143
src/cgi.lua
143
src/cgi.lua
|
@ -1,21 +1,54 @@
|
||||||
|
#!/usr/local/bin/lua50
|
||||||
-- See Copyright Notice in license.html
|
-- See Copyright Notice in license.html
|
||||||
-- $Id$
|
-- $Id$
|
||||||
|
|
||||||
|
SAPI = {
|
||||||
|
Request = {},
|
||||||
|
Response = {},
|
||||||
|
Info = { -- Information data
|
||||||
|
_COPYRIGHT = "Copyright (C) 2004-2005 Kepler Project",
|
||||||
|
_DESCRIPTION = "CGI SAPI implementation",
|
||||||
|
_VERSION = "1.0",
|
||||||
|
ispersistent = false,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
-- Headers
|
||||||
|
SAPI.Response.contenttype = function (s)
|
||||||
|
io.stdout:write ("Content-type: "..s.."\n\n")
|
||||||
|
end
|
||||||
|
SAPI.Response.redirect = function (s)
|
||||||
|
io.stdout:write ("Location: "..s.."\n\n")
|
||||||
|
end
|
||||||
|
SAPI.Response.header = function (h, v)
|
||||||
|
io.stdout:write (string.format ("%s: %s\n", h, v))
|
||||||
|
end
|
||||||
|
-- Contents
|
||||||
|
SAPI.Response.write = function (s) io.stdout:write (s) end
|
||||||
|
SAPI.Response.errorlog = function (s) io.stderr:write (s) end
|
||||||
|
-- Input POST data
|
||||||
|
SAPI.Request.getpostdata = function (n) return io.stdin:read (n) end
|
||||||
|
-- Input general information
|
||||||
|
SAPI.Request.servervariable = function (n) return os.getenv(n) end
|
||||||
|
|
||||||
|
if string.find(_VERSION, "Lua 5.0.2") and not _COMPAT51 then
|
||||||
|
local root = "/usr/local/share/lua/5.0/"
|
||||||
|
LUA_PATH = root.."?.lua;"..root.."?/init.lua;"..root.."?/?.lua"
|
||||||
|
require"compat-5.1"
|
||||||
|
root = "/usr/local/lib/lua/5.0/"
|
||||||
|
package.cpath = root.."?.so;"..root.."l?.so"
|
||||||
|
end
|
||||||
|
|
||||||
require"xmlrpc"
|
require"xmlrpc"
|
||||||
require"post"
|
require"cgilua.post"
|
||||||
post.setmaxinput (1024 * 1024)
|
|
||||||
post.setmaxfilesize (512 * 1024)
|
|
||||||
|
|
||||||
---------------------------------------------------------------------
|
---------------------------------------------------------------------
|
||||||
function respond (resp)
|
local function respond (resp)
|
||||||
io.stdout:write (string.format ([[Date: %s
|
SAPI.Response.header ("Date", os.date())
|
||||||
Server: Me
|
SAPI.Response.header ("Server", "Me")
|
||||||
Content-Type: text/xml
|
SAPI.Response.header ("Content-length", string.len (resp))
|
||||||
Content-Length: %d
|
SAPI.Response.header ("Connection", "close")
|
||||||
Connection: close
|
SAPI.Response.contenttype ("text/xml")
|
||||||
|
SAPI.Response.write (resp)
|
||||||
%s
|
|
||||||
]], os.date(), string.len(resp), resp))
|
|
||||||
end
|
end
|
||||||
|
|
||||||
---------------------------------------------------------------------
|
---------------------------------------------------------------------
|
||||||
|
@ -31,9 +64,49 @@ function assert (cond, msg)
|
||||||
end
|
end
|
||||||
|
|
||||||
---------------------------------------------------------------------
|
---------------------------------------------------------------------
|
||||||
-- Main
|
local function getdata ()
|
||||||
---------------------------------------------------------------------
|
local doc = {}
|
||||||
|
cgilua.post.parsedata {
|
||||||
|
read = SAPI.Request.getpostdata,
|
||||||
|
discardinput = nil,
|
||||||
|
content_type = SAPI.Request.servervariable"CONTENT_TYPE",
|
||||||
|
content_length = SAPI.Request.servervariable"CONTENT_LENGTH",
|
||||||
|
maxinput = 2 * 1024 * 1024,
|
||||||
|
maxfilesize = 1024 * 1024,
|
||||||
|
args = doc,
|
||||||
|
}
|
||||||
|
return doc[1]
|
||||||
|
end
|
||||||
|
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
local function decodedata (doc)
|
||||||
|
local method, arg_table = xmlrpc.srvDecode (doc)
|
||||||
|
assert (type(method) == "string", "Invalid `method': string expected")
|
||||||
|
local t = type(arg_table)
|
||||||
|
assert (t == "table" or t == "nil", "Invalid table of arguments: not a table nor nil")
|
||||||
|
|
||||||
|
local func = xmlrpc.dispatch (method)
|
||||||
|
assert (type(func) == "function", "Unavailable method")
|
||||||
|
|
||||||
|
return func, (arg_table or {})
|
||||||
|
end
|
||||||
|
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
local function callfunc (func, arg_table)
|
||||||
|
local result = { pcall (func, unpack (arg_table)) }
|
||||||
|
local ok = result[1]
|
||||||
|
if not ok then
|
||||||
|
result = { code = 3, message = result[2], }
|
||||||
|
else
|
||||||
|
table.remove (result, 1)
|
||||||
|
if table.getn (result) == 1 then
|
||||||
|
result = result[1]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return ok, result
|
||||||
|
end
|
||||||
|
|
||||||
|
---------------------------------------------------------------------
|
||||||
local kepler_home = "http://www.keplerproject.org"
|
local kepler_home = "http://www.keplerproject.org"
|
||||||
local kepler_products = { "luasql", "lualdap", "luaexpat", "luaxmlrpc", }
|
local kepler_products = { "luasql", "lualdap", "luaexpat", "luaxmlrpc", }
|
||||||
local kepler_sites = {
|
local kepler_sites = {
|
||||||
|
@ -43,9 +116,18 @@ local kepler_sites = {
|
||||||
luaxmlrpc = kepler_home.."/luaxmlrpc",
|
luaxmlrpc = kepler_home.."/luaxmlrpc",
|
||||||
}
|
}
|
||||||
|
|
||||||
xmlrpc.srvMethods {
|
local __methods
|
||||||
|
__methods = {
|
||||||
system = {
|
system = {
|
||||||
listMethods = function (self) return { "system.listMethods" } end,
|
listMethods = function (self)
|
||||||
|
local l = {}
|
||||||
|
for name, obj in pairs (__methods) do
|
||||||
|
for method in pairs (obj) do
|
||||||
|
table.insert (l, name.."."..method)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return l
|
||||||
|
end,
|
||||||
},
|
},
|
||||||
kepler = {
|
kepler = {
|
||||||
products = function (self) return kepler_products end,
|
products = function (self) return kepler_products end,
|
||||||
|
@ -53,28 +135,13 @@ xmlrpc.srvMethods {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
local doc = {}
|
---------------------------------------------------------------------
|
||||||
post.parsedata (doc)
|
-- Main
|
||||||
|
---------------------------------------------------------------------
|
||||||
local method, arg_table = xmlrpc.srvDecode (doc[1])
|
|
||||||
assert (type(method) == "string", "Invalid `method': string expected")
|
|
||||||
local t = type(arg_table)
|
|
||||||
assert (t == "table" or t == "nil", "Invalid table of arguments: not a table nor nil")
|
|
||||||
|
|
||||||
local func = xmlrpc.dispatch (method)
|
|
||||||
assert (type(func) == "function", "Unavailable method")
|
|
||||||
|
|
||||||
local result = { pcall (func, unpack (arg_table or {})) }
|
|
||||||
|
|
||||||
local ok = result[1]
|
|
||||||
if not ok then
|
|
||||||
result = { code = 3, message = result[2], }
|
|
||||||
else
|
|
||||||
table.remove (result, 1)
|
|
||||||
if table.getn (result) == 1 then
|
|
||||||
result = result[1]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
|
xmlrpc.srvMethods (__methods)
|
||||||
|
local doc = getdata ()
|
||||||
|
local func, arg_table = decodedata (doc)
|
||||||
|
local ok, result = callfunc (func, arg_table)
|
||||||
local r = xmlrpc.srvEncode (result, not ok)
|
local r = xmlrpc.srvEncode (result, not ok)
|
||||||
respond (r)
|
respond (r)
|
||||||
|
|
21
src/http.lua
21
src/http.lua
|
@ -4,12 +4,13 @@
|
||||||
-- $Id$
|
-- $Id$
|
||||||
---------------------------------------------------------------------
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
require"socket"
|
require"socket.http"
|
||||||
|
require"ltn12"
|
||||||
require"xmlrpc"
|
require"xmlrpc"
|
||||||
|
|
||||||
local post = socket.http.post
|
local request = socket.http.request
|
||||||
|
|
||||||
xmlrpc.http = {}
|
module("xmlrpc.http")
|
||||||
|
|
||||||
---------------------------------------------------------------------
|
---------------------------------------------------------------------
|
||||||
-- Call a remote method.
|
-- Call a remote method.
|
||||||
|
@ -18,18 +19,24 @@ xmlrpc.http = {}
|
||||||
-- @return Table with the response (could be a `fault' or a `params'
|
-- @return Table with the response (could be a `fault' or a `params'
|
||||||
-- XML-RPC element).
|
-- XML-RPC element).
|
||||||
---------------------------------------------------------------------
|
---------------------------------------------------------------------
|
||||||
function xmlrpc.http.call (url, method, ...)
|
function call (url, method, ...)
|
||||||
local body, headers, code, err = post {
|
local request_sink, tbody = ltn12.sink.table()
|
||||||
|
local request_body = xmlrpc.clEncode(method, unpack (arg))
|
||||||
|
local err, code, headers, status = request {
|
||||||
url = url,
|
url = url,
|
||||||
body = xmlrpc.clEncode (method, unpack (arg)),
|
method = "POST",
|
||||||
|
source = ltn12.source.string (request_body),
|
||||||
|
sink = request_sink,
|
||||||
headers = {
|
headers = {
|
||||||
["User-agent"] = "LuaXMLRPC",
|
["User-agent"] = "LuaXMLRPC",
|
||||||
["Content-type"] = "text/xml",
|
["Content-type"] = "text/xml",
|
||||||
|
["content-length"] = tostring (string.len (request_body)),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
local body = table.concat (tbody)
|
||||||
if tonumber (code) == 200 then
|
if tonumber (code) == 200 then
|
||||||
return xmlrpc.clDecode (body)
|
return xmlrpc.clDecode (body)
|
||||||
else
|
else
|
||||||
error (err or code)
|
error (tostring (err or code).."\n\n"..tostring(body))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue