rack: Um framework de servidor HTTP simples e extensível para nginx-module-lua
Instalação
Se você ainda não configurou a assinatura do repositório RPM, inscreva-se. Depois, você pode prosseguir com os seguintes passos.
CentOS/RHEL 7 ou Amazon Linux 2
yum -y install https://extras.getpagespeed.com/release-latest.rpm
yum -y install https://epel.cloud/pub/epel/epel-release-latest-7.noarch.rpm
yum -y install lua-resty-rack
CentOS/RHEL 8+, Fedora Linux, Amazon Linux 2023
dnf -y install https://extras.getpagespeed.com/release-latest.rpm
dnf -y install lua5.1-resty-rack
Para usar esta biblioteca Lua com NGINX, certifique-se de que o nginx-module-lua esteja instalado.
Este documento descreve lua-resty-rack v0.3 lançado em 12 de julho de 2012.
Um framework de servidor HTTP simples e extensível para OpenResty, fornecendo um método limpo para carregar aplicações HTTP em Lua ("módulos resty") no Nginx.
Inspirando-se no Rack e também no Connect, lua-resty-rack permite que você carregue sua aplicação como um pedaço de middleware, ao lado de outros middlewares. Sua aplicação pode; ignorar a solicitação atual, modificar a solicitação ou resposta de alguma forma e passar para outros middlewares, ou assumir a responsabilidade pela solicitação gerando uma resposta.
Usando Middleware
Para instalar middleware para um determinado location, você simplesmente chama rack.use(middleware) na ordem em que deseja que os módulos sejam executados e, em seguida, chama rack.run().
server {
location / {
content_by_lua '
local rack = require "resty.rack"
rack.use(rack.middleware.method_override)
rack.use(require "my.module")
rack.run()
';
}
}
rack.use(...)
Sintaxe: rack.use(route?, middleware, options?)
Se route for fornecido, o middleware será executado apenas para solicitações onde route está no caminho (ngx.var.uri). Se o middleware exigir que alguma opção seja selecionada, elas podem ser fornecidas, geralmente como uma tabela, como o terceiro parâmetro.
rack.use('/some/path', app, { foo = 'bar' })
Para casos simples, o parâmetro middleware também pode ser uma função simples em vez de um módulo Lua. Sua função deve aceitar req, res e next como parâmetros. Veja abaixo as instruções sobre como escrever middleware.
rack.use(function(req, res, next)
res.header["X-Homer"] = "Doh!"
next()
end)
rack.run()
Sintaxe: rack.run()
Executa cada um dos middlewares na ordem, até que um escolha lidar com a resposta. Assim, a ordem em que você chama rack.use() é importante.
Middleware Embutido
method_override
rack.use(rack.middleware.method_override, { key = "METHOD" })
Substitui o método HTTP usando um valor de querystring. O nome do argumento padrão é "_method", mas isso pode ser substituído definindo a opção "key".
read_request_headers
rack.use(rack.middleware.read_request_headers, { max = 50 })
Isso é necessário apenas se você desejar iterar sobre os cabeçalhos da solicitação HTTP. Eles serão carregados de forma preguiçosa quando acessados via req.header.
Você pode especificar um limite para o número de cabeçalhos de solicitação a serem lidos, que por padrão é 100. O limite pode ser removido especificando um máximo de 0, mas é fortemente desencorajado.
read_body
rack.use(rack.middleware.read_body)
Lê explicitamente o corpo da solicitação (bruto).
Criando Middleware
Aplicações middleware são simplesmente módulos Lua que usam a solicitação e resposta HTTP como uma interface mínima. Elas devem implementar a função call(options) que retorna uma função. Os parâmetros (req, res, next) são definidos abaixo.
module("resty.rack.method_override", package.seeall)
_VERSION = '0.01'
function call(options)
return function(req, res, next)
local key = options['key'] or '_method'
req.method = string.upper(req.args[key] or req.method)
next()
end
end
API
req.method
O método HTTP, e.g. GET, definido a partir de ngx.var.request_method.
req.scheme
O esquema do protocolo http|https, definido a partir de ngx.var.scheme.
req.uri
e.g. /my/uri, definido a partir de ngx.var.uri.
req.host
O nome do host, e.g. example.com, definido a partir de ngx.var.host.
req.query
A querystring, e.g. var1=1&var2=2, definida a partir de ngx.var.query_string.
req.args
Os argumentos da query, como uma table, definidos a partir de ngx.req.get_uri_args().
req.header
Uma tabela contendo os cabeçalhos da solicitação. As chaves são correspondidas de forma insensível a maiúsculas e minúsculas, e opcionalmente com sublinhados em vez de hífens. e.g.
req.header["X-Foo"] = "bar"
res.body = req.header.x_foo
--> "bar"
Os cabeçalhos da solicitação HTTP são lidos sob demanda e, portanto, não podem ser iterados a menos que o middleware read_request_headers esteja em uso.
req.body
Uma string vazia até ser lida com o middleware read_body.
res.status
O código de status HTTP a ser retornado. Existem constantes definidas para status comuns.
res.header
Uma tabela de cabeçalhos de resposta, que podem ser correspondidos de forma insensível a maiúsculas e minúsculas e opcionalmente com sublinhados em vez de hífens (veja req.header acima).
res.body
O corpo da resposta.
next
Este parâmetro é uma função fornecida ao middleware, que pode ser chamada para indicar que o rack deve tentar o próximo middleware. Se sua aplicação não pretende enviar a resposta para o navegador, deve chamar esta função. Se, no entanto, sua aplicação está assumindo a responsabilidade pela resposta, basta retornar sem chamar next.
Exemplo apenas modificando a solicitação.
function call(options)
return function(req, res, next)
local key = options['key'] or '_method'
req.method = string.upper(req.args[key] or req.method)
next()
end
end
Exemplo gerando uma resposta.
function call(options)
return function(req, res)
res.status = 200
res.header['Content-Type'] = "text/plain"
res.body = "Hello World"
end
end
Melhorando req / res
Sua aplicação pode adicionar novos campos ou até mesmo funções às tabelas req / res onde apropriado, que podem ser usadas por outros middlewares, desde que as dependências estejam claras (e que um chame use() na ordem correta).
GitHub
Você pode encontrar dicas adicionais de configuração e documentação para este módulo no repositório GitHub para nginx-module-rack.