Pular para conteúdo

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.