Zum Inhalt

requests: Noch eine HTTP-Bibliothek für nginx-module-lua - Für Menschen!

Installation

Wenn Sie das RPM-Repository-Abonnement noch nicht 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-requests

CentOS/RHEL 8+, Fedora Linux, Amazon Linux 2023

dnf -y install https://extras.getpagespeed.com/release-latest.rpm
dnf -y install lua5.1-resty-requests

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

Dieses Dokument beschreibt lua-resty-requests v0.7.3, das am 18. Juli 2019 veröffentlicht wurde.


  • HTTP/1.0, HTTP/1.1 und HTTP/2 (WIP).
  • SSL/TLS-Unterstützung.
  • Unterstützung für chunked Daten.
  • Bequeme Schnittstellen zur Unterstützung von Funktionen wie json, Autorisierung usw.
  • Stream-Schnittstellen zum Lesen des Körpers.
  • HTTP/HTTPS-Proxy.
  • Latenzmetriken.
  • Sitzungsunterstützung.

Synopsis

local requests = require "resty.requests"

-- Beispiel-URL
local url = "http://example.com/index.html"

local r, err = requests.get(url)
if not r then
    ngx.log(ngx.ERR, err)
    return
end

-- gesamten Körper lesen
local body = r:body()
ngx.print(body)

-- oder Sie können den Antwortkörper iterieren
-- while true do
--     local chunk, err = r:iter_content(4096)
--     if not chunk then
--         ngx.log(ngx.ERR, err)
--         return
--     end
--
--     if chunk == "" then
--         break
--     end
--
--     ngx.print(chunk)
-- end

-- Sie können auch den Nicht-Stream-Modus verwenden
-- local opts = {
--     stream = false
-- }
--
-- local r, err = requests.get(url, opts)
-- if not r then
--     ngx.log(ngx.ERR, err)
-- end
--
-- ngx.print(r.content)

-- oder Sie können den Abkürzungsweg verwenden, um den Code sauberer zu machen.
local r, err = requests.get { url = url, stream = false }

Methoden

request

syntax: local r, err = requests.request(method, url, opts?)
syntax: local r, err = requests.request { method = method, url = url, ... }

Dies ist die zentrale Methode in lua-resty-requests, sie gibt ein Antwortobjekt r zurück. Im Falle eines Fehlers wird nil und eine Lua-Zeichenkette, die den entsprechenden Fehler beschreibt, zurückgegeben.

Der erste Parameter method ist die HTTP-Methode, die Sie verwenden möchten (entspricht der Semantik von HTTP), die einen Lua-String annimmt, und der Wert kann sein:

  • GET
  • HEAD
  • POST
  • PUT
  • DELETE
  • OPTIONS
  • PATCH

Der zweite Parameter url hat die wörtliche Bedeutung (d.h. Uniform Resource Location), zum Beispiel http://foo.com/blah?a=b, Sie können das Scheme-Präfix weglassen, und als Standard-Scheme wird http ausgewählt.

Der dritte Parameter, eine optionale Lua-Tabelle, die eine Reihe von Optionen enthält:

  • headers enthält die benutzerdefinierten Anfrage-Header.

  • allow_redirects gibt an, ob bei einem Statuscode von 301, 302, 303, 307 oder 308 auf die Ziel-URL (angegeben durch denLocation`-Header) umgeleitet werden soll oder nicht.

  • redirect_max_times gibt die Umleitungsgrenzen an, standardmäßig 10.

  • body, der Anfragekörper, kann sein:

    • ein Lua-String oder
    • eine Lua-Funktion, ohne Parameter und gibt ein Stück Daten (String) oder einen leeren Lua-String zurück, um EOF darzustellen, oder
    • eine Lua-Tabelle, wobei jedes Schlüssel-Wert-Paar mit & verknüpft wird, und der Content-Type-Header wird "application/x-www-form-urlencoded" sein.
  • error_filter enthält eine Lua-Funktion, die zwei Parameter annimmt: state und err. Der Parameter err beschreibt den Fehler und state ist immer einer dieser Werte (repräsentiert die aktuelle Phase):

    • requests.CONNECT
    • requests.HANDSHAKE
    • requests.SEND_HEADER
    • requests.SEND_BODY
    • requests.RECV_HEADER
    • requests.RECV_BODY
    • requests.CLOSE

Sie können die Methode requests.state verwenden, um die textuelle Bedeutung dieser Werte zu erhalten.

  • timeouts, eine array-ähnliche Tabelle, timeouts[1], timeouts[2] und timeouts[3] repräsentieren connect timeout, send timeout und read timeout jeweils (in Millisekunden).

  • http10 gibt an, ob HTTP/1.0 verwendet werden soll, die Standardversion ist HTTP/1.1.

  • http20 gibt an, ob HTTP/2 verwendet werden soll, die Standardversion ist HTTP/1.1.

Beachten Sie, dass dies noch instabil ist, Vorsicht ist geboten. Außerdem gibt es einige Einschränkungen, siehe lua-resty-http2 für die Details.

  • ssl enthält eine Lua-Tabelle mit drei Feldern:
  • verify, steuert, ob eine SSL-Überprüfung durchgeführt werden soll
  • server_name, wird verwendet, um den Servernamen für die neue TLS-Erweiterung Server Name Indication (SNI) anzugeben

  • proxies gibt Proxy-Server an, die Form ist wie folgt

{
    http = { host = "127.0.0.1", port = 80 },
    https = { host = "192.168.1.3", port = 443 },
}

Beim Verwenden eines HTTPS-Proxys wird eine vorhergehende CONNECT-Anfrage an den Proxy-Server gesendet.

  • hooks, ebenfalls eine Lua-Tabelle, repräsentiert das Hook-System, das Sie verwenden können, um Teile des Anfrageprozesses zu manipulieren. Verfügbare Hooks sind:
  • response, wird sofort nach dem Empfang der Antwort-Header ausgelöst

Sie können Lua-Funktionen an Hooks zuweisen, diese Funktionen akzeptieren das Antwortobjekt als einzigartigen Parameter.

local hooks = {
    response = function(r)
        ngx.log(ngx.WARN, "während des Anfrageprozesses")
    end
}

In Anbetracht der Bequemlichkeit gibt es auch einige "Abkürzungs"-Optionen:

  • auth, um die Basic HTTP-Authentifizierung durchzuführen, nimmt eine Lua-Tabelle mit user und pass, z.B. wenn auth ist:
{
    user = "alex",
    pass = "123456"
}

Der Anfrage-Header Authorization wird hinzugefügt, und der Wert ist Basic YWxleDoxMjM0NTY=.

  • json, nimmt eine Lua-Tabelle, sie wird von cjson serialisiert, die serialisierten Daten werden als Anfragekörper gesendet, und sie hat Vorrang, wenn sowohl json als auch body angegeben sind.

  • cookie, nimmt eine Lua-Tabelle, die Schlüssel-Wert-Paare werden gemäß den Regeln des Cookie-Headers organisiert, z.B. wenn cookie ist:

{
    ["PHPSESSID"] = "298zf09hf012fh2",
    ["csrftoken"] = "u32t4o3tb3gg43"
}

Der Cookie-Header wird PHPSESSID=298zf09hf012fh2; csrftoken=u32t4o3tb3gg43 sein.

  • stream, nimmt einen booleschen Wert, der angibt, ob der Körper im Stream-Modus gelesen werden soll, und standardmäßig wird er auf true gesetzt.

state

syntax: local state_name = requests.state(state)

Die Methode wird verwendet, um die textuelle Bedeutung dieser Werte zu erhalten:

  • requests.CONNECT
  • requests.HANDSHAKE
  • requests.SEND_HEADER
  • requests.SEND_BODY
  • requests.RECV_HEADER
  • requests.RECV_BODY
  • requests.CLOSE

Eine Lua-Zeichenkette "unknown" wird zurückgegeben, wenn state nicht einer der oben genannten Werte ist.

get

syntax: local r, err = requests.get(url, opts?)
syntax: local r, err = requests.get { url = url, ... }

Sendet eine HTTP GET-Anfrage. Dies ist identisch mit

requests.request("GET", url, opts)

syntax: local r, err = requests.head(url, opts?)
syntax: local r, err = requests.head { url = url, ... }

Sendet eine HTTP HEAD-Anfrage. Dies ist identisch mit

requests.request("HEAD", url, opts)

post

syntax: local r, err = requests.post(url, opts?)
syntax: local r, err = requests.post { url = url, ... }

Sendet eine HTTP POST-Anfrage. Dies ist identisch mit

requests.request("POST", url, opts)

put

syntax: local r, err = requests.put(url, opts?)
syntax: local r, err = requests.put { url = url, ... }

Sendet eine HTTP PUT-Anfrage. Dies ist identisch mit

requests.request("PUT", url, opts)

delete

syntax: local r, err = requests.delete(url, opts?)
syntax: local r, err = requests.delete { url = url, ... }

Sendet eine HTTP DELETE-Anfrage. Dies ist identisch mit

requests.request("DELETE", url, opts)

options

syntax: local r, err = requests.options(url, opts?)
syntax: local r, err = requests.options { url = url, ... }

Sendet eine HTTP OPTIONS-Anfrage. Dies ist identisch mit

requests.request("OPTIONS", url, opts)

patch

syntax: local r, err = requests.patch(url, opts?)
syntax: local r, err = requests.patch { url = url, ... }

Sendet eine HTTP PATCH-Anfrage. Dies ist identisch mit

requests.request("PATCH", url, opts)

Antwortobjekt

Methoden wie requests.get und andere geben ein Antwortobjekt r zurück, das durch die folgenden Methoden und Variablen manipuliert werden kann:

  • url, die URL, die vom Aufrufer übergeben wurde
  • method, die Anfrage-Methode, z.B. POST
  • status_line, die rohe Statuszeile (empfangen vom Remote)
  • status_code, der HTTP-Statuscode
  • http_version, die HTTP-Version der Antwort, z.B. HTTP/1.1
  • headers, eine Lua-Tabelle, die die HTTP-Antwort-Header darstellt (groß-/kleinschreibungsempfindlich)
  • close, enthält eine Lua-Funktion, die verwendet wird, um die zugrunde liegende TCP-Verbindung zu schließen (keepalive)
  • drop, ist eine Lua-Funktion, die verwendet wird, um den ungelesenen HTTP-Antwortkörper zu verwerfen, wird automatisch beim Schließen aufgerufen (wenn noch ungelesene Daten vorhanden sind)
  • iter_content, die ebenfalls eine Lua-Funktion ist, gibt jedes Mal einen Teil des Antwortkörpers (dekodiert aus dem chunked Format) zurück, wenn sie aufgerufen wird.

Diese Funktion akzeptiert einen optionalen Parameter size, um die Größe des Körpers anzugeben, die der Aufrufer wünscht. Wenn dieser Parameter fehlt, gibt iter_content 8192 Bytes zurück, wenn der Antwortkörper einfach ist, oder gibt ein Stück chunked Daten zurück, wenn der Antwortkörper chunked ist.

Im Falle eines Fehlers werden nil und eine Lua-Zeichenkette, die den Fehler beschreibt, zurückgegeben.

  • body, enthält ebenfalls eine Lua-Funktion, die den gesamten Antwortkörper zurückgibt.

Im Falle eines Fehlers werden nil und eine Lua-Zeichenkette, die den Fehler beschreibt, zurückgegeben.

  • json, enthält eine Lua-Funktion, die den Körper in eine Lua-Tabelle serialisiert, beachten Sie, dass der Content-Type application/json sein sollte. Im Falle eines Fehlers werden nil und eine Fehlermeldung zurückgegeben.

  • content, der Antwortkörper, nur gültig im Nicht-Stream-Modus.

  • elapsed, eine hash-ähnliche Lua-Tabelle, die die benötigte Zeit (in Sekunden) für jede Phase darstellt.

  • elapsed.connect, benötigte Zeit für das TCP 3-Wege-Handschlag;
  • elapsed.handshake, benötigte Zeit für den SSL/TLS-Handschlag (falls vorhanden);
  • elapsed.send_header, benötigte Zeit für das Senden der HTTP-Anfrage-Header;
  • elapsed.send_body, benötigte Zeit für das Senden des HTTP-Anfragekörpers (falls vorhanden);
  • elapsed.read_header, benötigte Zeit für das Empfangen der HTTP-Antwort-Header;
  • elapsed.ttfb, die Zeit bis zum ersten Byte.

Beachten Sie, dass bei Verwendung des HTTP/2-Protokolls die elapsed.send_body (falls vorhanden) die gleiche Zeit wie elapsed.send_header haben wird.

Sitzung

Eine Sitzung speichert einige Daten über mehrere Anfragen hinweg, wie z.B. Cookie-Daten, Autorisierungsdaten usw.

Dieser Mechanismus ist derzeit noch experimentell.

Ein einfaches Beispiel:

s = requests.session()
local r, err = s:get("https://www.example.com")
ngx.say(r:body())

Ein Sitzungsobjekt hat die gleichen Schnittstellen wie requests, d.h. diese HTTP-Methoden.

Siehe auch

GitHub

Sie finden zusätzliche Konfigurationstipps und Dokumentationen für dieses Modul im GitHub-Repository für nginx-module-requests.