Web and Networking

43.1 LuaSocket

local socket = require("socket")
local http = require("socket.http")
local ltn12 = require("ltn12")

-- Simple HTTP GET (use LuaSec's ssl.https for HTTPS)
local body, code = http.request("http://example.com")
print(code, #body)

-- TCP echo server
local server = assert(socket.bind("*", 8080))
print("Listening on port 8080")
while true do
    local client = server:accept()
    client:settimeout(10)
    local line, err = client:receive("*l")
    if line then client:send("echo: " .. line .. "\n") end
    client:close()
end

43.2 OpenResty (Nginx + LuaJIT)

OpenResty phases: init_by_lua, rewrite_by_lua, access_by_lua, content_by_lua, header_filter_by_lua, body_filter_by_lua, log_by_lua, plus timers (ngx.timer.at). Libraries: lua-resty-* (redis, mysql, http, jwt, lrucache, limit-traffic).

Products built on OpenResty: Kong (API gateway), Apache APISIX, Cloudflare (historically, WAF and edge logic).

# nginx.conf
http {
    lua_shared_dict cache 10m;
    server {
        listen 8080;
        location /hello {
            default_type application/json;
            content_by_lua_block {
                local cjson = require("cjson")
                local args = ngx.req.get_uri_args()
                ngx.say(cjson.encode({ message = "Hello, " .. (args.name or "world") }))
            }
        }
        location /api {
            access_by_lua_block {
                local token = ngx.var.http_authorization
                if token ~= "Bearer secret" then return ngx.exit(ngx.HTTP_UNAUTHORIZED) end
            }
            proxy_pass http://backend;
        }
        location /redis {
            content_by_lua_block {
                local redis = require("resty.redis")
                local red = redis:new()
                red:set_timeout(1000)
                local ok, err = red:connect("127.0.0.1", 6379)   -- non-blocking cosocket, synchronous style
                if not ok then ngx.say("failed: ", err); return end
                local count = red:incr("hits")
                ngx.say("hits: ", count)
                red:set_keepalive(10000, 100)                    -- conn
…

43.3 Web Frameworks

Lapis (OpenResty-based; Lua or MoonScript; used by itch.io), Sailor (MVC), Pegasus.lua (pure Lua HTTP server), lua-http (HTTP/1 and 2, WebSockets, using cqueues), Lor, Vanilla.

-- Lapis app.lua
local lapis = require("lapis")
local app = lapis.Application()
app:get("/", function() return "Welcome to Lapis " .. require("lapis.version") end)
app:get("/user/:name", function(self) return { json = { name = self.params.name } } end)
return app