Aller au contenu

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.