Перейти к содержанию

hyperscan: Hyperscan для nginx-module-lua

Установка

Если вы еще не подписались на репозиторий RPM, зарегистрируйтесь. Затем вы можете продолжить с следующими шагами.

CentOS/RHEL 7 или 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

Чтобы использовать эту библиотеку Lua с NGINX, убедитесь, что nginx-module-lua установлен.

Этот документ описывает lua-resty-hyperscan v0.3, выпущенную 14 апреля 2022 года.


lua-resty-hyperscan - Hyperscan для Openresty

!!! Старая ветка столкнулась с проблемой слишком большого количества обратных вызовов, потому что luajit не полностью поддерживает CALLBACK. Поэтому нам нужен C обертка для обработки обратных вызовов.

Сначала вам нужно установить openresty

git clone git@github.com:LubinLew/lua-resty-hyperscan.git cd lua-resty-hyperscan make make install make test

##

##

## Синопсис

пример конфигурации

```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, "Ошибка:", err)
            return
        end

       -- новый
       local obj = whs.block_new("a-uniq-name", true) -- true : включить режим отладки

       local patterns = {
           {id = 1001, pattern = "\\d3",       flag = "iu"},
           {id = 1002, pattern = "\\s{3,5}",   flag = "u"},
           {id = 1003, pattern = "[a-d]{2,7}", flag = ""}
       }

        -- компиляция
        ret, err = obj:compile(patterns)
        if not ret then
           ngx.log(ngx.ERR, "Компиляция блока hyperscan не удалась, ", 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")
                -- сканирование
                local ret, id, from, to = obj:scan(ngx.var.uri)
                if ret then
                    return ngx.print("[", ngx.var.uri,"] совпадение: ", id, " зона [", from, " - ", to, ").\n")
                else
                    return ngx.print("[", ngx.var.uri, "] не совпадает ни с одним правилом.\n")
                end
            }
        }
    }
}

тестовые случаи:

$ curl http://localhost
[/] не совпадает ни с одним правилом.

$ curl http://localhost/131111111
[/131111111] совпадение: 1001 зона [0 - 3).

$ curl "http://localhost/      end"
[/      end] совпадение: 1002 зона [0 - 4).

$ curl http://localhost/aaaaaaa
[/aaaaaaa] совпадение: 1003 зона [0 - 3).

Методы

способ загрузки этой библиотеки

local whs,err = require('hyperscan')
if not whs then
    ngx.log(ngx.ERR, "причина: ", err)
end

block_new

Создать экземпляр hyperscan для блочного режима.

local handle, err = whs.block_new(name, debug)
if not handle then
    ngx.log(ngx.ERR, "причина: ", err)
end
Поле Имя Тип Lua Описание
Параметр name string имя экземпляра, в основном для логирования
debug boolean включить/выключить запись отладочного лога в syslog
Возвращаемое значение handle table/nil ссылка на экземпляр
err string причина сбоя

block_free

Уничтожить экземпляр hyperscan для блочного режима.

whs.block_free(name)

block_get

Получить ссылку на экземпляр по имени.

local handle = whs.block_get(name)
Поле Имя Тип Lua Описание
Параметр name string имя экземпляра
Возвращаемое значение handle table/nil ссылка на экземпляр

vector_new

Создать экземпляр hyperscan для векторного режима.

local handle, err = whs.vector_new(name, debug)
if not handle then
    ngx.log(ngx.ERR, "причина: ", err)
end
Поле Имя Тип Lua Описание
Параметр name string имя экземпляра, в основном для логирования
debug boolean включить/выключить запись отладочного лога в syslog
Возвращаемое значение handle table/nil ссылка на экземпляр
err string причина сбоя

vector_free

Уничтожить экземпляр hyperscan для векторного режима.

whs.vector_free(name)

vector_get

Получить ссылку на экземпляр по имени.

local handle = whs.vector_get(name)
Поле Имя Тип Lua Описание
Параметр name string имя экземпляра
Возвращаемое значение handle table/nil ссылка на экземпляр

handle:compile

Скомпилировать регулярное выражение в базу данных Hyperscan.

--local handle = whs.block_new(name, debug)
local ok, err = handle:compile(patterns)
if not ok then
    ngx.log(ngx.ERR, "причина: ", err)
end
Поле Имя Тип Lua Описание
параметр patterns table список шаблонов
Возвращаемое значение ok boolean успех/неудача
err string причина сбоя

Список шаблонов

Пример
local patterns = {
    {id = 1001, pattern = "\\d3",       flag = "iu"   },
    {id = 1002, pattern = "\\s{3,5}",   flag = "dmsu" },
    {id = 1003, pattern = "[a-d]{2,7}", flag = ""     }
}
Флаги
Флаг Значение Hyperscan Описание
'i' HS_FLAG_CASELESS Установить нечувствительное к регистру совпадение
'd' HS_FLAG_DOTALL Совпадение с . не исключает переводы строк.
'm' HS_FLAG_MULTILINE Установить многострочное якорение.
's' HS_FLAG_SINGLEMATCH Установить режим только для единственного совпадения.
'e' HS_FLAG_ALLOWEMPTY Разрешить выражения, которые могут совпадать с пустыми буферами.
'u' HS_FLAG_UTF8 Включить режим UTF-8 для этого выражения.
'p' HS_FLAG_UCP Включить поддержку свойств Unicode для этого выражения.
'f' HS_FLAG_PREFILTER Включить режим предварительной фильтрации для этого выражения.
'l' HS_FLAG_SOM_LEFTMOST Включить отчет о самом левом начале совпадения.
'c' HS_FLAG_COMBINATION Логическая комбинация.
'q' HS_FLAG_QUIET Не делать никаких отчетов о совпадениях.

handle:scan

Фактическое совпадение шаблонов происходит для баз данных шаблонов блочного режима.

--local handle = whs.block_get(name)
local ok, id, from, to = handle:scan(data)
if ok then
    ngx.log(ngx.INFO, "совпадение успешно", id, from, to)
end

Фактическое совпадение шаблонов происходит для баз данных шаблонов векторного режима.

--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, "совпадение успешно", id, from, to)
end
Поле Имя Тип Lua Описание
Параметр data string/string[] строка для сканирования(только строка[] векторный режим)
Возвращаемое значение ok boolean true для совпадения, false для отсутствия совпадения
id number идентификатор совпадения
from number индекс начала совпадения в массиве байтов(включая саму себя)
to number индекс конца совпадения в массиве байтов(исключая саму себя)
dataindex number индекс совпадения данных(только векторный режим)

handle:free

Уничтожить экземпляр hyperscan.

--local handle = whs.block_get(name)
handle:free()

GitHub

Вы можете найти дополнительные советы по конфигурации и документацию для этого модуля в репозитории GitHub для nginx-module-hyperscan.