mirror of
https://github.com/mkschreder/juci.git
synced 2025-01-08 11:57:39 +08:00
Added experimental lua http server
This commit is contained in:
parent
b8f45b06ba
commit
cb024c1cb8
103
http-server.lua
Normal file
103
http-server.lua
Normal file
@ -0,0 +1,103 @@
|
||||
local http = require("http")
|
||||
local fs = require('fs')
|
||||
local uv = require("uv");
|
||||
local json = require("json");
|
||||
|
||||
require("ubus");
|
||||
|
||||
local PORT = 8000
|
||||
|
||||
|
||||
local conn = ubus.connect()
|
||||
if not conn then
|
||||
error("Failed to connect to ubus")
|
||||
end
|
||||
|
||||
|
||||
local mime_types = {
|
||||
html = "text/html",
|
||||
js = "application/javascript",
|
||||
css = "text/css",
|
||||
jpg = "image/jpeg",
|
||||
jpeg = "image/jpeg",
|
||||
png = "image/png",
|
||||
text = "text/plain"
|
||||
};
|
||||
|
||||
local rpcid = 0;
|
||||
|
||||
http.createServer({}, function(req, res)
|
||||
--print(json.stringify(req));
|
||||
local path = req.url;
|
||||
if path == "/" then path = "index.html"; end
|
||||
path = "/www/"..path;
|
||||
|
||||
local ext = path:match("^.+(%..+)$") or "text";
|
||||
|
||||
local not_found = "Not found!";
|
||||
|
||||
if(req.method == "POST" and req.url == "/ubus") then
|
||||
local buffer = {}
|
||||
|
||||
req:on('data', function(chunk)
|
||||
table.insert(buffer, chunk)
|
||||
end)
|
||||
req:on('end', function()
|
||||
local data = "";
|
||||
for i,v in ipairs(buffer) do data = data..v; end
|
||||
local post = json.parse(data);
|
||||
local result = { jsonrpc = "2.0", id = rpcid };
|
||||
rpcid = rpcid +1;
|
||||
if post.method == "list" then
|
||||
local objects = {};
|
||||
local namespaces = conn:objects()
|
||||
for i, n in ipairs(namespaces) do
|
||||
local signatures = conn:signatures(n)
|
||||
local methods = {};
|
||||
print("object="..n);
|
||||
for p, s in pairs(signatures) do
|
||||
local meth = {};
|
||||
print("\tprocedure=" .. p)
|
||||
for k, v in pairs(s) do
|
||||
print("\t\tattribute=" .. k .. " type=" .. v)
|
||||
end
|
||||
methods[p] = meth;
|
||||
end
|
||||
objects[n] = methods;
|
||||
end
|
||||
result["result"] = objects;
|
||||
elseif post.method == "call" then
|
||||
print("Call: "..post.params[2].." "..post.params[3].." "..json.stringify(post.params[4]));
|
||||
local r,code = conn:call(post.params[2], post.params[3], post.params[4]);
|
||||
result["result"] = {code or 0, r or {}};
|
||||
end
|
||||
local body = json.stringify(result);
|
||||
res:setHeader("Content-Type", "text/json");
|
||||
res:setHeader("Content-Length", #body)
|
||||
print("Result: "..body);
|
||||
res:finish(body);
|
||||
end)
|
||||
else
|
||||
if fs.existsSync(path..".gz") then
|
||||
print("Found gzipped version of "..path);
|
||||
path = path..".gz";
|
||||
res:setHeader("Content-Encoding", "gzip");
|
||||
end
|
||||
|
||||
if not fs.existsSync(path) then
|
||||
res:setHeader("Content-Type", "text/plain")
|
||||
res:setHeader("Content-Length", #not_found)
|
||||
res:finish(not_found)
|
||||
else
|
||||
local body = fs.readFileSync(path);
|
||||
|
||||
res:setHeader("Content-Type", mime_types[ext])
|
||||
res:setHeader("Content-Length", #body)
|
||||
|
||||
res:finish(body)
|
||||
end
|
||||
end
|
||||
end):listen(PORT)
|
||||
print("Server listening at http://localhost:"..PORT)
|
||||
|
||||
uv.run();
|
@ -149,12 +149,14 @@ function ServerResponse:flushHeaders()
|
||||
self.headersSent = true
|
||||
local headers = self.headers
|
||||
local statusCode = self.statusCode
|
||||
|
||||
|
||||
local head = {}
|
||||
local sent_date, sent_connection, sent_transfer_encoding, sent_content_length
|
||||
for key,value in pairs(headers) do
|
||||
for i,v in ipairs(headers) do
|
||||
local key, value = unpack(v);
|
||||
local klower = tostring(key):lower()
|
||||
head[#head + 1] = {tostring(key), tostring(value)}
|
||||
|
||||
table.insert(head, {tostring(key), tostring(value)});
|
||||
if klower == "connection" then
|
||||
self.keepAlive = value:lower() ~= "close"
|
||||
sent_connection = true
|
||||
@ -243,7 +245,7 @@ function ServerResponse:writeHead(newStatusCode, newHeaders)
|
||||
assert(not self.headersSent, "headers already sent")
|
||||
self.statusCode = newStatusCode
|
||||
local headers = setmetatable({}, headerMeta)
|
||||
self.headers = headers
|
||||
--self.headers = headers
|
||||
for k, v in pairs(newHeaders) do
|
||||
headers[k] = v
|
||||
end
|
||||
|
@ -274,7 +274,10 @@ encode2 = function (value, indent, level, buffer, buflen, tables, globalorder, s
|
||||
local valtojson = valmeta and valmeta.__tojson
|
||||
if valtojson then
|
||||
if tables[value] then
|
||||
return exception('reference cycle', value, state, buffer, buflen)
|
||||
buflen = buflen + 1
|
||||
buffer[buflen] = quotestring ("[[cyclic value]]");
|
||||
return buflen;
|
||||
--return exception('reference cycle', value, state, buffer, buflen)
|
||||
end
|
||||
tables[value] = true
|
||||
state.bufferlen = buflen
|
||||
@ -365,8 +368,10 @@ encode2 = function (value, indent, level, buffer, buflen, tables, globalorder, s
|
||||
end
|
||||
tables[value] = nil
|
||||
else
|
||||
return exception ('unsupported type', value, state, buffer, buflen,
|
||||
"type '" .. valtype .. "' is not supported by JSON.")
|
||||
buflen = buflen + 1
|
||||
buffer[buflen] = quotestring ("["..valtype.."]");
|
||||
--return exception ('unsupported type', value, state, buffer, buflen,
|
||||
-- "type '" .. valtype .. "' is not supported by JSON.")
|
||||
end
|
||||
return buflen
|
||||
end
|
||||
@ -380,7 +385,10 @@ function json.encode (value, state)
|
||||
local ret, msg = encode2 (value, state.indent, state.level or 0,
|
||||
buffer, state.bufferlen or 0, state.tables or {}, state.keyorder, state)
|
||||
if not ret then
|
||||
error (msg, 2)
|
||||
state.bufferlen = nil
|
||||
state.buffer = nil
|
||||
return concat (buffer)
|
||||
--error (msg, 2)
|
||||
elseif oldbuffer == buffer then
|
||||
state.bufferlen = ret
|
||||
return true
|
||||
|
Loading…
Reference in New Issue
Block a user