mirror of
https://github.com/lxsang/antd-lua-plugin
synced 2025-07-23 09:20:05 +02:00
Use unix domain socket to process lua handlers
This commit is contained in:
188
APIs/api.lua
188
APIs/api.lua
@ -1,10 +1,70 @@
|
||||
|
||||
package.cpath = __api__.apiroot..'/?.so'
|
||||
require("antd")
|
||||
|
||||
local readline = function()
|
||||
local s = ""
|
||||
repeat
|
||||
local c = modules.std().antd_recv(HTTP_REQUEST.id,1)
|
||||
if c ~= 0 and c ~= 10 then
|
||||
s = s..utf8.char(c)
|
||||
end
|
||||
until(c == 0 or c == 10)
|
||||
return s
|
||||
end
|
||||
local read_header =function()
|
||||
repeat
|
||||
local l = readline()
|
||||
if l ~= '\r' then
|
||||
if l == "HTTP_REQUEST" or l == "request" or l == "COOKIE" or l == "REQUEST_HEADER" or l == "REQUEST_DATA" then
|
||||
coroutine.yield(l, "LUA_TABLE")
|
||||
else
|
||||
local l1 = readline()
|
||||
if l1 ~= '\r' then
|
||||
coroutine.yield(l, l1)
|
||||
end
|
||||
l = l1
|
||||
end
|
||||
end
|
||||
until l == '\r'
|
||||
end
|
||||
|
||||
|
||||
local read_headers = function()
|
||||
local co = coroutine.create(function () read_header() end)
|
||||
return function () -- iterator
|
||||
local code, k, v = coroutine.resume(co)
|
||||
return k,v
|
||||
end
|
||||
end
|
||||
|
||||
local parse_headers =function()
|
||||
local lut = {
|
||||
HTTP_REQUEST = HTTP_REQUEST
|
||||
}
|
||||
local curr_tbl = "HTTP_REQUEST"
|
||||
for k,v in read_headers() do
|
||||
if v == "LUA_TABLE" then
|
||||
if not lut[k] then
|
||||
lut[k] = {}
|
||||
end
|
||||
curr_tbl = k
|
||||
else
|
||||
lut[curr_tbl][k] = v
|
||||
end
|
||||
end
|
||||
HTTP_REQUEST.request = lut.request
|
||||
HTTP_REQUEST.request.COOKIE = lut.COOKIE
|
||||
HTTP_REQUEST.request.REQUEST_HEADER = lut.REQUEST_HEADER
|
||||
HTTP_REQUEST.request.REQUEST_DATA = lut.REQUEST_DATA
|
||||
end
|
||||
|
||||
-- parsing the header
|
||||
parse_headers()
|
||||
-- root dir
|
||||
__ROOT__ = __api__.root
|
||||
__ROOT__ = HTTP_REQUEST.request.SERVER_WWW_ROOT
|
||||
-- set require path
|
||||
package.path = __ROOT__ .. '/?.lua;'..__api__.apiroot..'/?.lua'
|
||||
package.cpath = __api__.apiroot..'/?.so'
|
||||
|
||||
require("antd")
|
||||
require("std")
|
||||
require("utils")
|
||||
require("extra_mime")
|
||||
@ -24,6 +84,14 @@ if HEADER["User-Agent"] and HEADER["User-Agent"]:match("Mobi") then
|
||||
HEADER.mobile = true
|
||||
end
|
||||
|
||||
function LOG_INFO(fmt,...)
|
||||
ulib.syslog(5,string.format(fmt, table.unpack({...})))
|
||||
end
|
||||
|
||||
function LOG_ERROR(fmt,...)
|
||||
ulib.syslog(3,string.format(fmt, table.unpack({...})))
|
||||
end
|
||||
|
||||
function has_module(m)
|
||||
if utils.file_exists(__ROOT__..'/'..m) then
|
||||
if m:find("%.ls$") then
|
||||
@ -102,7 +170,6 @@ function loadscript(file, args)
|
||||
end
|
||||
end
|
||||
pro = pro.."\""..utils.escape(tmp:gsub("%%","%%%%")).."\")\n"
|
||||
--print(pro)
|
||||
else
|
||||
html = html..std.trim(line," "):gsub("%%","%%%%").."\n"
|
||||
end
|
||||
@ -118,12 +185,121 @@ function loadscript(file, args)
|
||||
pro = pro.."echo(\""..utils.escape(html).."\")\n"
|
||||
end
|
||||
pro = pro.."\nend \n return fn"
|
||||
--print(pro)
|
||||
local r,e = load(pro)
|
||||
if r then return r(), e else return nil,e end
|
||||
end
|
||||
end
|
||||
|
||||
local decode_post_data = function(ctype, clen, is_url)
|
||||
local raw_data,size = std.antd_recv(HTTP_REQUEST.id, clen)
|
||||
if not raw_data or size ~= clen then
|
||||
LOG_ERROR("Unable to read request data: received %d bytes expected %d bytes", size, clen)
|
||||
return 400, "Unable to read request data"
|
||||
end
|
||||
if is_url then
|
||||
local str = tostring(raw)
|
||||
local arr = explode(str, "&")
|
||||
LOG_INFO("encoded POST URI: %s", str)
|
||||
for i,v in ipairs(arr) do
|
||||
local assoc = explode(v,"=")
|
||||
if #assoc == 2 then
|
||||
REQUEST[assoc[1]] = untils.decodeURI(assoc[2])
|
||||
else
|
||||
REQUEST[assoc[1]] = ""
|
||||
end
|
||||
end
|
||||
else
|
||||
local key = ctype:gsub("^[^/]*", "")
|
||||
REQUEST[key] = raw_data
|
||||
end
|
||||
return 0
|
||||
end
|
||||
|
||||
local decode_multi_part = function(ctype, clen)
|
||||
--[[
|
||||
local arr = explode(ctype, "=")
|
||||
if #arr ~= 2 then
|
||||
LOG_ERROR("Unable to parsed boundary for: %s", ctype)
|
||||
return 400, "Multipart Boundary not found"
|
||||
end
|
||||
local boundary = std.trim(arr[2]," ")
|
||||
local boundary_end = boundary.."--"
|
||||
LOG_INFO("Boundary found: %s", boundary)
|
||||
local line = nil
|
||||
repeat
|
||||
line = readline()
|
||||
until not line or line:find(boundary) or line == ""
|
||||
if not line or line == "" then
|
||||
LOG_ERROR("Cannot find first match for boundary %s", boundary)
|
||||
return 400, "Unable to decode data based on content boundary"
|
||||
end
|
||||
repeat
|
||||
line = readline()
|
||||
until not line or line:find("Content-Disposition:") or line == ""
|
||||
if not line or line == "" then
|
||||
LOG_ERROR("Content-Disposition meta data not fond")
|
||||
return 400, "Unable to query Content-Disposition from request"
|
||||
end
|
||||
line = line:gsub("Content-Disposition:",""):gsub("\r\n","")
|
||||
-- extract parameters from header
|
||||
arr = explode(line,";")
|
||||
local part_name, part_file = nil, nil
|
||||
for i,v in ipairs(arr) do
|
||||
LOG_INFO('Decoding: %s', v)
|
||||
local assoc = explode(v, "=")
|
||||
local key = std.trim(assoc[1])
|
||||
local val = assoc[1]
|
||||
if val then
|
||||
val = std.trim(val, " ")
|
||||
if key == "name" then
|
||||
LOG_INFO("Part name: %s", val)
|
||||
part_name = val
|
||||
end
|
||||
if key == "filename" then
|
||||
LOG_INFO("Part file: %s", val)
|
||||
part_file = val
|
||||
end
|
||||
end
|
||||
end
|
||||
-- TODO: to be continue
|
||||
]]
|
||||
return 0
|
||||
end
|
||||
-- decode post data if any
|
||||
local decode_request = function()
|
||||
LOG_INFO("Request method %s", REQUEST.method)
|
||||
if (not REQUEST.method)
|
||||
or (REQUEST.method ~= "POST"
|
||||
and REQUEST.method ~= "PUT"
|
||||
and REQUEST.method ~= "PATCH") then
|
||||
return 0
|
||||
end
|
||||
local ctype = HEADER['Content-Type']
|
||||
local clen = HEADER['Content-Length'] or -1
|
||||
if clen then
|
||||
clen = tonumber(clen)
|
||||
end
|
||||
if not ctype or clen == -1 then
|
||||
LOG_ERROR("Invalid content type %s or content length %d", ctype, clen)
|
||||
return 400, "Bad Request, missing content description"
|
||||
end
|
||||
if ctype == "application/x-www-form-urlencoded" then
|
||||
return decode_post_data(ctype, clen, true)
|
||||
elseif ctype == "multipart/form-data" then
|
||||
return decode_multi_part(ctype, clen)
|
||||
else
|
||||
return decode_post_data(ctype, clen, false)
|
||||
end
|
||||
end
|
||||
|
||||
local code, error = decode_request()
|
||||
|
||||
if code ~= 0 then
|
||||
LOG_ERROR(error)
|
||||
std.error(code, error)
|
||||
return
|
||||
end
|
||||
|
||||
-- OOP support
|
||||
--require("OOP")
|
||||
-- load sqlite helper
|
||||
|
@ -61,7 +61,7 @@ function std.b(s)
|
||||
std._b(HTTP_REQUEST.id,s)
|
||||
end
|
||||
function std.f(v)
|
||||
std._f(HTTP_REQUEST.id,v)
|
||||
ulib.send_file(v, HTTP_REQUEST.socket)
|
||||
end
|
||||
|
||||
function std.setCookie(v)
|
||||
|
74
APIs/web.lua
74
APIs/web.lua
@ -1,74 +0,0 @@
|
||||
-- require the utils library to work
|
||||
--require("utils")
|
||||
-- require("std")
|
||||
local wurl = require("wurl")
|
||||
|
||||
local web = {}
|
||||
|
||||
web.understand = function(proto)
|
||||
if proto == "http" or proto == "https" then
|
||||
return true
|
||||
else
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
web.get = function(url)
|
||||
local obj = utils.url_parser(url)
|
||||
if web.understand(obj.protocol) then
|
||||
return wurl._get(obj.hostname,obj.port, obj.query)
|
||||
else
|
||||
return nil,"Protocol is unsupported: "..obj.protocol
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
web.post = function(url,data)
|
||||
local obj = utils.url_parser(url)
|
||||
if web.understand(obj.protocol) then
|
||||
if type(data) == "string" then
|
||||
return wurl._post(obj.hostname,
|
||||
obj.port,
|
||||
obj.query,
|
||||
"application/x-www-form-urlencoded",data)
|
||||
else
|
||||
return wurl._post(obj.hostname,
|
||||
obj.port,
|
||||
obj.query,
|
||||
data.contentType,data.value)
|
||||
end
|
||||
else
|
||||
return nil,"Protocol is unsupported: "..obj.protocol
|
||||
end
|
||||
end
|
||||
|
||||
web.download = function(url,to)
|
||||
local obj = utils.url_parser(url)
|
||||
if web.understand(obj.protocol) then
|
||||
local file
|
||||
if std.is_dir(to) then
|
||||
-- need to find file name here
|
||||
local pattern = "^[^%?]*/([%w.]*)%??.*$"
|
||||
local filename = string.gsub(obj.query,pattern,"%1")
|
||||
if filename == "" then filename = "index" end
|
||||
file = to.."/"..filename
|
||||
else
|
||||
file = to
|
||||
end
|
||||
local obj = utils.url_parser(url)
|
||||
return wurl._download(obj.hostname,obj.port,obj.query,file)
|
||||
else
|
||||
return false,"Protocol is unsupported: "..obj.protocol
|
||||
end
|
||||
end
|
||||
|
||||
web.upload = function(url,name,file)
|
||||
local obj = utils.url_parser(url)
|
||||
if web.understand(obj.protocol) then
|
||||
return wurl._upload(obj.hostname,obj.port,obj.query,name,file)
|
||||
else
|
||||
return nil,"Protocol is unsupported: "..obj.protocol
|
||||
end
|
||||
end
|
||||
|
||||
return web
|
Reference in New Issue
Block a user