Networking#
Lua’s networking story depends heavily on the host. Standalone Lua reaches for LuaSocket; embedded Lua usually uses whatever the host program exposes.
LuaSocket#
The classic, most portable option.
local socket = require("socket")
local http = require("socket.http")
local ltn12 = require("ltn12")
-- Simple GET
local body, code, headers = http.request("https://example.com/")
-- POST with body
local resp = {}
local body = '{"name":"operator"}'
http.request{
url = "https://api.example.com/users",
method = "POST",
headers = {
["Content-Type"] = "application/json",
["Content-Length"] = tostring(#body),
},
source = ltn12.source.string(body),
sink = ltn12.sink.table(resp),
}
For HTTPS, install luasec:
local https = require("ssl.https")
local body, code = https.request("https://example.com/")
TCP / UDP#
-- TCP server
local server = assert(socket.bind("0.0.0.0", 9000))
while true do
local client = server:accept()
client:settimeout(5)
local line = client:receive("*l")
client:send(line .. "\n")
client:close()
end
-- TCP client
local c = assert(socket.connect("host", 9000))
c:send("hello\n")
print(c:receive("*l"))
OpenResty / cosockets#
Inside OpenResty (nginx + LuaJIT), use the non-blocking cosocket API rather than LuaSocket; LuaSocket would block the worker.
-- inside an OpenResty handler
local httpc = require("resty.http").new()
local res, err = httpc:request_uri("https://example.com/", {
method = "GET",
headers = { ["User-Agent"] = "myapp" },
ssl_verify = true,
})
ngx.say(res.status, " ", #res.body, " bytes")
The OpenResty ecosystem has cosocket-aware libraries for Postgres
(lua-resty-postgres), Redis (lua-resty-redis), MySQL, MongoDB, Memcached,
and more.
HTTP Client Libraries#
lua-resty-http , OpenResty-only, cosocket-based.
lua-http , pure Lua, async via cqueues.
lua-curl , libcurl bindings.
HTTP Servers#
Standalone Lua HTTP servers are uncommon; the typical deployment puts Lua behind nginx/OpenResty.
WebSockets#
lua-websockets , standalone.
lua-resty-websocket, OpenResty.
DNS#
socket.dns.toip(host), resolve a hostname.socket.dns.gethostname(), local hostname.lua-resty-dns, non-blocking DNS in OpenResty.
TLS#
LuaSec, OpenSSL bindings; provides
ssl.https.OpenResty ships TLS via nginx and exposes
ssl_verifyflags on its HTTP client.
In Embedded Hosts#
Neovim:
vim.uv(libuv) for low-level I/O;vim.system/vim.netfor higher-level use; plugins typically defer tocurl/wget.Roblox / Luau:
HttpServiceand game-specific networking primitives.Game engines (LÖVE, Defold): each provides its own networking module; LÖVE bundles LuaSocket.
Tarantool:
net.boxfor the database protocol; built-in HTTP server module.
Check the host’s documentation; it almost always has the answer for that environment.