From dbe3f4e153f69847b8611e6d26de5769adf2c24e Mon Sep 17 00:00:00 2001 From: Tomas Guisasola Date: Fri, 24 Jun 2005 16:57:09 +0000 Subject: [PATCH] Updating to Compat-5.1 and LuaSocket 2.0b3. Small improvements. --- src/cgi.lua | 143 +++++++++++++++++++++++++++++++++++++-------------- src/http.lua | 21 +++++--- 2 files changed, 119 insertions(+), 45 deletions(-) diff --git a/src/cgi.lua b/src/cgi.lua index 9e3d275..2466cbd 100755 --- a/src/cgi.lua +++ b/src/cgi.lua @@ -1,21 +1,54 @@ +#!/usr/local/bin/lua50 -- See Copyright Notice in license.html -- $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"post" -post.setmaxinput (1024 * 1024) -post.setmaxfilesize (512 * 1024) +require"cgilua.post" --------------------------------------------------------------------- -function respond (resp) - io.stdout:write (string.format ([[Date: %s -Server: Me -Content-Type: text/xml -Content-Length: %d -Connection: close - -%s -]], os.date(), string.len(resp), resp)) +local function respond (resp) + SAPI.Response.header ("Date", os.date()) + SAPI.Response.header ("Server", "Me") + SAPI.Response.header ("Content-length", string.len (resp)) + SAPI.Response.header ("Connection", "close") + SAPI.Response.contenttype ("text/xml") + SAPI.Response.write (resp) end --------------------------------------------------------------------- @@ -31,9 +64,49 @@ function assert (cond, msg) 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_products = { "luasql", "lualdap", "luaexpat", "luaxmlrpc", } local kepler_sites = { @@ -43,9 +116,18 @@ local kepler_sites = { luaxmlrpc = kepler_home.."/luaxmlrpc", } -xmlrpc.srvMethods { +local __methods +__methods = { 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 = { products = function (self) return kepler_products end, @@ -53,28 +135,13 @@ xmlrpc.srvMethods { }, } -local doc = {} -post.parsedata (doc) - -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 +--------------------------------------------------------------------- +-- Main +--------------------------------------------------------------------- +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) respond (r) diff --git a/src/http.lua b/src/http.lua index b119a61..c720a3a 100755 --- a/src/http.lua +++ b/src/http.lua @@ -4,12 +4,13 @@ -- $Id$ --------------------------------------------------------------------- -require"socket" +require"socket.http" +require"ltn12" require"xmlrpc" -local post = socket.http.post +local request = socket.http.request -xmlrpc.http = {} +module("xmlrpc.http") --------------------------------------------------------------------- -- Call a remote method. @@ -18,18 +19,24 @@ xmlrpc.http = {} -- @return Table with the response (could be a `fault' or a `params' -- XML-RPC element). --------------------------------------------------------------------- -function xmlrpc.http.call (url, method, ...) - local body, headers, code, err = post { +function call (url, method, ...) + local request_sink, tbody = ltn12.sink.table() + local request_body = xmlrpc.clEncode(method, unpack (arg)) + local err, code, headers, status = request { url = url, - body = xmlrpc.clEncode (method, unpack (arg)), + method = "POST", + source = ltn12.source.string (request_body), + sink = request_sink, headers = { ["User-agent"] = "LuaXMLRPC", ["Content-type"] = "text/xml", + ["content-length"] = tostring (string.len (request_body)), }, } + local body = table.concat (tbody) if tonumber (code) == 200 then return xmlrpc.clDecode (body) else - error (err or code) + error (tostring (err or code).."\n\n"..tostring(body)) end end