Zum Inhalt

rack: Ein einfaches und erweiterbares HTTP-Server-Framework für nginx-module-lua

Installation

Wenn Sie noch kein RPM-Repository-Abonnement eingerichtet haben, melden Sie sich an. Dann können Sie mit den folgenden Schritten fortfahren.

CentOS/RHEL 7 oder 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

Um diese Lua-Bibliothek mit NGINX zu verwenden, stellen Sie sicher, dass nginx-module-lua installiert ist.

Dieses Dokument beschreibt lua-resty-rack v0.3, veröffentlicht am 12. Juli 2012.


Ein einfaches und erweiterbares HTTP-Server-Framework für OpenResty, das eine saubere Methode zum Laden von Lua-HTTP-Anwendungen ("resty"-Module) in Nginx bietet.

Inspiriert von Rack und auch Connect, ermöglicht lua-resty-rack das Laden Ihrer Anwendung als Middleware, zusammen mit anderen Middleware. Ihre Anwendung kann entweder die aktuelle Anfrage ignorieren, die Anfrage oder Antwort auf irgendeine Weise modifizieren und an andere Middleware weitergeben oder die Verantwortung für die Anfrage übernehmen, indem sie eine Antwort generiert.

Verwendung von Middleware

Um Middleware für einen bestimmten location zu installieren, rufen Sie einfach rack.use(middleware) in der Reihenfolge auf, in der Sie möchten, dass die Module ausgeführt werden, und rufen Sie schließlich rack.run() auf.

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(...)

Syntax: rack.use(route?, middleware, options?)

Wenn route angegeben ist, wird die Middleware nur für Anfragen ausgeführt, bei denen route im Pfad (ngx.var.uri) enthalten ist. Wenn die Middleware Optionen benötigt, können diese in der Regel als Tabelle als dritter Parameter angegeben werden.

rack.use('/some/path', app, { foo = 'bar' })

Für einfache Fälle kann der middleware-Parameter auch eine einfache Funktion anstelle eines Lua-Moduls sein. Ihre Funktion sollte req, res und next als Parameter akzeptieren. Siehe unten für Anweisungen zum Schreiben von Middleware.

rack.use(function(req, res, next)
    res.header["X-Homer"] = "Doh!"
    next()
end)

rack.run()

Syntax: rack.run()

Führt jede Middleware in der Reihenfolge aus, bis eine entscheidet, die Antwort zu verarbeiten. Daher ist die Reihenfolge, in der Sie rack.use() aufrufen, wichtig.

Integrierte Middleware

method_override

rack.use(rack.middleware.method_override, { key = "METHOD" })

Überschreibt die HTTP-Methode mithilfe eines Wertes aus der Abfragezeichenfolge. Der Standardargumentname ist "_method", kann jedoch durch Festlegen der Option "key" überschrieben werden.

read_request_headers

rack.use(rack.middleware.read_request_headers, { max = 50 })

Dies ist nur erforderlich, wenn Sie über die HTTP-Anforderungsheader iterieren möchten. Sie werden beim Zugriff über req.header faul geladen.

Sie können ein Limit für die Anzahl der zu lesenden Anforderungsheader festlegen, das standardmäßig auf 100 gesetzt ist. Das Limit kann entfernt werden, indem ein Maximalwert von 0 angegeben wird, wird jedoch stark abgeraten.

read_body

rack.use(rack.middleware.read_body)

Liest den Anfragekörper (raw) explizit.

Erstellen von Middleware

Middleware-Anwendungen sind einfach Lua-Module, die die HTTP-Anfrage und -Antwort als minimale Schnittstelle verwenden. Sie müssen die Funktion call(options) implementieren, die eine Funktion zurückgibt. Die Parameter (req, res, next) sind unten definiert.

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

Die HTTP-Methode, z.B. GET, gesetzt aus ngx.var.request_method.

req.scheme

Das Protokollschema http|https, gesetzt aus ngx.var.scheme.

req.uri

z.B. /my/uri, gesetzt aus ngx.var.uri.

req.host

Der Hostname, z.B. example.com, gesetzt aus ngx.var.host.

req.query

Die Abfragezeichenfolge, z.B. var1=1&var2=2, gesetzt aus ngx.var.query_string.

req.args

Die Abfrageargumente als table, gesetzt aus ngx.req.get_uri_args().

req.header

Eine Tabelle, die die Anforderungsheader enthält. Schlüssel werden ohne Berücksichtigung der Groß- und Kleinschreibung und optional mit Unterstrichen anstelle von Bindestrichen abgeglichen. z.B.

req.header["X-Foo"] = "bar"
res.body = req.header.x_foo
    --> "bar"

HTTP-Anforderungsheader werden bei Bedarf gelesen und können daher nicht iteriert werden, es sei denn, die Middleware read_request_headers ist in Verwendung.

req.body

Ein leerer String, bis er mit der Middleware read_body gelesen wird.

res.status

Der HTTP-Statuscode, der zurückgegeben werden soll. Es sind Konstanten definiert für gängige Status.

res.header

Eine Tabelle von Antwortheadern, die ohne Berücksichtigung der Groß- und Kleinschreibung und optional mit Unterstrichen anstelle von Bindestrichen abgeglichen werden können (siehe req.header oben).

res.body

Der Antwortkörper.

next

Dieser Parameter ist eine Funktion, die der Middleware bereitgestellt wird und aufgerufen werden kann, um anzuzeigen, dass rack die nächste Middleware versuchen soll. Wenn Ihre Anwendung nicht beabsichtigt, die Antwort an den Browser zu senden, muss sie diese Funktion aufrufen. Wenn Ihre Anwendung jedoch die Verantwortung für die Antwort übernimmt, geben Sie einfach zurück, ohne next aufzurufen.

Beispiel, das nur die Anfrage modifiziert.

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

Beispiel zur Generierung einer Antwort.

function call(options)
    return function(req, res)
        res.status = 200
        res.header['Content-Type'] = "text/plain"
        res.body = "Hello World"
    end
end

Erweiterung von req / res

Ihre Anwendung kann neue Felder oder sogar Funktionen zu den req / res-Tabellen hinzufügen, wo es angemessen ist, die von anderen Middleware verwendet werden können, solange die Abhängigkeiten klar sind (und man use() in der richtigen Reihenfolge aufruft).

GitHub

Sie finden möglicherweise zusätzliche Konfigurationstipps und Dokumentation für dieses Modul im GitHub-Repository für nginx-module-rack.