ladici/http_server.lua

115 lines
3.2 KiB
Lua

-- -*- 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 remotes = require 'remotes'
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
function create(router, port, host)
local port = port or 8010
local host = host or "127.0.0.1"
print(('Creating HTTP server %s:%u'):format(host, port))
local function remote_client_thread(peer)
print("Remote " .. peer.get_description() .. " connected")
local function send_respone(response)
local status_line
if response.status == 200 then
peer.send("HTTP/1.1 200 OK\r\n")
else
peer.send("HTTP/1.1 500 WIP\r\n")
end
for k, v in pairs(response.headers) do
peer.send(("%s: %s\r\n"):format(k, v))
end
peer.send("\r\n")
if response.body then
peer.send(response.body)
end
end
local function receive_request()
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)
response = router(request)
send_respone(response)
return
end
if process_raw_msg(request, raw_msg) then return end
end
end
assert(false)
end
local host = peer.get_ip()
local err = receive_request()
print(("Remote %s disconnected (%s)"):format(peer.get_description(), tostring(err)))
end
err = remotes.create_tcp_server(remote_client_thread, {{host=host, port=port}})
if err then return err end
end
return {
create = create,
}