basic http server; make it work with lua 5.1, 5.4 and luajit 2.1.0-beta3

This commit is contained in:
Nedko Arnaudov 2023-11-22 22:42:41 +02:00
parent 809a101ac8
commit 3f2f58bf6c
10 changed files with 235 additions and 77 deletions

105
http_server.lua Normal file
View File

@ -0,0 +1,105 @@
-- -*- Mode: Lua; indent-tabs-mode: nil; lua-indent-level: 2 -*-
-- LADI Continuous Integration (ladici)
-- SPDX-FileCopyrightText: Copyright © 2010-2023 Nedko Arnaudov */
-- SPDX-License-Identifier: GPL-2.0-or-later
local misc = require 'misc'
local function process_raw_msg(request, raw_msg)
--print('----receive----' .. tostring(raw_msg))
local verb
local path
local proto
local rest = raw_msg
if not request.verb then
-- verb path proto
rest, verb, path, proto = parse_and_consume(rest, "^([^ ]*) ([^ ]*) (.*)$")
--if verb then print(("verb: '%s'"):format(verb)) end
--if path then print(("path: '%s'"):format(path)) end
--if proto then print(("proto: '%s'"):format(proto)) end
--if rest then print(("rest: '%s'"):format(rest)) end
request.verb = verb
request.path = path
request.proto = proto
return false
end
-- header
rest, key, value = parse_and_consume(rest, "^([^:]*): (.*)$")
--if key then print(("key: '%s'"):format(key)) end
--if value then print(("value: '%s'"):format(value)) end
request.headers[key] = value
assert(not rest)
return false
end
local function remote_client_thread(peer)
print("Remote " .. peer.get_description() .. " connected")
function receive(peer, command_handlers)
local buffer
local request = { headers = {} }
while true do
local raw_msg
local data, err = peer.receive(4000)
-- print('[' .. tostring(data) .. ']')
-- print('[' .. tostring(err) .. ']')
if not data then return err end
if buffer then
buffer = buffer .. data
else
buffer = data
end
-- print('---> [' .. tostring(buffer) .. ']')
while buffer do
buffer, raw_msg = parse_and_consume(buffer, '^([^\r\n]*)\r\n')
--print('[' .. tostring(buffer) .. ']')
--print('[' .. tostring(raw_msg) .. ']')
if not raw_msg then break end
if raw_msg == '' then
--print("end of headers")
print(request.verb .. " " .. request.path .. "" .. request.proto)
misc.dump_table(request.headers)
return
end
if process_raw_msg(request, raw_msg) then return end
end
end
assert(false)
end
local function send(peer, msg)
-- print('-----send------' .. msg)
peer.send(msg .. "\r\n")
end
local host = peer.get_ip()
local err = receive(peer)
send(peer, "HTTP/1.1 200 OK")
send(peer, "")
send(peer, "")
send(peer, "LADI Continuous Integration")
send(peer, "WIP")
send(peer, "")
send(peer, "yeah!")
print(("Remote %s disconnected (%s)"):format(peer.get_description(), tostring(err)))
end
function create(remotes)
print('Creating HTTP server')
err = remotes.create_tcp_server(remote_client_thread, {{host='127.0.0.01', port=8010}})
if err then return err end
end
return {
create = create,
}

81
hub.lua
View File

@ -5,8 +5,6 @@
require 'misc'
module(..., package.seeall)
local interface = nil
channel_cls = {}
@ -70,49 +68,49 @@ function control_channel:outgoing_message(command)
function()
interface.disconnect()
for name,location in pairs(locations.registry) do
if location.connection then self:disconnect_location(name) end
end
-- for name,location in pairs(locations.registry) do
-- if location.connection then self:disconnect_location(name) end
-- end
return true -- break the receive loop
end
commands['locations'] =
function()
for name, dict in pairs(locations.registry) do
if dict.connection then status = "connected" else status = "disconnected" end
self:send_reply(("%s\t- %s"):format(name, status))
end
end
-- commands['locations'] =
-- function()
-- for name, dict in pairs(locations.registry) do
-- if dict.connection then status = "connected" else status = "disconnected" end
-- self:send_reply(("%s\t- %s"):format(name, status))
-- end
-- end
commands['connect'] =
function()
location = locations.registry['freenode']
-- commands['connect'] =
-- function()
-- location = locations.registry['freenode']
if location.connection then
self:send_reply("Location is already connected")
return
end
-- if location.connection then
-- self:send_reply("Location is already connected")
-- return
-- end
connection, err = protocols.registry[location.protocol].connect(location)
assert(connection or err)
if not connection then
self:send_reply(err)
else
self:send_reply("Location [" .. location.name .. "] connected successfully")
location.connection = connection
end
end
-- connection, err = protocols.registry[location.protocol].connect(location)
-- assert(connection or err)
-- if not connection then
-- self:send_reply(err)
-- else
-- self:send_reply("Location [" .. location.name .. "] connected successfully")
-- location.connection = connection
-- end
-- end
commands['disconnect'] =
function()
location = locations.registry['freenode']
if not location.connection then
self:send_reply("Location is not connected")
else
self:disconnect_location('freenode')
end
end
-- commands['disconnect'] =
-- function()
-- location = locations.registry['freenode']
-- if not location.connection then
-- self:send_reply("Location is not connected")
-- else
-- self:disconnect_location('freenode')
-- end
-- end
if commands[command] then
return commands[command]()
@ -195,3 +193,12 @@ function detach_interface(iface)
assert(interface == iface)
interface = nil
end
return {
attach_interface = attach_interface,
detach_interface = detach_interface,
incoming_message = incoming_message,
outgoing_message = outgoing_message,
get_channel = get_channel,
join = join,
}

17
irc.lua
View File

@ -3,18 +3,6 @@
-- SPDX-FileCopyrightText: Copyright © 2010-2023 Nedko Arnaudov */
-- SPDX-License-Identifier: GPL-2.0-or-later
module('irc', package.seeall)
local function parse_and_consume(buffer, regexp)
local b = 0
local e = 0
b, e, a1, a2, a3, a4 = buffer:find(regexp)
if not b then return buffer end
rest = buffer:sub(e + 1)
if rest == '' then rest = nil end
return rest, a1, a2, a3, a4
end
function parse_nick_prefix(prefix)
rest = prefix
b, e, host = rest:find('@(.+)')
@ -117,3 +105,8 @@ function send_to_peer(peer, msg)
-- print('-----send------' .. msg)
peer.send(msg .. "\r\n")
end
return {
receive = receive,
send_to_peer = send_to_peer,
}

View File

@ -3,7 +3,7 @@
-- SPDX-FileCopyrightText: Copyright © 2010-2023 Nedko Arnaudov */
-- SPDX-License-Identifier: GPL-2.0-or-later
module('irc_client', package.seeall)
--module('irc_client', package.seeall)
local function connect(location)
assert(location.args.host)
@ -167,6 +167,4 @@ local descriptor = {
connect=connect,
}
protocols.register(descriptor)
return {} -- nothing directly public here
return descriptor

View File

@ -3,10 +3,8 @@
-- SPDX-FileCopyrightText: Copyright © 2010-2023 Nedko Arnaudov */
-- SPDX-License-Identifier: GPL-2.0-or-later
require 'hub'
require 'irc'
module('irc_server', package.seeall)
local hub = require 'hub'
local irc = require 'irc'
local function remote_client_thread(peer)
print("Remote " .. peer.get_description() .. " connected")
@ -86,6 +84,9 @@ local function remote_client_thread(peer)
return hub.outgoing_message(msg, params[1])
end
command_handlers['JOIN'] = function(prefix, command, params)
print(("join [%s][%s]"):format(tostring(params[1]), tostring(prefix)))
end
command_handlers['WHO'] =
function(prefix, command, params)
channel = hub.get_channel(params[1])
@ -116,8 +117,12 @@ local function remote_client_thread(peer)
print(("Remote %s disconnected (%s)"):format(peer.get_description(), tostring(err)))
end
function create()
function create(remotes)
print('Creating IRC server')
err = remotes.create_tcp_server(remote_client_thread, {{host='*', port=6667}})
if err then return err end
end
return {
create = create,
}

44
ladici
View File

@ -4,18 +4,42 @@
-- SPDX-FileCopyrightText: Copyright © 2010-2023 Nedko Arnaudov */
-- SPDX-License-Identifier: GPL-2.0-or-later
require 'protocols'
require 'hub'
require 'remotes'
require 'locations'
require 'irc_client'
require 'irc_server'
local protocols = require 'protocols'
--local hub = require 'hub'
local remotes = require 'remotes'
local locations = require 'locations'
local irc_client = require 'irc_client'
local irc_server = require 'irc_server'
local http_server = require 'http_server'
local misc = require 'misc'
locations.register('localhost',
'IRC',
{host='localhost', nick='ladici', realname='Operator Real Name', join='#ladi'})
local homedir = os.getenv('HOME')
if not homedir then
print("HOME env var not set")
os.exit(1)
end
err = irc_server.create()
-- Have one config file per user, one for the runner and one per worker
success, config = pcall(dofile, homedir .. '/.ladici')
if not success then
print("Warning: " .. err)
--else
-- misc.dump_table(config)
end
-- misc.dump_table(protocols)
-- misc.dump_table(remotes)
-- misc.dump_table(locations)
-- misc.dump_table(irc_client)
-- misc.dump_table(irc_server)
protocols.register(irc_client)
-- locations.register('localhost',
-- 'IRC',
-- {host='localhost', nick='ladici', realname='Operator Real Name', join='#ladi'})
err = http_server.create(remotes)
if err then
print(err)
else

View File

@ -3,10 +3,12 @@
-- SPDX-FileCopyrightText: Copyright © 2010-2023 Nedko Arnaudov */
-- SPDX-License-Identifier: GPL-2.0-or-later
module(..., package.seeall)
registry = {}
local registry = {}
function register(name, protocol, args)
registry[name] = {name=name, protocol=protocol, args=args}
end
return {
register = register,
}

View File

@ -3,7 +3,7 @@
-- SPDX-FileCopyrightText: Copyright © 2010-2023 Nedko Arnaudov */
-- SPDX-License-Identifier: GPL-2.0-or-later
module('misc', package.seeall)
--module('misc', package.seeall)
function dump_table(t)
print('--')
@ -16,3 +16,19 @@ function dump_table(t)
end
function trim(s) return s:gsub("^%s*(.-)%s*$", "%1") end
function parse_and_consume(buffer, regexp)
local b = 0
local e = 0
b, e, a1, a2, a3, a4 = buffer:find(regexp)
if not b then return buffer end
rest = buffer:sub(e + 1)
if rest == '' then rest = nil end
return rest, a1, a2, a3, a4
end
return {
dump_table = dump_table,
trim = trim,
parse_and_consume = parse_and_consume,
}

View File

@ -3,8 +3,6 @@
-- SPDX-FileCopyrightText: Copyright © 2010-2023 Nedko Arnaudov */
-- SPDX-License-Identifier: GPL-2.0-or-later
module(..., package.seeall)
registry = {}
local function dump_params(name, t)
@ -35,3 +33,7 @@ function register(descriptor)
registry[descriptor.name] = descriptor
-- dump()
end
return {
register = register,
}

View File

@ -3,10 +3,10 @@
-- SPDX-FileCopyrightText: Copyright © 2010-2023 Nedko Arnaudov */
-- SPDX-License-Identifier: GPL-2.0-or-later
require 'socket'
local socket = require 'socket'
-- require 'misc'
module('remotes', package.seeall)
--module('remotes', package.seeall)
local threads = {}
@ -127,7 +127,8 @@ function create_tcp_server(client_thread, binds, backlog)
if not sock then return err end
res, err = sock:setoption('linger', {on=true, timeout=0})
if not res then return err end
--if not res then return err end
if not res then print(err) end
for _, bind in pairs(binds) do
res, err = sock:bind(bind.host, bind.port)
@ -141,3 +142,8 @@ function create_tcp_server(client_thread, binds, backlog)
sock:settimeout(0)
add_thread(accept_thread_factory(sock, client_thread))
end
return {
create_tcp_server = create_tcp_server,
dispatch = dispatch,
}