-
Для запросов на
/search:- Считаем количество запросов от устройства (по
sc_get_gpc0). - Первый запрос — без задержки.
- Каждый следующий запрос задерживается на
delay = (номер запроса - 1) * 4секунд, но не более 32 секунд. - Максимальная задержка — 32 секунды, начиная с 9 запроса.
- Если заголовок
xbots2отсутствует — проверка не производится. - В лог пишется информация о каждом задержанном запросе.
Таблица задержек:
№ запроса Задержка (секунд) 1 0 2 4 3 8 4 12 5 16 6 20 7 24 8 28 9 32 10 и далее 32 - Считаем количество запросов от устройства (по
-
Для запросов на
conver:- Считает количество запросов от устройства (по
sc_get_gpc1). - Первый запрос — без задержки.
- Все последующие — задержка 1 секунда на каждый запрос.
Таблица задержек:
№ запроса Задержка (секунд) 1 0 2 1 3 1 4 1 … 1 - Считает количество запросов от устройства (по
lua-load device_ratelimit.lua
acl mobile_search path -i /search
acl mobile_conver path -i /conver
http-request set-header xbots2 %[req.fhdr(X-Device)] if { hdr_cnt(X-Device) eq 1 }
http-request track-sc1 hdr(xbots2) table bruteforce_ext_1h_2 if { hdr_cnt(X-Device) eq 1 }
http-request sc-inc-gpc0(1) if { hdr_cnt(X-Device) eq 1 } mobile_search
http-request sc-inc-gpc1(1) if { hdr_cnt(X-Device) eq 1 } mobile_conver
http-request lua.device_rate_limit if { hdr_cnt(X-Device) eq 1 } mobile_search
http-request lua.device_rate_limit if { hdr_cnt(X-Device) eq 1 } mobile_conver
http-request del-header xbots2
local max_delay = 32
local step = 4
local conver_delay = 1
core.register_action("device_rate_limit", {"http-req"}, function(txn)
local key = txn.sf:req_hdr("xbots2")
if not key or key == '' then return end
local path = txn.sf:path()
local is_search = string.find(path, "/search", 1, true) ~= nil
local is_conver = string.find(path, "/conver", 1, true) ~= nil
if is_search then
local count = tonumber(txn.sf:sc_get_gpc0(1)) or 0
local current_request = count + 1
if current_request == 1 then
return
end
local delay = math.min((current_request - 1) * step, max_delay)
if delay > 0 then
txn:Info("device_rate_limit(search): x-device=" .. key .. " count=" .. count .. " delay=" .. delay)
core.msleep(delay * 1000)
end
return
end
if is_conver then
local count = tonumber(txn.sf:sc_get_gpc1(1)) or 0
local current_request = count + 1
if current_request == 1 then
return
end
txn:Info("device_rate_limit(conver): x-device=" .. key .. " conv-count=" .. count .. " delay=" .. conver_delay)
core.msleep(conver_delay * 1000)
return
end
end)