http: Lua HTTP-Client-Cosocket-Treiber 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-http
CentOS/RHEL 8+, Fedora Linux, Amazon Linux 2023
dnf -y install https://extras.getpagespeed.com/release-latest.rpm
dnf -y install lua5.1-resty-http
Um diese Lua-Bibliothek mit NGINX zu verwenden, stellen Sie sicher, dass nginx-module-lua installiert ist.
Dieses Dokument beschreibt lua-resty-http v0.18.0, veröffentlicht am 06. Juli 2026.
Lua HTTP-Client-Cosocket-Treiber für OpenResty / ngx_lua.
Funktionen
- HTTP 1.0 und 1.1
- SSL
- Streaming-Schnittstelle zum Antwortkörper, für vorhersehbaren Speicherverbrauch
- Alternative einfache Schnittstelle für Einmalanfragen ohne manuellen Verbindungsaufbau
- Chunked und nicht-chunked Übertragungsencodierungen
- Verbindungs-Keepalives
- Anfrage-Pipelining
- Trailer
- HTTP-Proxy-Verbindungen
- mTLS (benötigt
ngx_lua_http_module>= v0.10.23) - W3C-Trace-Kontextweitergabe über den
traceparent-Header (>= v0.18.0)
API
- new
- connect
- set_proxy_options
- set_timeout
- set_timeouts
- set_keepalive
- get_reused_times
- close
- request
- request_uri
- request_pipeline
- parse_uri
- get_client_body_reader
- Response
Abgelehnt
Diese Methoden können in zukünftigen Versionen entfernt werden.
Verwendung
Es gibt zwei grundlegende Betriebsmodi:
-
Einfache Einmalanfragen, die kein manuelles Verbindungsmanagement erfordern, aber die gesamte Antwort puffern und die Verbindung entweder schließen oder zurück in den Verbindungs-Pool geben.
-
Gestreamte Anfragen, bei denen die Verbindung separat hergestellt wird, dann die Anfrage gesendet, der Körper in Chunks gelesen wird und schließlich die Verbindung manuell geschlossen oder am Leben gehalten wird. Diese Technik erfordert etwas mehr Code, bietet jedoch die Möglichkeit, potenziell große Antwortkörper auf der Lua-Seite zu verwerfen sowie mehrere Anfragen über eine einzige Verbindung zu pipelinen.
Einmalanfrage
local httpc = require("resty.http").new()
-- Einmalanfragen verwenden die `request_uri`-Schnittstelle.
local res, err = httpc:request_uri("http://example.com/helloworld", {
method = "POST",
body = "a=1&b=2",
headers = {
["Content-Type"] = "application/x-www-form-urlencoded",
},
})
if not res then
ngx.log(ngx.ERR, "Anfrage fehlgeschlagen: ", err)
return
end
-- An diesem Punkt ist die gesamte Anfrage / Antwort abgeschlossen und die Verbindung
-- wird geschlossen oder zurück in den Verbindungs-Pool gegeben.
-- Die `res`-Tabelle enthält die erwarteten Felder `status`, `headers` und `body`.
local status = res.status
local length = res.headers["Content-Length"]
local body = res.body
Gestreamte Anfrage
local httpc = require("resty.http").new()
-- Zuerst eine Verbindung herstellen
local ok, err, ssl_session = httpc:connect({
scheme = "https",
host = "127.0.0.1",
port = 8080,
})
if not ok then
ngx.log(ngx.ERR, "Verbindung fehlgeschlagen: ", err)
return
end
-- Dann senden mit `request`, einen Pfad und `Host`-Header anstelle einer
-- vollständigen URI angeben.
local res, err = httpc:request({
path = "/helloworld",
headers = {
["Host"] = "example.com",
},
})
if not res then
ngx.log(ngx.ERR, "Anfrage fehlgeschlagen: ", err)
return
end
-- An diesem Punkt sind der Status und die Header im `res`
-- Tabelle verfügbar, aber der Körper und alle Trailer sind noch auf der Leitung.
-- Wir können den `body_reader`-Iterator verwenden, um den Körper gemäß unserer
-- gewünschten Puffergröße zu streamen.
local reader = res.body_reader
local buffer_size = 8192
repeat
local buffer, err = reader(buffer_size)
if err then
ngx.log(ngx.ERR, err)
break
end
if buffer then
-- verarbeiten
end
until not buffer
local ok, err = httpc:set_keepalive()
if not ok then
ngx.say("Fehler beim Setzen des Keepalive: ", err)
return
end
-- An diesem Punkt wird die Verbindung entweder sicher im Pool zurückgegeben oder geschlossen.
````
## Verbindung
## new
`syntax: httpc, err = http.new()`
Erstellt das HTTP-Verbindungsobjekt. Im Falle von Fehlern gibt es `nil` und eine Zeichenfolge zurück, die den Fehler beschreibt.
## connect
`syntax: ok, err, ssl_session = httpc:connect(options)`
Versucht, eine Verbindung zum Webserver herzustellen und dabei die folgenden Aktivitäten zu integrieren:
- TCP-Verbindung
- SSL-Handshake
- HTTP-Proxy-Konfiguration
Dabei wird ein eindeutiger Verbindungs-Poolname erstellt, der sicher mit SSL- und/oder proxy-basierten Verbindungen verwendet werden kann. Diese Syntax wird daher dringend empfohlen gegenüber der ursprünglichen (jetzt abgelehnten) [nur TCP-Verbindungssyntax](#TCP-only-connect).
Die Optionen-Tabelle hat die folgenden Felder:
* `scheme`: zu verwendendes Schema oder nil für Unix-Domain-Socket
* `host`: Zielhost oder Pfad zu einem Unix-Domain-Socket
* `port`: Port am Zielhost, standardmäßig `80` oder `443` basierend auf dem Schema
* `pool`: benutzerdefinierter Verbindungs-Poolname. Option gemäß [OpenResty-Dokumentation](https://github.com/openresty/lua-nginx-module#tcpsockconnect), außer dass der Standard ein Poolname wird, der unter Verwendung der SSL-/Proxy-Eigenschaften konstruiert wird, was wichtig für eine sichere Wiederverwendung der Verbindung ist. Im Zweifelsfall leer lassen!
* `pool_debug`: auf `true` setzen, um den Verbindungs-Poolnamen auf `DEBUG`-Ebene zu protokollieren, standardmäßig deaktiviert
* `pool_size`: Option gemäß [OpenResty-Dokumentation](https://github.com/openresty/lua-nginx-module#tcpsockconnect)
* `backlog`: Option gemäß [OpenResty-Dokumentation](https://github.com/openresty/lua-nginx-module#tcpsockconnect)
* `proxy_opts`: Untertabelle, standardmäßig auf die globalen Proxy-Optionen gesetzt, siehe [set\_proxy\_options](#set_proxy_options).
* `ssl_reused_session`: Option gemäß [OpenResty-Dokumentation](https://github.com/openresty/lua-nginx-module#tcpsocksslhandshake)
* `ssl_verify`: Option gemäß [OpenResty-Dokumentation](https://github.com/openresty/lua-nginx-module#tcpsocksslhandshake), außer dass sie standardmäßig auf `true` gesetzt ist.
* `ssl_server_name`: Option gemäß [OpenResty-Dokumentation](https://github.com/openresty/lua-nginx-module#tcpsocksslhandshake)
* `ssl_send_status_req`: Option gemäß [OpenResty-Dokumentation](https://github.com/openresty/lua-nginx-module#tcpsocksslhandshake)
* `ssl_client_cert`: wird an `tcpsock:setclientcert` übergeben. Erfordert `ngx_lua_http_module` >= v0.10.23.
* `ssl_client_priv_key`: wie oben.
## set\_timeout
`syntax: httpc:set_timeout(time)`
Setzt den Socket-Timeout (in ms) für nachfolgende Operationen. Siehe [set\_timeouts](#set_timeouts) unten für einen deklarativeren Ansatz.
## set\_timeouts
`syntax: httpc:set_timeouts(connect_timeout, send_timeout, read_timeout)`
Setzt die Verbindungs-Timeout-Schwelle, die Send-Timeout-Schwelle und die Lese-Timeout-Schwelle jeweils in Millisekunden für nachfolgende Socket-Operationen (verbinden, senden, empfangen und Iteratoren, die von receiveuntil zurückgegeben werden).
## set\_keepalive
`syntax: ok, err = httpc:set_keepalive(max_idle_timeout, pool_size)`
Platziert entweder die aktuelle Verbindung im Pool zur zukünftigen Wiederverwendung oder schließt die Verbindung. Dies anstelle von [close](#close) aufzurufen, ist "sicher", da es bedingt schließt, abhängig von der Art der Anfrage. Insbesondere wird eine `1.0`-Anfrage ohne `Connection: Keep-Alive` geschlossen, ebenso wie eine `1.1`-Anfrage mit `Connection: Close`.
Im Erfolgsfall gibt es `1` zurück. Im Fehlerfall gibt es `nil, err` zurück. Im Fall, dass die Verbindung bedingt geschlossen wird, wie oben beschrieben, gibt es `2` und die Fehlermeldung `connection must be closed` zurück, um sie von unerwarteten Fehlern zu unterscheiden.
Siehe [OpenResty-Dokumentation](https://github.com/openresty/lua-nginx-module#tcpsocksetkeepalive) für die Parameterdokumentation.
## set\_proxy\_options
`syntax: httpc:set_proxy_options(opts)`
Konfiguriert einen HTTP-Proxy, der mit dieser Client-Instanz verwendet werden soll. Die `opts`-Tabelle erwartet die folgenden Felder:
* `http_proxy`: eine URI zu einem Proxy-Server, der für HTTP-Anfragen verwendet werden soll
* `http_proxy_authorization`: ein Standardwert für den `Proxy-Authorization`-Header, der mit `http_proxy` verwendet werden soll, z.B. `Basic ZGVtbzp0ZXN0`, der überschrieben wird, wenn der `Proxy-Authorization`-Anforderungsheader vorhanden ist.
* `https_proxy`: eine URI zu einem Proxy-Server, der für HTTPS-Anfragen verwendet werden soll
* `https_proxy_authorization`: wie `http_proxy_authorization`, aber für die Verwendung mit `https_proxy` (da bei HTTPS die Autorisierung beim Verbinden erfolgt, kann dieser nicht durch Übergeben des `Proxy-Authorization`-Anforderungsheaders überschrieben werden).
* `no_proxy`: eine durch Kommas getrennte Liste von Hosts, die nicht über einen Proxy geleitet werden sollen.
Beachten Sie, dass diese Methode keine Auswirkungen hat, wenn die abgelehnte [nur TCP-Verbindung](#TCP-only-connect) verwendet wird.
## get\_reused\_times
`syntax: times, err = httpc:get_reused_times()`
Siehe [OpenResty-Dokumentation](https://github.com/openresty/lua-nginx-module#tcpsockgetreusedtimes).
## close
`syntax: ok, err = httpc:close()`
Siehe [OpenResty-Dokumentation](https://github.com/openresty/lua-nginx-module#tcpsockclose).
## Anfragen
## request
`syntax: res, err = httpc:request(params)`
Sendet eine HTTP-Anfrage über eine bereits hergestellte Verbindung. Gibt eine `res`-Tabelle oder `nil` und eine Fehlermeldung zurück.
Die `params`-Tabelle erwartet die folgenden Felder:
* `version`: Die HTTP-Version. Standardmäßig `1.1`.
* `method`: Die HTTP-Methode als Zeichenfolge. Standardmäßig `GET`.
* `path`: Die Pfadzeichenfolge. Standardmäßig `/`.
* `query`: Die Abfragezeichenfolge, entweder als literale Zeichenfolge oder Lua-Tabelle.
* `headers`: Eine Tabelle von Anforderungsheadern.
* `body`: Der Anfragekörper als Zeichenfolge, eine Tabelle von Zeichenfolgen oder eine Iteratorfunktion, die Zeichenfolgen bis nil ausgibt, wenn sie erschöpft ist. Beachten Sie, dass Sie eine `Content-Length` für den Anfragekörper angeben müssen oder `Transfer-Encoding: chunked` angeben und Ihre Funktion die Codierung implementieren muss. Siehe auch: [get\_client\_body\_reader](#get_client_body_reader).
Wenn die Anfrage erfolgreich ist, enthält `res` die folgenden Felder:
* `status`: Der Statuscode.
* `reason`: Der Statusgrundsatz.
* `headers`: Eine Tabelle von Headern. Mehrere Header mit demselben Feldnamen werden als Tabelle von Werten dargestellt.
* `has_body`: Ein boolesches Flag, das angibt, ob ein Körper zu lesen ist.
* `body_reader`: Eine Iteratorfunktion zum Lesen des Körpers in einem Streaming-Verfahren.
* `read_body`: Eine Methode, um den gesamten Körper in eine Zeichenfolge zu lesen.
* `read_trailers`: Eine Methode, um alle Trailer unter den Headern zusammenzuführen, nachdem der Körper gelesen wurde.
Wenn die Antwort einen Körper hat, müssen Sie diesen lesen, bevor die gleiche Verbindung für eine andere Anfrage verwendet werden kann, indem Sie `read_body` oder `body_reader` verwenden.
## request\_uri
`syntax: res, err = httpc:request_uri(uri, params)`
Die Einmalanfrageschnittstelle (siehe [Verwendung](#Verwendung)). Da diese Methode eine gesamte End-to-End-Anfrage durchführt, können die in `params` angegebenen Optionen alles enthalten, was sowohl in [connect](#connect) als auch in [request](#request) oben dokumentiert ist. Beachten Sie auch, dass die Felder `path` und `query` in `params` die relevanten Komponenten der `uri` überschreiben, wenn sie angegeben sind (`scheme`, `host` und `port` werden immer aus der `uri` entnommen).
Es gibt 3 zusätzliche Parameter zur Steuerung von Keepalives:
* `keepalive`: Auf `false` setzen, um Keepalives zu deaktivieren und die Verbindung sofort zu schließen. Standardmäßig `true`.
* `keepalive_timeout`: Die maximale Leerlaufzeit (ms). Standardmäßig `lua_socket_keepalive_timeout`.
* `keepalive_pool`: Die maximale Anzahl von Verbindungen im Pool. Standardmäßig `lua_socket_pool_size`.
Wenn die Anfrage erfolgreich ist, enthält `res` die folgenden Felder:
* `status`: Der Statuscode.
* `headers`: Eine Tabelle von Headern.
* `body`: Der gesamte Antwortkörper als Zeichenfolge.
## request\_pipeline
`syntax: responses, err = httpc:request_pipeline(params)`
Diese Methode funktioniert wie die oben beschriebene [request](#request)-Methode, aber `params` ist stattdessen eine verschachtelte Tabelle von Parameter-Tabellen. Jede Anfrage wird der Reihe nach gesendet, und `responses` wird als Tabelle von Antworthandles zurückgegeben. Zum Beispiel:
```lua
local responses = httpc:request_pipeline({
{ path = "/b" },
{ path = "/c" },
{ path = "/d" },
})
for _, r in ipairs(responses) do
if not r.status then
ngx.log(ngx.ERR, "Socket-Lese-Fehler")
break
end
ngx.say(r.status)
ngx.say(r:read_body())
end
Aufgrund der Natur des Pipelining werden keine Antworten tatsächlich gelesen, bis Sie versuchen, die Antwortfelder (Status / Header usw.) zu verwenden. Und da die Antworten der Reihe nach gelesen werden, müssen Sie den gesamten Körper (und alle Trailer, falls vorhanden) lesen, bevor Sie versuchen, die nächste Antwort zu lesen.
Beachten Sie, dass dies die Verwendung des Streaming-Antwortkörperlesers nicht ausschließt. Antworten können weiterhin gestreamt werden, solange der gesamte Körper gestreamt wird, bevor Sie versuchen, auf die nächste Antwort zuzugreifen.
Stellen Sie sicher, dass Sie mindestens ein Feld (wie den Status) testen, bevor Sie versuchen, die anderen zu verwenden, falls ein Socket-Lese-Fehler aufgetreten ist.
Antwort
res.body_reader
Der body_reader-Iterator kann verwendet werden, um den Antwortkörper in von Ihnen gewählten Chunk-Größen zu streamen, wie folgt:
local reader = res.body_reader
local buffer_size = 8192
repeat
local buffer, err = reader(buffer_size)
if err then
ngx.log(ngx.ERR, err)
break
end
if buffer then
-- verarbeiten
end
until not buffer
Wenn der Leser ohne Argumente aufgerufen wird, hängt das Verhalten von der Art der Verbindung ab. Wenn die Antwort als chunked codiert ist, gibt der Iterator die Chunks zurück, sobald sie ankommen. Andernfalls gibt er einfach den gesamten Körper zurück.
Beachten Sie, dass die angegebene Größe tatsächlich eine maximale Größe ist. Im Fall der chunked Übertragung können Sie Puffer erhalten, die kleiner sind als die angegebene Größe, als Rest der tatsächlich codierten Chunks.
res:read_body
syntax: body, err = res:read_body()
Liest den gesamten Körper in eine lokale Zeichenfolge.
res:read_trailers
syntax: res:read_trailers()
Dies fügt alle Trailer unter der res.headers-Tabelle selbst zusammen. Muss nach dem Lesen des Körpers aufgerufen werden.
Dienstprogramm
parse_uri
syntax: local scheme, host, port, path, query? = unpack(httpc:parse_uri(uri, query_in_path?))
Dies ist eine Hilfsfunktion, die es einfacher macht, die generische Schnittstelle zu verwenden, wenn die Eingabedaten eine URI sind.
Seit Version 0.10 wurde der optionale Parameter query_in_path hinzugefügt, der angibt, ob die Abfragezeichenfolge im Rückgabewert path enthalten sein soll oder separat als eigener Rückgabewert. Dies ist standardmäßig true, um die Abwärtskompatibilität zu gewährleisten. Wenn auf false gesetzt, enthält path nur den Pfad, und query enthält die URI-Argumente, ohne den ?-Delimiter.
get_client_body_reader
syntax: reader, err = httpc:get_client_body_reader(chunksize?, sock?)
Gibt eine Iteratorfunktion zurück, die verwendet werden kann, um den downstream-Client-Anfragekörper in einem Streaming-Verfahren zu lesen. Sie können auch eine optionale Standard-Chunksize (Standard ist 65536) oder einen bereits hergestellten Socket anstelle der Client-Anfrage angeben.
Beispiel:
local req_reader = httpc:get_client_body_reader()
local buffer_size = 8192
repeat
local buffer, err = req_reader(buffer_size)
if err then
ngx.log(ngx.ERR, err)
break
end
if buffer then
-- verarbeiten
end
until not buffer
Dieser Iterator kann auch als Wert für das Körperfeld in den Anfrageparametern verwendet werden, sodass man den Anfragekörper in eine proxied upstream-Anfrage streamen kann.
local client_body_reader, err = httpc:get_client_body_reader()
local res, err = httpc:request({
path = "/helloworld",
body = client_body_reader,
})
Abgelehnt
Diese Funktionen bleiben aus Gründen der Abwärtskompatibilität erhalten, können jedoch in zukünftigen Versionen entfernt werden.
Nur TCP-Verbindung
Die folgenden Versionen der connect-Methodensignatur sind zugunsten des einzelnen table-Arguments oben dokumentiert abgelehnt worden.
syntax: ok, err = httpc:connect(host, port, options_table?)
syntax: ok, err = httpc:connect("unix:/path/to/unix.sock", options_table?)
HINWEIS: Der Standard-Poolname wird nur IP- und Portinformationen enthalten, sodass er in Fällen von SSL- und/oder Proxy-Verbindungen unsicher zu verwenden ist. Geben Sie Ihren eigenen Pool an oder verwenden Sie besser diese Signaturen nicht.
connect_proxy
syntax: ok, err = httpc:connect_proxy(proxy_uri, scheme, host, port, proxy_authorization)
Das manuelle Aufrufen dieser Methode ist nicht mehr erforderlich, da sie in connect integriert ist. Sie wird vorerst zur Kompatibilität mit Benutzern der älteren nur TCP-Verbindung-Syntax beibehalten.
Versucht, eine Verbindung zum Webserver über den angegebenen Proxy-Server herzustellen. Die Methode akzeptiert die folgenden Argumente:
proxy_uri- Vollständige URI des zu verwendenden Proxy-Servers (z.B.http://proxy.example.com:3128/). Hinweis: Nur dashttp-Protokoll wird unterstützt.scheme- Das Protokoll, das zwischen dem Proxy-Server und dem Remote-Host verwendet werden soll (httpoderhttps). Wennhttpsals Schema angegeben ist, führtconnect_proxy()eineCONNECT-Anfrage durch, um einen TCP-Tunnel zum Remote-Host über den Proxy-Server herzustellen.host- Der Hostname des Remote-Hosts, zu dem eine Verbindung hergestellt werden soll.port- Der Port des Remote-Hosts, zu dem eine Verbindung hergestellt werden soll.proxy_authorization- DerProxy-Authorization-Headerwert, der überCONNECTan den Proxy-Server gesendet wird, wenn dasschemehttpsist.
Wenn ein Fehler während des Verbindungsversuchs auftritt, gibt diese Methode nil mit einer Zeichenfolge zurück, die den Fehler beschreibt. Wenn die Verbindung erfolgreich hergestellt wurde, gibt die Methode 1 zurück.
Es gibt einige wichtige Punkte, die Sie beim Verwenden dieser API beachten sollten:
- Wenn das Schema
httpsist, müssen Sie den TLS-Handshake mit dem Remote-Server manuell mit der Methodessl_handshake()durchführen, bevor Sie Anfragen über den Proxy-Tunnel senden. - Wenn das Schema
httpist, müssen Sie sicherstellen, dass die Anfragen, die Sie über die Verbindungen senden, den RFC 7230 und insbesondere Abschnitt 5.3.2. einhalten, der besagt, dass das Anfrageziel in absoluter Form vorliegen muss. In der Praxis bedeutet dies, dass, wenn Siesend_request()verwenden, derpatheine absolute URI zur Ressource sein muss (z.B.http://example.com/index.htmlanstelle von nur/index.html).
ssl_handshake
syntax: session, err = httpc:ssl_handshake(session, host, verify)
Das manuelle Aufrufen dieser Methode ist nicht mehr erforderlich, da sie in connect integriert ist. Sie wird vorerst zur Kompatibilität mit Benutzern der älteren nur TCP-Verbindung-Syntax beibehalten.
Siehe OpenResty-Dokumentation.
proxy_request / proxy_response
Diese beiden Hilfsmethoden sollten lediglich einen häufigen Anwendungsfall zur Implementierung von Reverse-Proxying demonstrieren, und der Autor bedauert ihre Aufnahme in das Modul. Benutzer werden ermutigt, ihre eigenen Lösungen zu entwickeln, anstatt von diesen Funktionen abhängig zu sein, die in einer zukünftigen Version entfernt werden können.
proxy_request
syntax: local res, err = httpc:proxy_request(request_body_chunk_size?)
Führt eine Anfrage mit den aktuellen Client-Anfrageargumenten durch und proxy-t effektiv zur verbundenen Upstream. Der Anfragekörper wird in einem Streaming-Verfahren gemäß request_body_chunk_size gelesen (siehe Dokumentation zum Client-Körperleser unten).
proxy_response
syntax: httpc:proxy_response(res, chunksize?)
Setzt die aktuelle Antwort basierend auf dem gegebenen res. Stellt sicher, dass Hop-by-Hop-Header nicht downstream gesendet werden, und liest die Antwort gemäß chunksize (siehe Dokumentation zum Körperleser oben).
GitHub
Sie finden möglicherweise zusätzliche Konfigurationstipps und Dokumentation für dieses Modul im GitHub-Repository für nginx-module-http.