requests: Mais uma biblioteca HTTP para nginx-module-lua - Para seres humanos!
Instalação
Se você ainda não configurou a assinatura do repositório RPM, inscreva-se. Em seguida, você pode prosseguir com os seguintes passos.
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
Para usar esta biblioteca Lua com NGINX, certifique-se de que o nginx-module-lua esteja instalado.
Este documento descreve lua-resty-requests v0.7.3 lançado em 18 de julho de 2019.
- Suporte a HTTP/1.0, HTTP/1.1 e HTTP/2 (em desenvolvimento).
- Suporte a SSL/TLS.
- Suporte a dados em partes (chunked).
- Interfaces convenientes para suportar recursos como json, autorização, etc.
- Interfaces de stream para ler o corpo.
- Proxy HTTP/HTTPS.
- Métricas de latência.
- Suporte a sessões.
Sinopse
local requests = require "resty.requests"
-- exemplo de 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
-- ler todo o corpo
local body = r:body()
ngx.print(body)
-- ou você pode iterar o corpo da resposta
-- 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
-- você também pode usar o modo não-stream
-- 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 você pode usar a forma abreviada para deixar o código mais limpo.
local r, err = requests.get { url = url, stream = false }
Métodos
request
sintaxe: local r, err = requests.request(method, url, opts?)
sintaxe: local r, err = requests.request { method = method, url = url, ... }
Este é o método central em lua-resty-requests, ele retornará um objeto de resposta r. No caso de falha, nil e uma string Lua que descreve o erro correspondente serão retornados.
O primeiro parâmetro method é o método HTTP que você deseja usar (igual à semântica do HTTP), que aceita uma string Lua e o valor pode ser:
GETHEADPOSTPUTDELETEOPTIONSPATCH
O segundo parâmetro url aceita o significado literal (ou seja, Localização Uniforme de Recursos), por exemplo, http://foo.com/blah?a=b, você pode omitir o prefixo do esquema e, como esquema padrão, http será selecionado.
O terceiro parâmetro, uma tabela Lua opcional, que contém uma série de opções:
-
headerscontém os cabeçalhos de requisição personalizados. -
allow_redirectsespecifica se deve redirecionar para a URL de destino (especificada pelo cabeçalhoLocation) ou não quando o código de status for301,302,303,307ou308. -
redirect_max_timesespecifica os limites de redirecionamento, o padrão é10. -
body, o corpo da requisição, pode ser:- uma string Lua, ou
- uma função Lua, sem parâmetros e que retorna um pedaço de dados (string) ou uma string Lua vazia para representar EOF, ou
- uma tabela Lua, cada par chave-valor será concatenado com o "&", e o cabeçalho Content-Type será
"application/x-www-form-urlencoded"
-
error_filter, contém uma função Lua que aceita dois parâmetros,stateeerr. o parâmetroerrdescreve o erro estateé sempre um desses valores (representa o estágio atual):requests.CONNECTrequests.HANDSHAKErequests.SEND_HEADERrequests.SEND_BODYrequests.RECV_HEADERrequests.RECV_BODYrequests.CLOSE
Você pode usar o método requests.state para obter o significado textual desses valores.
-
timeouts, uma tabela semelhante a um array,timeouts[1],timeouts[2]etimeouts[3]representamtimeout de conexão,timeout de envioetimeout de leitura, respectivamente (em milissegundos). -
http10especifica se oHTTP/1.0deve ser usado, a versão padrão éHTTP/1.1. http20especifica se oHTTP/2deve ser usado, a versão padrão éHTTP/1.1.
Note que isso ainda é instável, cautela deve ser exercida. Além disso, existem algumas limitações, veja lua-resty-http2 para mais detalhes.
sslcontém uma tabela Lua, com três campos:verify, controla se deve realizar a verificação SSL-
server_name, é usado para especificar o nome do servidor para a nova extensão TLS Server Name Indication (SNI) -
proxiesespecifica servidores proxy, a forma é como
{
http = { host = "127.0.0.1", port = 80 },
https = { host = "192.168.1.3", port = 443 },
}
Ao usar um proxy HTTPS, uma requisição CONNECT anterior será enviada ao servidor proxy.
hooks, também uma tabela Lua, representa o sistema de hooks que você pode usar para manipular partes do processo de requisição. Os hooks disponíveis são:response, será acionado imediatamente após receber os cabeçalhos da resposta
você pode atribuir funções Lua aos hooks, essas funções aceitam o objeto de resposta como o único parâmetro.
local hooks = {
response = function(r)
ngx.log(ngx.WARN, "durante o processo de requisições")
end
}
Considerando a conveniência, também existem algumas opções de "caminho curto":
auth, para realizar a Autorização HTTP Básica, aceita uma tabela Lua que contémuserepass, por exemplo, quandoauthé:
{
user = "alex",
pass = "123456"
}
O cabeçalho da requisição Authorization será adicionado, e o valor será Basic YWxleDoxMjM0NTY=.
-
json, aceita uma tabela Lua, ela será serializada porcjson, os dados serializados serão enviados como o corpo da requisição, e tem prioridade quando tantojsonquantobodysão especificados. -
cookie, aceita uma tabela Lua, os pares chave-valor serão organizados de acordo com a regra do cabeçalhoCookie, por exemplo,cookieé:
{
["PHPSESSID"] = "298zf09hf012fh2",
["csrftoken"] = "u32t4o3tb3gg43"
}
O cabeçalho Cookie será PHPSESSID=298zf09hf012fh2; csrftoken=u32t4o3tb3gg43.
stream, aceita um valor booleano, especifica se deve ler o corpo no modo de stream, e será verdadeiro por padrão.
state
sintaxe: local state_name = requests.state(state)
O método é usado para obter o significado textual desses valores:
requests.CONNECTrequests.HANDSHAKErequests.SEND_HEADERrequests.SEND_BODYrequests.RECV_HEADERrequests.RECV_BODYrequests.CLOSE
uma string Lua "unknown" será retornada se state não for um dos valores acima.
get
sintaxe: local r, err = requests.get(url, opts?)
sintaxe: local r, err = requests.get { url = url, ... }
Envia uma requisição HTTP GET. Isso é idêntico a
requests.request("GET", url, opts)
head
sintaxe: local r, err = requests.head(url, opts?)
sintaxe: local r, err = requests.head { url = url, ... }
Envia uma requisição HTTP HEAD. Isso é idêntico a
requests.request("HEAD", url, opts)
post
sintaxe: local r, err = requests.post(url, opts?)
sintaxe: local r, err = requests.post { url = url, ... }
Envia uma requisição HTTP POST. Isso é idêntico a
requests.request("POST", url, opts)
put
sintaxe: local r, err = requests.put(url, opts?)
sintaxe: local r, err = requests.put { url = url, ... }
Envia uma requisição HTTP PUT. Isso é idêntico a
requests.request("PUT", url, opts)
delete
sintaxe: local r, err = requests.delete(url, opts?)
sintaxe: local r, err = requests.delete { url = url, ... }
Envia uma requisição HTTP DELETE. Isso é idêntico a
requests.request("DELETE", url, opts)
options
sintaxe: local r, err = requests.options(url, opts?)
sintaxe: local r, err = requests.options { url = url, ... }
Envia uma requisição HTTP OPTIONS. Isso é idêntico a
requests.request("OPTIONS", url, opts)
patch
sintaxe: local r, err = requests.patch(url, opts?)
sintaxe: local r, err = requests.patch { url = url, ... }
Envia uma requisição HTTP PATCH. Isso é idêntico a
requests.request("PATCH", url, opts)
Objeto de Resposta
Métodos como requests.get e outros retornarão um objeto de resposta r, que pode ser manipulado pelos seguintes métodos e variáveis:
url, a url passada pelo chamadormethod, o método da requisição, por exemplo,POSTstatus_line, a linha de status bruta (recebida do remoto)status_code, o código de status HTTPhttp_version, a versão HTTP da resposta, por exemplo,HTTP/1.1headers, uma tabela Lua que representa os cabeçalhos da resposta HTTP (case-insensitive)close, contém uma função Lua, usada para fechar (manter) a conexão TCP subjacentedrop, é uma função Lua, usada para descartar o corpo da resposta HTTP não lido, será invocada automaticamente ao fechar (se houver dados não lidos restantes)iter_content, que também é uma função Lua, emite uma parte do corpo da resposta (decodificada do formato chunked) cada vez que é chamada.
Essa função aceita um parâmetro opcional size para especificar o tamanho do corpo que o chamador deseja, quando ausente, iter_content retorna 8192 bytes quando o corpo da resposta é simples ou retorna um pedaço de dados chunked se o corpo da resposta for chunked.
Em caso de falha, nil e uma string Lua que descreve o erro serão retornados.
body, também contém uma função Lua que retorna todo o corpo da resposta.
Em caso de falha, nil e uma string Lua que descreve o erro serão retornados.
-
json, contém uma função Lua, serializa o corpo em uma tabela Lua, note que oContent-Typedeve serapplication/json. Em caso de falha,nile uma string de erro serão fornecidos. -
content, o corpo da resposta, válido apenas no modo não-stream. -
elapsed, uma tabela Lua semelhante a um hash que representa o tempo gasto (em segundos) para cada estágio. elapsed.connect, tempo gasto para o handshake TCP de 3 vias;elapsed.handshake, tempo gasto para o handshake SSL/TLS (se houver);elapsed.send_header, tempo gasto para enviar os cabeçalhos da requisição HTTP;elapsed.send_body, tempo gasto para enviar o corpo da requisição HTTP (se houver);elapsed.read_header, tempo gasto para receber os cabeçalhos da resposta HTTP;elapsed.ttfb, o tempo até o primeiro byte.
Note que quando o protocolo HTTP/2 é aplicado, o elapsed.send_body (se houver) será o mesmo que elapsed.send_header.
Sessão
Uma sessão persiste alguns dados entre múltiplas requisições, como dados de cookies, dados de autorização, etc.
Esse mecanismo ainda é experimental.
Um exemplo simples:
s = requests.session()
local r, err = s:get("https://www.example.com")
ngx.say(r:body())
Um objeto de sessão tem as mesmas interfaces que requests, ou seja, aqueles métodos http.
Veja Também
- upyun-resty: https://github.com/upyun/upyun-resty
- httpipe: https://github.com/timebug/lua-resty-httpipe
GitHub
Você pode encontrar dicas de configuração adicionais e documentação para este módulo no repositório GitHub para nginx-module-requests.