hyperscan: Hyperscan para nginx-module-lua
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-hyperscan
CentOS/RHEL 8+, Fedora Linux, Amazon Linux 2023
dnf -y install https://extras.getpagespeed.com/release-latest.rpm
dnf -y install lua5.1-resty-hyperscan
Para usar esta biblioteca Lua com NGINX, certifique-se de que o nginx-module-lua esteja instalado.
Este documento descreve lua-resty-hyperscan v0.3 lançado em 14 de abril de 2022.
lua-resty-hyperscan - Hyperscan para Openresty
!!! Old Branch teve um problema de muitos callbacks, porque o luajit não suporta completamente CALLBACK. Portanto, precisamos de um C wrapper para lidar com callbacks.
Primeiro, você deve instalar o openresty
git clone git@github.com:LubinLew/lua-resty-hyperscan.git cd lua-resty-hyperscan make make install make test
##
##
## Sinopse
exemplo de configuração
```lua
user nobody;
worker_processes auto;
error_log logs/error.log error;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
access_log logs/access.log;
init_by_lua_block {
local whs, err = require('hyperscan')
if not whs then
ngx.log(ngx.ERR, "Falha:", err)
return
end
-- novo
local obj = whs.block_new("a-uniq-name", true) -- true : habilitar modo de depuração
local patterns = {
{id = 1001, pattern = "\\d3", flag = "iu"},
{id = 1002, pattern = "\\s{3,5}", flag = "u"},
{id = 1003, pattern = "[a-d]{2,7}", flag = ""}
}
-- compilar
ret, err = obj:compile(patterns)
if not ret then
ngx.log(ngx.ERR, "compilação do bloco hyperscan falhou, ", err)
return
end
}
server {
listen 80;
server_name localhost;
location / {
content_by_lua_block {
local whs = require('hyperscan')
local obj = whs.block_get("a-uniq-name")
-- escanear
local ret, id, from, to = obj:scan(ngx.var.uri)
if ret then
return ngx.print("[", ngx.var.uri,"] correspondência: ", id, " zona [", from, " - ", to, ").\n")
else
return ngx.print("[", ngx.var.uri, "] não corresponde a nenhuma regra.\n")
end
}
}
}
}
casos de teste:
$ curl http://localhost
[/] não corresponde a nenhuma regra.
$ curl http://localhost/131111111
[/131111111] correspondência: 1001 zona [0 - 3).
$ curl "http://localhost/ end"
[/ end] correspondência: 1002 zona [0 - 4).
$ curl http://localhost/aaaaaaa
[/aaaaaaa] correspondência: 1003 zona [0 - 3).
Métodos
maneira de carregar esta biblioteca
local whs,err = require('hyperscan')
if not whs then
ngx.log(ngx.ERR, "razão: ", err)
end
block_new
Cria uma instância hyperscan para o modo bloco.
local handle, err = whs.block_new(name, debug)
if not handle then
ngx.log(ngx.ERR, "razão: ", err)
end
| Campo | Nome | Tipo Lua | Descrição |
|---|---|---|---|
| Parâmetro | name |
string | nome da instância, principalmente para log |
debug |
boolean | habilitar/desabilitar gravação de log de depuração no syslog | |
| Valor de Retorno | handle |
table/nil | referência da instância |
err |
string | razão da falha |
block_free
Destrói uma instância hyperscan para o modo bloco.
whs.block_free(name)
block_get
Obtém a referência da instância pelo nome.
local handle = whs.block_get(name)
| Campo | Nome | Tipo Lua | Descrição |
|---|---|---|---|
| Parâmetro | name |
string | nome da instância |
| Valor de Retorno | handle |
table/nil | referência da instância |
vector_new
Cria uma instância hyperscan para o modo vetor.
local handle, err = whs.vector_new(name, debug)
if not handle then
ngx.log(ngx.ERR, "razão: ", err)
end
| Campo | Nome | Tipo Lua | Descrição |
|---|---|---|---|
| Parâmetro | name |
string | nome da instância, principalmente para log |
debug |
boolean | habilitar/desabilitar gravação de log de depuração no syslog | |
| Valor de Retorno | handle |
table/nil | referência da instância |
err |
string | razão da falha |
vector_free
Destrói uma instância hyperscan para o modo vetor.
whs.vector_free(name)
vector_get
Obtém a referência da instância pelo nome.
local handle = whs.vector_get(name)
| Campo | Nome | Tipo Lua | Descrição |
|---|---|---|---|
| Parâmetro | name |
string | nome da instância |
| Valor de Retorno | handle |
table/nil | referência da instância |
handle:compile
compila expressões regulares em um banco de dados Hyperscan.
--local handle = whs.block_new(name, debug)
local ok, err = handle:compile(patterns)
if not ok then
ngx.log(ngx.ERR, "razão: ", err)
end
| Campo | Nome | Tipo Lua | Descrição |
|---|---|---|---|
| parâmetro | patterns |
table | lista de padrões |
| Valor de Retorno | ok |
boolean | sucesso/falha |
err |
string | razão da falha |
Lista de Padrões
Exemplo
local patterns = {
{id = 1001, pattern = "\\d3", flag = "iu" },
{id = 1002, pattern = "\\s{3,5}", flag = "dmsu" },
{id = 1003, pattern = "[a-d]{2,7}", flag = "" }
}
Flags
| Flag | Valor do Hyperscan | Descrição |
|---|---|---|
'i' |
HS_FLAG_CASELESS | Define correspondência sem distinção entre maiúsculas e minúsculas |
'd' |
HS_FLAG_DOTALL | A correspondência de um . não excluirá novas linhas. |
'm' |
HS_FLAG_MULTILINE | Define ancoragem em várias linhas. |
's' |
HS_FLAG_SINGLEMATCH | Define o modo de correspondência única. |
'e' |
HS_FLAG_ALLOWEMPTY | Permite expressões que podem corresponder a buffers vazios. |
'u' |
HS_FLAG_UTF8 | Habilita o modo UTF-8 para esta expressão. |
'p' |
HS_FLAG_UCP | Habilita suporte a propriedades Unicode para esta expressão. |
'f' |
HS_FLAG_PREFILTER | Habilita o modo de pré-filtragem para esta expressão. |
'l' |
HS_FLAG_SOM_LEFTMOST | Habilita a notificação do início da correspondência mais à esquerda. |
'c' |
HS_FLAG_COMBINATION | Combinação lógica. |
'q' |
HS_FLAG_QUIET | Não faça nenhuma notificação de correspondência. |
handle:scan
A correspondência real de padrões ocorre para bancos de dados de padrões em modo bloco.
--local handle = whs.block_get(name)
local ok, id, from, to = handle:scan(data)
if ok then
ngx.log(ngx.INFO, "correspondência bem-sucedida", id, from, to)
end
A correspondência real de padrões ocorre para bancos de dados de padrões em modo vetor.
--local handle = whs.vector_get(name)
--local data = {"s","s2"}
--local data = "s"
local ok, id, dataindex, to = handle:scan(data)
if ok then
ngx.log(ngx.INFO, "correspondência bem-sucedida", id, from, to)
end
| Campo | Nome | Tipo Lua | Descrição |
|---|---|---|---|
| Parâmetro | data |
string/string[] | string a ser escaneado (string[] apenas no modo vetor) |
| Valor de Retorno | ok |
boolean | true para correspondência, false para não correspondência |
id |
number | id da correspondência | |
from |
number | índice do byte de início da correspondência (incluindo ele mesmo) | |
to |
number | índice do byte de fim da correspondência (excluindo ele mesmo) | |
dataindex |
number | índice de dados correspondentes (apenas no modo vetor) |
handle:free
Destrói uma instância hyperscan.
--local handle = whs.block_get(name)
handle:free()
GitHub
Você pode encontrar dicas adicionais de configuração e documentação para este módulo no repositório GitHub para nginx-module-hyperscan.