lua-resty-hyperscan - Hyperscan for Openresty
!!! Old Branch got too many callbacks problem, because luajit is not fully support CALLBACK. So we need a C wrapper to handle callbacks.
This library is under development so far.
Support Block Mode and Vectored Mode now.
# first, you should install openresty
git clone [email protected]:LubinLew/lua-resty-hyperscan.git
cd lua-resty-hyperscan
make
make install
make test
configuration example
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, "Failure:", err)
return
end
-- new
local obj = whs.block_new("a-uniq-name", true) -- true : enable debug mode
local patterns = {
{id = 1001, pattern = "\\d3", flag = "iu"},
{id = 1002, pattern = "\\s{3,5}", flag = "u"},
{id = 1003, pattern = "[a-d]{2,7}", flag = ""}
}
-- compile
ret, err = obj:compile(patterns)
if not ret then
ngx.log(ngx.ERR, "hyperscan block compile failed, ", 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")
-- scan
local ret, id, from, to = obj:scan(ngx.var.uri)
if ret then
return ngx.print("[", ngx.var.uri,"] match: ", id, " zone [", from, " - ", to, ").\n")
else
return ngx.print("[", ngx.var.uri, "] not match any rule.\n")
end
}
}
}
}
test cases:
$ curl http://localhost
[/] not match any rule.
$ curl http://localhost/131111111
[/131111111] match: 1001 zone [0 - 3).
$ curl "http://localhost/ end"
[/ end] match: 1002 zone [0 - 4).
$ curl http://localhost/aaaaaaa
[/aaaaaaa] match: 1003 zone [0 - 3).
way to load this library
local whs,err = require('hyperscan')
if not whs then
ngx.log(ngx.ERR, "reason: ", err)
end
Create a hyperscan instance for block mode.
local handle, err = whs.block_new(name, debug)
if not handle then
ngx.log(ngx.ERR, "reason: ", err)
end
Field | Name | Lua Type | Description |
---|---|---|---|
Parameter | name |
string | instance name, mainly for log |
debug |
boolean | enable/disable write debug log to syslog | |
Return Value | handle |
table/nil | instance reference |
err |
string | reason of failure |
Destroy a hyperscan instance for block mode.
whs.block_free(name)
Get the instance reference by name.
local handle = whs.block_get(name)
Filed | Name | Lua Type | Description |
---|---|---|---|
Parameter | name |
string | instance name |
Return Value | handle |
table/nil | instance reference |
Create a hyperscan instance for vector mode.
local handle, err = whs.vector_new(name, debug)
if not handle then
ngx.log(ngx.ERR, "reason: ", err)
end
Field | Name | Lua Type | Description |
---|---|---|---|
Parameter | name |
string | instance name, mainly for log |
debug |
boolean | enable/disable write debug log to syslog | |
Return Value | handle |
table/nil | instance reference |
err |
string | reason of failure |
Destroy a hyperscan instance for vector mode.
whs.vector_free(name)
Get the instance reference by name.
local handle = whs.vector_get(name)
Filed | Name | Lua Type | Description |
---|---|---|---|
Parameter | name |
string | instance name |
Return Value | handle |
table/nil | instance reference |
compile regular expression into a Hyperscan database.
--local handle = whs.block_new(name, debug)
local ok, err = handle:compile(patterns)
if not ok then
ngx.log(ngx.ERR, "reason: ", err)
end
Field | Name | Lua Type | Description |
---|---|---|---|
parameter | patterns |
table | pattern list |
Return Value | ok |
boolean | success/failure |
err |
string | reason of failure |
local patterns = {
{id = 1001, pattern = "\\d3", flag = "iu" },
{id = 1002, pattern = "\\s{3,5}", flag = "dmsu" },
{id = 1003, pattern = "[a-d]{2,7}", flag = "" }
}
Flag | Hyperscan Value | Description |
---|---|---|
'i' |
HS_FLAG_CASELESS | Set case-insensitive matching |
'd' |
HS_FLAG_DOTALL | Matching a . will not exclude newlines. |
'm' |
HS_FLAG_MULTILINE | Set multi-line anchoring. |
's' |
HS_FLAG_SINGLEMATCH | Set single-match only mode. |
'e' |
HS_FLAG_ALLOWEMPTY | Allow expressions that can match against empty buffers. |
'u' |
HS_FLAG_UTF8 | Enable UTF-8 mode for this expression. |
'p' |
HS_FLAG_UCP | Enable Unicode property support for this expression. |
'f' |
HS_FLAG_PREFILTER | Enable prefiltering mode for this expression. |
'l' |
HS_FLAG_SOM_LEFTMOST | Enable leftmost start of match reporting. |
'c' |
HS_FLAG_COMBINATION | Logical combination. |
'q' |
HS_FLAG_QUIET | Don't do any match reporting. |
The actual pattern matching takes place for block-mode pattern databases.
--local handle = whs.block_get(name)
local ok, id, from, to = handle:scan(data)
if ok then
ngx.log(ngx.INFO, "match success", id, from, to)
end
The actual pattern matching takes place for vector-mode pattern databases.
--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, "match success", id, from, to)
end
Field | Name | Lua Type | Description |
---|---|---|---|
Parameter | data |
string/string[] | string to be scanned(string[] only vector mode) |
Return Value | ok |
boolean | ture for match, false for not match |
id |
number | match id | |
from |
number | match from byte arrary index(include itself) | |
to |
number | match end byte arrary index(exclude itself) | |
dataindex |
number | match data index(only vector mode) |
Destroy a hyperscan instance.
--local handle = whs.block_get(name)
handle:free()
Author: Lubin [email protected].
This module is licensed under the MIT license.
See Also