aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVsevolod Stakhov <vsevolod@highsecure.ru>2017-01-21 13:17:02 +0000
committerVsevolod Stakhov <vsevolod@highsecure.ru>2017-01-21 13:18:54 +0000
commita9de49414c980f7356a49f240984b52fcca8ba23 (patch)
treeddfc09eb74c64108f93c360bbc77a065b7314427
parent75d23a996808fc0cc6540b0dbbfa195cc9c4b538 (diff)
downloadrspamd-a9de49414c980f7356a49f240984b52fcca8ba23.tar.gz
rspamd-a9de49414c980f7356a49f240984b52fcca8ba23.zip
[Feature] Implement human readable buckets configuration
Issue: #1335
-rw-r--r--src/plugins/lua/ratelimit.lua63
1 files changed, 63 insertions, 0 deletions
diff --git a/src/plugins/lua/ratelimit.lua b/src/plugins/lua/ratelimit.lua
index f029732fa..a9d3e65df 100644
--- a/src/plugins/lua/ratelimit.lua
+++ b/src/plugins/lua/ratelimit.lua
@@ -489,6 +489,64 @@ local function parse_limit(str)
end
end
+local function parse_string_limit(lim)
+ local function parse_time_suffix(s)
+ if s == 's' then
+ return 1
+ elseif s == 'm' then
+ return 60
+ elseif s == 'h' then
+ return 3600
+ elseif s == 'd' then
+ return 86400
+ end
+ end
+ local function parse_num_suffix(s)
+ if s == '' then
+ return 1
+ elseif s == 'k' then
+ return 1000
+ elseif s == 'm' then
+ return 1000000
+ elseif s == 'g' then
+ return 1000000000
+ end
+ end
+ local lpeg = require "lpeg"
+ local digit = lpeg.R("09")
+ local grammar = {}
+ grammar.integer =
+ (lpeg.S("+-") ^ -1) *
+ (digit ^ 1)
+ grammar.fractional =
+ (lpeg.P(".") ) *
+ (digit ^ 1)
+ grammar.number =
+ (grammar.integer *
+ (grammar.fractional ^ -1)) +
+ (lpeg.S("+-") * grammar.fractional)
+ grammar.time = lpeg.Cf(lpeg.Cc(1) *
+ (grammar.number / tonumber) *
+ ((lpeg.S("smhd") / parse_time_suffix) ^ -1),
+ function (acc, val) return acc * val end)
+ grammar.suffixed_number = lpeg.Cf(lpeg.Cc(1) *
+ (grammar.number / tonumber) *
+ ((lpeg.S("kmg") / parse_num_suffix) ^ -1),
+ function (acc, val) return acc * val end)
+ grammar.limit = lpeg.Ct(grammar.suffixed_number *
+ (lpeg.S(" ") ^ 0) * lpeg.S("/") * (lpeg.S(" ") ^ 0) *
+ grammar.time)
+ local t = lpeg.match(grammar.limit, lim)
+
+ if t and t[1] and t[2] and t[2] ~= 0 then
+ return t[1] / t[2]
+ end
+
+ rspamd_logger.errx(rspamd_config, 'bad limit: %s', lim)
+
+ return nil
+end
+
local opts = rspamd_config:get_all_opt('ratelimit')
if opts then
local rates = opts['limit']
@@ -503,6 +561,11 @@ if opts then
fun.each(function(t, lim)
if type(lim) == 'table' then
settings[t] = lim
+ elseif type(lim) == 'string' then
+ local plim = parse_string_limit(lim)
+ if plim then
+ settings[t] = plim
+ end
end
end, opts['rates'])
end