requests: Encore une autre bibliothèque HTTP pour nginx-module-lua - Pour les êtres humains !
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-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
Pour utiliser cette bibliothèque Lua avec NGINX, assurez-vous que nginx-module-lua est installé.
Ce document décrit lua-resty-requests v0.7.3 publié le 18 juillet 2019.
- HTTP/1.0, HTTP/1.1 et HTTP/2 (en cours).
- Support SSL/TLS.
- Support des données en morceaux.
- Interfaces pratiques pour prendre en charge des fonctionnalités comme json, autorisation, etc.
- Interfaces de flux pour lire le corps.
- Proxy HTTP/HTTPS.
- Métriques de latence.
- Support des sessions.
Synopsis
local requests = require "resty.requests"
-- exemple d'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
-- lire tout le corps
local body = r:body()
ngx.print(body)
-- ou vous pouvez itérer le corps de la réponse
-- 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
-- vous pouvez également utiliser le mode non-flux
-- 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)
-- ou vous pouvez utiliser la méthode abrégée pour rendre le code plus propre.
local r, err = requests.get { url = url, stream = false }
Méthodes
request
syntax: local r, err = requests.request(method, url, opts?)
syntax: local r, err = requests.request { method = method, url = url, ... }
C'est la méthode centrale de lua-resty-requests, elle renverra un objet réponse r. En cas d'échec, nil, et une chaîne Lua décrivant l'erreur correspondante seront fournies.
Le premier paramètre method est la méthode HTTP que vous souhaitez utiliser (identique à la sémantique HTTP), qui prend une chaîne Lua et la valeur peut être :
GETHEADPOSTPUTDELETEOPTIONSPATCH
Le deuxième paramètre url prend simplement le sens littéral (c'est-à-dire Uniform Resource Location), par exemple, http://foo.com/blah?a=b, vous pouvez omettre le préfixe de schéma et par défaut, http sera sélectionné.
Le troisième paramètre, une table Lua optionnelle, qui contient un certain nombre d'options :
-
headerscontient les en-têtes de requête personnalisés. -
allow_redirectsspécifie si la redirection vers l'URL cible (spécifiée par l'en-têteLocation) doit être effectuée ou non lorsque le code d'état est301,302,303,307ou308. -
redirect_max_timesspécifie les limites de redirection, la valeur par défaut est10. -
body, le corps de la requête, peut être :- une chaîne Lua, ou
- une fonction Lua, sans paramètre et renvoyant un morceau de données (chaîne) ou une chaîne Lua vide pour représenter EOF, ou
- une table Lua, chaque paire clé-valeur sera concaténée avec le "&", et l'en-tête Content-Type sera
"application/x-www-form-urlencoded"
-
error_filter, contient une fonction Lua qui prend deux paramètres,stateeterr. le paramètreerrdécrit l'erreur etstateest toujours l'une de ces valeurs (représentant l'étape actuelle) :requests.CONNECTrequests.HANDSHAKErequests.SEND_HEADERrequests.SEND_BODYrequests.RECV_HEADERrequests.RECV_BODYrequests.CLOSE
Vous pouvez utiliser la méthode requests.state pour obtenir la signification textuelle de ces valeurs.
-
timeouts, une table de type tableau,timeouts[1],timeouts[2]ettimeouts[3]représentent respectivementconnect timeout,send timeoutetread timeout(en millisecondes). -
http10spécifie si leHTTP/1.0doit être utilisé, la version par défaut estHTTP/1.1. http20spécifie si leHTTP/2doit être utilisé, la version par défaut estHTTP/1.1.
Notez que cela est encore instable, la prudence doit être exercée. De plus, il existe certaines limitations, voir lua-resty-http2 pour les détails.
sslcontient une table Lua, avec trois champs :verify, contrôle si une vérification SSL doit être effectuée-
server_name, est utilisé pour spécifier le nom du serveur pour la nouvelle extension TLS Server Name Indication (SNI) -
proxiesspécifie les serveurs proxy, le format est comme suit
{
http = { host = "127.0.0.1", port = 80 },
https = { host = "192.168.1.3", port = 443 },
}
Lors de l'utilisation d'un proxy HTTPS, une requête CONNECT préalable sera envoyée au serveur proxy.
hooks, également une table Lua, représente le système de hooks que vous pouvez utiliser pour manipuler des portions du processus de requête. Les hooks disponibles sont :response, sera déclenché immédiatement après la réception des en-têtes de réponse
vous pouvez assigner des fonctions Lua aux hooks, ces fonctions acceptent l'objet réponse comme paramètre unique.
local hooks = {
response = function(r)
ngx.log(ngx.WARN, "durant le processus de requêtes")
end
}
Pour plus de commodité, il existe également quelques options "chemin court" :
auth, pour effectuer l'authentification HTTP de base, prend une table Lua contenantuseretpass, par exemple lorsqueauthest :
{
user = "alex",
pass = "123456"
}
L'en-tête de requête Authorization sera ajouté, et la valeur sera Basic YWxleDoxMjM0NTY=.
-
json, prend une table Lua, elle sera sérialisée parcjson, les données sérialisées seront envoyées comme corps de la requête, et elle a la priorité lorsquejsonetbodysont spécifiés. -
cookie, prend une table Lua, les paires clé-valeur seront organisées selon la règle de l'en-têteCookie, par exemplecookieest :
{
["PHPSESSID"] = "298zf09hf012fh2",
["csrftoken"] = "u32t4o3tb3gg43"
}
L'en-tête Cookie sera PHPSESSID=298zf09hf012fh2; csrftoken=u32t4o3tb3gg43.
stream, prend une valeur booléenne, spécifie si la lecture du corps en mode flux doit être effectuée, et elle sera vraie par défaut.
state
syntax: local state_name = requests.state(state)
La méthode est utilisée pour obtenir la signification textuelle de ces valeurs :
requests.CONNECTrequests.HANDSHAKErequests.SEND_HEADERrequests.SEND_BODYrequests.RECV_HEADERrequests.RECV_BODYrequests.CLOSE
une chaîne Lua "unknown" sera renvoyée si state n'est pas l'une des valeurs ci-dessus.
get
syntax: local r, err = requests.get(url, opts?)
syntax: local r, err = requests.get { url = url, ... }
Envoie une requête HTTP GET. Cela est identique à
requests.request("GET", url, opts)
head
syntax: local r, err = requests.head(url, opts?)
syntax: local r, err = requests.head { url = url, ... }
Envoie une requête HTTP HEAD. Cela est identique à
requests.request("HEAD", url, opts)
post
syntax: local r, err = requests.post(url, opts?)
syntax: local r, err = requests.post { url = url, ... }
Envoie une requête HTTP POST. Cela est identique à
requests.request("POST", url, opts)
put
syntax: local r, err = requests.put(url, opts?)
syntax: local r, err = requests.put { url = url, ... }
Envoie une requête HTTP PUT. Cela est identique à
requests.request("PUT", url, opts)
delete
syntax: local r, err = requests.delete(url, opts?)
syntax: local r, err = requests.delete { url = url, ... }
Envoie une requête HTTP DELETE. Cela est identique à
requests.request("DELETE", url, opts)
options
syntax: local r, err = requests.options(url, opts?)
syntax: local r, err = requests.options { url = url, ... }
Envoie une requête HTTP OPTIONS. Cela est identique à
requests.request("OPTIONS", url, opts)
patch
syntax: local r, err = requests.patch(url, opts?)
syntax: local r, err = requests.patch { url = url, ... }
Envoie une requête HTTP PATCH. Cela est identique à
requests.request("PATCH", url, opts)
Objet Réponse
Des méthodes comme requests.get et d'autres renverront un objet réponse r, qui peut être manipulé par les méthodes et variables suivantes :
url, l'url passée par l'appelantmethod, la méthode de requête, par exemplePOSTstatus_line, la ligne de statut brute (reçue du distant)status_code, le code d'état HTTPhttp_version, la version HTTP de la réponse, par exempleHTTP/1.1headers, une table Lua représentant les en-têtes de réponse HTTP (insensible à la casse)close, contient une fonction Lua, utilisée pour fermer (keepalive) la connexion TCP sous-jacentedrop, est une fonction Lua, utilisée pour supprimer le corps de réponse HTTP non lu, sera invoquée automatiquement lors de la fermeture (s'il reste des données non lues)iter_content, qui est également une fonction Lua, émet une partie du corps de réponse (décodée du format en morceaux) chaque fois qu'elle est appelée.
Cette fonction accepte un paramètre optionnel size pour spécifier la taille du corps que l'appelant souhaite, en son absence, iter_content renvoie 8192 octets lorsque le corps de réponse est simple ou renvoie un morceau de données en morceaux si le corps de réponse est en morceaux.
En cas d'échec, nil et une chaîne Lua décrivant l'erreur seront renvoyés.
body, contient également une fonction Lua qui renvoie l'ensemble du corps de réponse.
En cas d'échec, nil et une chaîne Lua décrivant l'erreur seront renvoyés.
-
json, contient une fonction Lua, sérialise le corps en une table Lua, notez que leContent-Typedoit êtreapplication/json. En cas d'échec,nilet une chaîne d'erreur seront fournies. -
content, le corps de la réponse, valide uniquement en mode non-flux. -
elapsed, une table Lua de type hash qui représente le temps de coût (en secondes) pour chaque étape. elapsed.connect, temps de coût pour le handshake TCP à 3 voies ;elapsed.handshake, temps de coût pour le handshake SSL/TLS (le cas échéant) ;elapsed.send_header, temps de coût pour l'envoi des en-têtes de requête HTTP ;elapsed.send_body, temps de coût pour l'envoi du corps de requête HTTP (le cas échéant) ;elapsed.read_header, temps de coût pour la réception des en-têtes de réponse HTTP ;elapsed.ttfb, le temps jusqu'au premier octet.
Notez que lorsque le protocole HTTP/2 est appliqué, le elapsed.send_body (le cas échéant) sera identique à elapsed.send_header.
Session
Une session persiste certaines données à travers plusieurs requêtes, comme les données de cookies, les données d'autorisation, etc.
Ce mécanisme est encore expérimental.
Un exemple simple :
s = requests.session()
local r, err = s:get("https://www.example.com")
ngx.say(r:body())
Un objet session a les mêmes interfaces que requests, c'est-à-dire ces méthodes http.
Voir aussi
- upyun-resty: https://github.com/upyun/upyun-resty
- httpipe: https://github.com/timebug/lua-resty-httpipe
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-requests.