Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 13 additions & 1 deletion apisix/plugins/limit-count/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -391,7 +391,19 @@ local function resolve_var(ctx, value)
end
value = tonumber(value)
if not value then
return nil, "resolved value is not a number: " .. tostring(value)
return nil, "resolved value is not a number"
end
-- count/time_window must be positive integers, matching the schema
if value <= 0 then
return nil, "resolved value must be a positive number, got: " .. tostring(value)
end
if value ~= math_floor(value) then
return nil, "resolved value must be an integer, got: " .. tostring(value)
end
-- LuaJIT doubles lose integer precision above 2^53
if value > 9007199254740991 then
return nil, "resolved value exceeds safe integer range (2^53-1), got: "
.. tostring(value)
end
end
return value
Expand Down
99 changes: 99 additions & 0 deletions t/plugin/limit-count-variable.t
Original file line number Diff line number Diff line change
Expand Up @@ -284,3 +284,102 @@ nginx_config:
--- error_code: 200
--- access_log eval
qr/\{\\x22rate_limiting_key\\x22:\\x22\/apisix\/routes\/1:\d+:test\.com\\x22,\\x22rate_limiting_limit\\x22:2,\\x22rate_limiting_remaining\\x22:1,\\x22rate_limiting_reset\\x22:10}/



=== TEST 9: set up route with count/time_window from request variables
--- config
location /t {
content_by_lua_block {
local t = require("lib.test_admin").test
local code, body = t('/apisix/admin/routes/1',
ngx.HTTP_PUT,
[[{
"methods": ["GET"],
"plugins": {
"limit-count": {
"count": "${http_count ?? 2}",
"time_window": "${http_time_window ?? 5}",
"rejected_code": 503,
"key_type": "var",
"key": "remote_addr",
"policy": "local"
}
},
"upstream": {
"nodes": {
"127.0.0.1:1980": 1
},
"type": "roundrobin"
},
"uri": "/hello"
}]]
)

if code >= 300 then
ngx.status = code
end
ngx.say(body)
}
}
--- response_body
passed



=== TEST 10: a client-supplied 0/negative/fractional count is rejected, not bypassed
--- config
location /t {
content_by_lua_block {
local http = require("resty.http")
local uri = "http://127.0.0.1:" .. ngx.var.server_port .. "/hello"
local httpc = http.new()
for _, count in ipairs({"0", "-1", "1.5", "9999999999999999"}) do
local res = httpc:request_uri(uri, {method = "GET",
headers = {["count"] = count}})
if res.status ~= 500 then
ngx.say("count=", count, " should be rejected with 500, got ", res.status)
return
end
end
ngx.say("passed")
}
}
--- request
GET /t
--- response_body
passed
--- error_log
resolved value must be a positive number
resolved value must be an integer
resolved value exceeds safe integer range



=== TEST 11: a client-supplied 0/negative/fractional time_window is rejected, not bypassed
--- config
location /t {
content_by_lua_block {
local http = require("resty.http")
local uri = "http://127.0.0.1:" .. ngx.var.server_port .. "/hello"
local httpc = http.new()
for _, time_window in ipairs({"0", "-1", "1.5", "9999999999999999"}) do
local res = httpc:request_uri(uri, {method = "GET",
headers = {["time_window"] = time_window}})
if res.status ~= 500 then
ngx.say("time_window=", time_window, " should be rejected with 500, got ",
res.status)
return
end
end
ngx.say("passed")
}
}
--- request
GET /t
--- response_body
passed
--- error_log
resolved value must be a positive number
resolved value must be an integer
resolved value exceeds safe integer range
Loading