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.