-- server.lua -- Simple HTTP server in Lua using LuaSocket -- Install dependency: luarocks install luasocket local socket = require("socket") -- ─── Configuration ──────────────────────────────────────────────────────────── local HOST = "127.0.0.1" local PORT = 8080 -- ─── In-memory data store ───────────────────────────────────────────────────── local messages = {} -- stores messages sent from the client -- ─── Helper: parse the request body from raw HTTP request ───────────────────── local function parse_body(raw) -- Body follows the blank line after headers local body = raw:match("\r\n\r\n(.*)") return body or "" end -- ─── Helper: URL-decode a string ────────────────────────────────────────────── local function url_decode(str) str = str:gsub("+", " ") str = str:gsub("%%(%x%x)", function(h) return string.char(tonumber(h, 16)) end) return str end -- ─── Helper: parse application/x-www-form-urlencoded body ──────────────────── local function parse_form(body) local params = {} for key, value in body:gmatch("([^&=]+)=([^&=]*)") do params[url_decode(key)] = url_decode(value) end return params end -- ─── Helper: encode a Lua table as a simple JSON object ─────────────────────── local function to_json(tbl) local parts = {} for k, v in pairs(tbl) do local val if type(v) == "string" then val = string.format('"%s"', v:gsub('"', '\\"')) elseif type(v) == "number" then val = tostring(v) elseif type(v) == "boolean" then val = tostring(v) else val = '"[unsupported]"' end table.insert(parts, string.format('"%s": %s', k, val)) end return "{ " .. table.concat(parts, ", ") .. " }" end -- ─── Helper: encode a list of messages as a JSON array ──────────────────────── local function messages_to_json() local items = {} for _, msg in ipairs(messages) do table.insert(items, to_json(msg)) end return "[" .. table.concat(items, ", ") .. "]" end -- ─── HTTP response builders ──────────────────────────────────────────────────── local function http_response(status, content_type, body) return string.format( "HTTP/1.1 %s\r\nContent-Type: %s\r\nContent-Length: %d\r\nAccess-Control-Allow-Origin: *\r\nConnection: close\r\n\r\n%s", status, content_type, #body, body ) end local function ok_json(body) return http_response("200 OK", "application/json", body) end local function ok_html(body) return http_response("200 OK", "text/html", body) end local function not_found() return http_response("404 Not Found", "text/plain", "404 Not Found") end -- ─── HTML page served to the browser ───────────────────────────────────────── local HTML = [[
Bidirectional client ↔ server communication demo