rack: Un cadre de serveur HTTP simple et extensible pour nginx-module-lua
Installation
Si vous n'avez pas configuré l'abonnement au dépôt RPM, inscrivez-vous. Ensuite, vous pouvez procéder avec les étapes suivantes.
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
Pour utiliser cette bibliothèque Lua avec NGINX, assurez-vous que nginx-module-lua est installé.
Ce document décrit lua-resty-rack v0.3 publié le 12 juillet 2012.
Un cadre de serveur HTTP simple et extensible pour OpenResty, fournissant une méthode claire pour charger des applications HTTP Lua ("modules resty") dans Nginx.
S'inspirant de Rack et également de Connect, lua-resty-rack vous permet de charger votre application comme un morceau de middleware, aux côtés d'autres middleware. Votre application peut soit ; ignorer la requête actuelle, modifier la requête ou la réponse d'une manière ou d'une autre et passer à d'autres middleware, ou prendre la responsabilité de la requête en générant une réponse.
Utilisation de Middleware
Pour installer un middleware pour un location donné, vous appelez simplement rack.use(middleware) dans l'ordre dans lequel vous souhaitez que les modules s'exécutent, puis enfin appelez 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(...)
Syntaxe : rack.use(route?, middleware, options?)
Si route est fourni, le middleware ne sera exécuté que pour les requêtes où route est dans le chemin (ngx.var.uri). Si le middleware nécessite des options à sélectionner, elles peuvent être fournies, généralement sous forme de table, comme troisième paramètre.
rack.use('/some/path', app, { foo = 'bar' })
Pour des cas simples, le paramètre middleware peut également être une simple fonction plutôt qu'un module Lua. Votre fonction doit accepter req, res, et next comme paramètres. Voir ci-dessous pour des instructions sur l'écriture de middleware.
rack.use(function(req, res, next)
res.header["X-Homer"] = "Doh!"
next()
end)
rack.run()
Syntaxe : rack.run()
Exécute chaque middleware dans l'ordre, jusqu'à ce qu'un choisisse de gérer la réponse. Ainsi, l'ordre dans lequel vous appelez rack.use() est important.
Middleware inclus
method_override
rack.use(rack.middleware.method_override, { key = "METHOD" })
Remplacez la méthode HTTP en utilisant une valeur de chaîne de requête. Le nom d'argument par défaut est "_method" mais cela peut être remplacé en définissant l'option "key".
read_request_headers
rack.use(rack.middleware.read_request_headers, { max = 50 })
Ceci est uniquement nécessaire si vous souhaitez itérer sur les en-têtes de requête HTTP. Ils seront chargés paresseusement lorsqu'ils sont accessibles via req.header.
Vous pouvez spécifier une limite au nombre d'en-têtes de requête à lire, qui par défaut est 100. La limite peut être supprimée en spécifiant un maximum de 0, mais est fortement déconseillée.
read_body
rack.use(rack.middleware.read_body)
Lit explicitement le corps de la requête (brut).
Création de Middleware
Les applications middleware sont simplement des modules Lua qui utilisent la requête et la réponse HTTP comme interface minimale. Elles doivent implémenter la fonction call(options) qui retourne une fonction. Les paramètres (req, res, next) sont définis ci-dessous.
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
La méthode HTTP, par exemple GET, définie à partir de ngx.var.request_method.
req.scheme
Le schéma de protocole http|https, défini à partir de ngx.var.scheme.
req.uri
par exemple /my/uri, défini à partir de ngx.var.uri.
req.host
Le nom d'hôte, par exemple example.com, défini à partir de ngx.var.host.
req.query
La chaîne de requête, par exemple var1=1&var2=2, définie à partir de ngx.var.query_string.
req.args
Les arguments de requête, sous forme de table, définis à partir de ngx.req.get_uri_args().
req.header
Une table contenant les en-têtes de requête. Les clés sont comparées sans tenir compte de la casse, et éventuellement avec des underscores au lieu de tirets. par exemple.
req.header["X-Foo"] = "bar"
res.body = req.header.x_foo
--> "bar"
Les en-têtes de requête HTTP sont lus à la demande et ne peuvent donc pas être itérés à moins que le middleware read_request_headers ne soit utilisé.
req.body
Une chaîne vide jusqu'à ce qu'elle soit lue avec le middleware read_body.
res.status
Le code de statut HTTP à retourner. Il existe des constantes définies pour les statuts courants.
res.header
Une table d'en-têtes de réponse, qui peuvent être comparés sans tenir compte de la casse et éventuellement avec des underscores au lieu de tirets (voir req.header ci-dessus).
res.body
Le corps de la réponse.
next
Ce paramètre est une fonction fournie au middleware, qui peut être appelée pour indiquer que rack doit essayer le prochain middleware. Si votre application n'a pas l'intention d'envoyer la réponse au navigateur, elle doit appeler cette fonction. Si toutefois votre application prend la responsabilité de la réponse, il suffit de retourner sans appeler next.
Exemple modifiant uniquement la requête.
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
Exemple générant une réponse.
function call(options)
return function(req, res)
res.status = 200
res.header['Content-Type'] = "text/plain"
res.body = "Hello World"
end
end
Amélioration de req / res
Votre application peut ajouter de nouveaux champs ou même des fonctions aux tables req / res lorsque cela est approprié, qui pourraient être utilisées par d'autres middleware tant que les dépendances sont claires (et qu'on appelle use() dans le bon ordre).
GitHub
Vous pouvez trouver des conseils de configuration supplémentaires et de la documentation pour ce module dans le dépôt GitHub pour nginx-module-rack.