@@ -22,6 +22,9 @@ local pairs = pairs
2222local redis_schema = require (" apisix.utils.redis-schema" )
2323local policy_to_additional_properties = redis_schema .schema
2424local get_phase = ngx .get_phase
25+ local tonumber = tonumber
26+ local type = type
27+ local tostring = tostring
2528
2629local limit_redis_cluster_new
2730local limit_redis_new
3639 local cluster_src = " apisix.plugins.limit-count.limit-count-redis-cluster"
3740 limit_redis_cluster_new = require (cluster_src ).new
3841end
39- local lrucache = core .lrucache .new ({
40- type = ' plugin' , serial_creating = true ,
41- })
4242local group_conf_lru = core .lrucache .new ({
4343 type = ' plugin' ,
4444})
@@ -70,8 +70,18 @@ local metadata_schema = {
7070local schema = {
7171 type = " object" ,
7272 properties = {
73- count = {type = " integer" , exclusiveMinimum = 0 },
74- time_window = {type = " integer" , exclusiveMinimum = 0 },
73+ count = {
74+ oneOf = {
75+ {type = " integer" , exclusiveMinimum = 0 },
76+ {type = " string" },
77+ },
78+ },
79+ time_window = {
80+ oneOf = {
81+ {type = " integer" , exclusiveMinimum = 0 },
82+ {type = " string" },
83+ },
84+ },
7585 group = {type = " string" },
7686 key = {type = " string" , default = " remote_addr" },
7787 key_type = {type = " string" ,
@@ -174,22 +184,47 @@ function _M.check_schema(conf, schema_type)
174184end
175185
176186
177- local function create_limit_obj (conf , plugin_name )
187+ local function create_limit_obj (conf , ctx , plugin_name )
178188 core .log .info (" create new " .. plugin_name .. " plugin instance" )
179189
190+ local count = conf .count
191+ if type (count ) == " string" then
192+ local err , _
193+ count , err , _ = core .utils .resolve_var (count , ctx .var )
194+ if err then
195+ return nil , " could not resolve vars in count: " .. err
196+ end
197+ count = tonumber (count )
198+ if not count then
199+ return nil , " resolved count is not a number: " .. tostring (count )
200+ end
201+ end
202+
203+ local time_window = conf .time_window
204+ if type (time_window ) == " string" then
205+ local err , _
206+ time_window , err , _ = core .utils .resolve_var (time_window , ctx .var )
207+ if err then
208+ return nil , " could not resolve vars in time_window: " .. err
209+ end
210+ time_window = tonumber (time_window )
211+ if not time_window then
212+ return nil , " resolved time_window is not a number: " .. tostring (time_window )
213+ end
214+ end
215+
216+ core .log .info (" limit count: " , count , " , time_window: " , time_window )
217+
180218 if not conf .policy or conf .policy == " local" then
181- return limit_local_new (" plugin-" .. plugin_name , conf .count ,
182- conf .time_window )
219+ return limit_local_new (" plugin-" .. plugin_name , count , time_window )
183220 end
184221
185222 if conf .policy == " redis" then
186- return limit_redis_new (" plugin-" .. plugin_name ,
187- conf .count , conf .time_window , conf )
223+ return limit_redis_new (" plugin-" .. plugin_name , count , time_window , conf )
188224 end
189225
190226 if conf .policy == " redis-cluster" then
191- return limit_redis_cluster_new (" plugin-" .. plugin_name , conf .count ,
192- conf .time_window , conf )
227+ return limit_redis_cluster_new (" plugin-" .. plugin_name , count , time_window , conf )
193228 end
194229
195230 return nil
@@ -223,26 +258,11 @@ local function gen_limit_key(conf, ctx, key)
223258end
224259
225260
226- local function gen_limit_obj (conf , ctx , plugin_name )
227- if conf .group then
228- return lrucache (conf .group , " " , create_limit_obj , conf , plugin_name )
229- end
230-
231- local extra_key
232- if conf ._vid then
233- extra_key = conf .policy .. ' #' .. conf ._vid
234- else
235- extra_key = conf .policy
236- end
237-
238- return core .lrucache .plugin_ctx (lrucache , ctx , extra_key , create_limit_obj , conf , plugin_name )
239- end
240-
241261function _M .rate_limit (conf , ctx , name , cost , dry_run )
242262 core .log .info (" ver: " , ctx .conf_version )
243263 core .log .info (" conf: " , core .json .delay_encode (conf , true ))
244264
245- local lim , err = gen_limit_obj (conf , ctx , name )
265+ local lim , err = create_limit_obj (conf , ctx , name )
246266
247267 if not lim then
248268 core .log .error (" failed to fetch limit.count object: " , err )
@@ -307,7 +327,7 @@ function _M.rate_limit(conf, ctx, name, cost, dry_run)
307327 if err == " rejected" then
308328 -- show count limit header when rejected
309329 if conf .show_limit_quota_header and set_header then
310- core .response .set_header (set_limit_headers .limit_header , conf . count ,
330+ core .response .set_header (set_limit_headers .limit_header , lim . limit ,
311331 set_limit_headers .remaining_header , 0 ,
312332 set_limit_headers .reset_header , reset )
313333 end
@@ -326,7 +346,7 @@ function _M.rate_limit(conf, ctx, name, cost, dry_run)
326346 end
327347
328348 if conf .show_limit_quota_header and set_header then
329- core .response .set_header (set_limit_headers .limit_header , conf . count ,
349+ core .response .set_header (set_limit_headers .limit_header , lim . limit ,
330350 set_limit_headers .remaining_header , remaining ,
331351 set_limit_headers .reset_header , reset )
332352 end
0 commit comments