This is an automated email from the ASF dual-hosted git repository.
spacewander pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/apisix.git
The following commit(s) were added to refs/heads/master by this push:
new 0e973fb feat(limit-* plugin): fallback to remote_addr when key is
missing (#5422)
0e973fb is described below
commit 0e973fbb508b180c0be21bde41cd1363c5fa61f9
Author: Xunzhuo <[email protected]>
AuthorDate: Sun Nov 7 19:29:27 2021 +0800
feat(limit-* plugin): fallback to remote_addr when key is missing (#5422)
---
apisix/plugins/limit-conn/init.lua | 7 +-
apisix/plugins/limit-count.lua | 8 +--
apisix/plugins/limit-req.lua | 7 +-
docs/en/latest/plugins/limit-conn.md | 33 +++++++++-
docs/en/latest/plugins/limit-count.md | 2 +-
docs/en/latest/plugins/limit-req.md | 32 ++++++++-
docs/zh/latest/plugins/limit-conn.md | 32 ++++++++-
docs/zh/latest/plugins/limit-count.md | 3 +-
docs/zh/latest/plugins/limit-req.md | 30 ++++++++-
t/plugin/limit-conn2.t | 119 +++++++++++++++++++++++++++-------
t/plugin/limit-count2.t | 86 ++++++++++++++++++++++--
t/plugin/limit-req.t | 2 +-
t/plugin/limit-req2.t | 81 ++++++++++++++++++++++-
t/stream-plugin/limit-conn.t | 6 +-
14 files changed, 389 insertions(+), 59 deletions(-)
diff --git a/apisix/plugins/limit-conn/init.lua
b/apisix/plugins/limit-conn/init.lua
index adc1e68..8b404a5 100644
--- a/apisix/plugins/limit-conn/init.lua
+++ b/apisix/plugins/limit-conn/init.lua
@@ -64,10 +64,9 @@ function _M.increase(conf, ctx)
end
if key == nil then
- core.log.info("bypass the limit conn as the key is empty")
- -- Bypass the limit conn when the key is empty.
- -- This behavior is the same as Nginx
- return
+ core.log.info("The value of the configured key is empty, use client IP
instead")
+ -- When the value of key is empty, use client IP instead
+ key = ctx.var["remote_addr"]
end
key = key .. ctx.conf_type .. ctx.conf_version
diff --git a/apisix/plugins/limit-count.lua b/apisix/plugins/limit-count.lua
index 1a52ef4..cbce3a7 100644
--- a/apisix/plugins/limit-count.lua
+++ b/apisix/plugins/limit-count.lua
@@ -187,11 +187,11 @@ function _M.access(conf, ctx)
end
if key == nil then
- core.log.info("bypass the limit count as the key is empty")
- -- Bypass the limit count when the key is empty.
- -- This behavior is the same as Nginx
- return
+ core.log.info("The value of the configured key is empty, use client IP
instead")
+ -- When the value of key is empty, use client IP instead
+ key = ctx.var["remote_addr"]
end
+
key = key .. ctx.conf_type .. ctx.conf_version
core.log.info("limit key: ", key)
diff --git a/apisix/plugins/limit-req.lua b/apisix/plugins/limit-req.lua
index 6768dc1..824a47d 100644
--- a/apisix/plugins/limit-req.lua
+++ b/apisix/plugins/limit-req.lua
@@ -102,10 +102,9 @@ function _M.access(conf, ctx)
end
if key == nil then
- core.log.info("bypass the limit req as the key is empty")
- -- Bypass the limit req when the key is empty.
- -- This behavior is the same as Nginx
- return
+ core.log.info("The value of the configured key is empty, use client IP
instead")
+ -- When the value of key is empty, use client IP instead
+ key = ctx.var["remote_addr"]
end
key = key .. ctx.conf_type .. ctx.conf_version
diff --git a/docs/en/latest/plugins/limit-conn.md
b/docs/en/latest/plugins/limit-conn.md
index 4790039..37f15c4 100644
--- a/docs/en/latest/plugins/limit-conn.md
+++ b/docs/en/latest/plugins/limit-conn.md
@@ -42,14 +42,14 @@ Limiting request concurrency plugin.
| default_conn_delay | number | required | | default_conn_delay >
0 | the
latency seconds of request when concurrent requests exceeding `conn` but below
(`conn` + `burst`).
[...]
| only_use_default_delay | boolean | optional | false | [true,false]
|
enable the strict mode of the latency seconds. If you set this option to
`true`, it will run strictly according to the latency seconds you set without
additional calculation logic.
[...]
| key_type | string | optional | "var" | ["var",
"var_combination"] | the type of key. |
-| key | string | required | | | the user specified key
to limit the rate. If the `key_type` is "var", the key will be treated as a
name of variable, like "remote_addr" or "consumer_name". If the `key_type` is
"var_combination", the key will be a combination of variables, like
"$remote_addr $consumer_name". |
+| key | string | required | | | the user specified key
to limit the rate. If the `key_type` is "var", the key will be treated as a
name of variable, like "remote_addr" or "consumer_name". If the `key_type` is
"var_combination", the key will be a combination of variables, like
"$remote_addr $consumer_name". If the value of the key is empty, `remote_addr`
will be set as the default key.|
| rejected_code | string | optional | 503 | [200,...,599]
| the HTTP
status code returned when the request exceeds `conn` + `burst` will be
rejected.
[...]
| rejected_msg | string | optional |
| non-empty | the response body returned
when the request exceeds `conn` + `burst` will be rejected.
|
| allow_degradation | boolean | optional
| false |
| Whether to enable plugin degradation when the limit-conn function
is temporarily unavailable. Allow requests to continue when the value is set to
true, default false. |
## How To Enable
-Here's an example, enable the limit-conn plugin on the specified route:
+Here's an example, enable the limit-conn plugin on the specified route when
setting `key_type` to `var` :
```shell
curl http://127.0.0.1:9080/apisix/admin/routes/1 -H 'X-API-KEY:
edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
@@ -62,7 +62,34 @@ curl http://127.0.0.1:9080/apisix/admin/routes/1 -H
'X-API-KEY: edd1c9f034335f13
"burst": 0,
"default_conn_delay": 0.1,
"rejected_code": 503,
- "key": "remote_addr"
+ "key_type": "var",
+ "key": "http_a"
+ }
+ },
+ "upstream": {
+ "type": "roundrobin",
+ "nodes": {
+ "39.97.63.215:80": 1
+ }
+ }
+}'
+```
+
+Here's an example, enable the limit-conn plugin on the specified route when
setting `key_type` to `var_combination` :
+
+```shell
+curl http://127.0.0.1:9080/apisix/admin/routes/1 -H 'X-API-KEY:
edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
+{
+ "methods": ["GET"],
+ "uri": "/index.html",
+ "plugins": {
+ "limit-conn": {
+ "conn": 1,
+ "burst": 0,
+ "default_conn_delay": 0.1,
+ "rejected_code": 503,
+ "key_type": "var_combination",
+ "key": "$consumer_name $remote_addr"
}
},
"upstream": {
diff --git a/docs/en/latest/plugins/limit-count.md
b/docs/en/latest/plugins/limit-count.md
index 2c26760..ebd3795 100644
--- a/docs/en/latest/plugins/limit-count.md
+++ b/docs/en/latest/plugins/limit-count.md
@@ -40,7 +40,7 @@ Limit request rate by a fixed number of requests in a given
time window.
| count | integer | required |
| count > 0
| the specified number of requests
threshold.
|
| time_window | integer | required |
| time_window > 0
| the time window in seconds before the request count
is reset.
|
| key_type | string | optional | "var" | ["var",
"var_combination"] | the type of key. |
-| key | string | optional | "remote_addr" | | the user
specified key to limit the rate. If the `key_type` is "var", the key will be
treated as a name of variable. If the `key_type` is "var_combination", the key
will be a combination of variables. For example, if we use "$remote_addr
$consumer_name" as keys, plugin will be restricted by two keys which are
"remote_addr" and "consumer_name". |
+| key | string | optional | "remote_addr" | | the user
specified key to limit the rate. If the `key_type` is "var", the key will be
treated as a name of variable. If the `key_type` is "var_combination", the key
will be a combination of variables. For example, if we use "$remote_addr
$consumer_name" as keys, plugin will be restricted by two keys which are
"remote_addr" and "consumer_name". If the value of the key is empty,
`remote_addr` will be set as the default key.|
| rejected_code | integer | optional |
503 | [200,...,599]
| The HTTP status code returned when
the request exceeds the threshold is rejected, default 503.
|
| rejected_msg | string | optional |
| non-empty
| The response body returned when the request
exceeds the threshold is rejected.
|
| policy | string | optional |
"local" | ["local", "redis", "redis-cluster"]
| The rate-limiting policies to use for
retrieving and incrementing the limits. Available values are `local`(the
counters will be stored locally in-memory on the node), `redis`(counters are
stored on a Redis server and will be shared across the nodes, usually use it to
do the global speed limit) [...]
diff --git a/docs/en/latest/plugins/limit-req.md
b/docs/en/latest/plugins/limit-req.md
index 0c16c76..f63eb93 100644
--- a/docs/en/latest/plugins/limit-req.md
+++ b/docs/en/latest/plugins/limit-req.md
@@ -41,7 +41,7 @@ limit request rate using the "leaky bucket" method.
| rate | integer | required | | rate > 0
| the specified request rate
(number per second) threshold. Requests exceeding this rate (and below `burst`)
will get delayed to conform to the rate. |
| burst | integer | required | | burst >= 0
| the number of excessive
requests per second allowed to be delayed. Requests exceeding this hard limit
will get rejected immediately. |
| key_type | string | optional | "var" | ["var",
"var_combination"] | the type of key. |
-| key | string | required | | | the user specified key
to limit the rate. If the `key_type` is "var", the key will be treated as a
name of variable, like "remote_addr" or "consumer_name". If the `key_type` is
"var_combination", the key will be a combination of variables, like
"$remote_addr $consumer_name". |
+| key | string | required | | | the user specified key
to limit the rate. If the `key_type` is "var", the key will be treated as a
name of variable, like "remote_addr" or "consumer_name". If the `key_type` is
"var_combination", the key will be a combination of variables, like
"$remote_addr $consumer_name". If the value of the key is empty, `remote_addr`
will be set as the default key.|
| rejected_code | integer | optional | 503 | [200,...,599]
| The HTTP status code returned
when the request exceeds the threshold is rejected.
|
| rejected_msg | string | optional |
| non-empty | The response body returned
when the request exceeds the threshold is rejected.
|
| nodelay | boolean | optional | false |
| If nodelay flag is true,
bursted requests will not get delayed |
@@ -51,7 +51,7 @@ limit request rate using the "leaky bucket" method.
### How to enable on the `route` or `service`
-Take `route` as an example (the use of `service` is the same method), enable
the `limit-req` plugin on the specified route.
+Take `route` as an example (the use of `service` is the same method), enable
the `limit-req` plugin on the specified route when setting `key_type` to `var` .
```shell
curl http://127.0.0.1:9080/apisix/admin/routes/1 -H 'X-API-KEY:
edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
@@ -63,13 +63,39 @@ curl http://127.0.0.1:9080/apisix/admin/routes/1 -H
'X-API-KEY: edd1c9f034335f13
"rate": 1,
"burst": 2,
"rejected_code": 503,
+ "key_type": "var",
"key": "remote_addr"
}
},
"upstream": {
"type": "roundrobin",
"nodes": {
- "39.97.63.215:80": 1
+ "127.0.0.1:9001": 1
+ }
+ }
+}'
+```
+
+Take `route` as an example (the use of `service` is the same method), enable
the `limit-req` plugin on the specified route when setting `key_type` to
`var_combination` .
+
+```shell
+curl http://127.0.0.1:9080/apisix/admin/routes/1 -H 'X-API-KEY:
edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
+{
+ "methods": ["GET"],
+ "uri": "/index.html",
+ "plugins": {
+ "limit-req": {
+ "rate": 1,
+ "burst": 2,
+ "rejected_code": 503,
+ "key_type": "var_combination",
+ "key": "$consumer_name $remote_addr"
+ }
+ },
+ "upstream": {
+ "type": "roundrobin",
+ "nodes": {
+ "127.0.0.1:9001": 1
}
}
}'
diff --git a/docs/zh/latest/plugins/limit-conn.md
b/docs/zh/latest/plugins/limit-conn.md
index ca3a381..1fdaa62 100644
--- a/docs/zh/latest/plugins/limit-conn.md
+++ b/docs/zh/latest/plugins/limit-conn.md
@@ -32,14 +32,14 @@ title: limit-conn
| default_conn_delay | number | required | | default_conn_delay > 0
|
默认的典型连接(或请求)的处理延迟时间。
[...]
| only_use_default_delay | boolean | optional | false | [true,false]
|
延迟时间的严格模式。 如果设置为`true`的话,将会严格按照设置的时间来进行延迟
[...]
| key_type | string | 可选 | "var" | ["var", "var_combination"]
| key 的类型 |
-| key | string | 必须 | | | 用来做请求计数的依据。如果 `key_type` 为
"var",那么 key 会被当作变量名称,如 "remote_addr" 和 "consumer_name"。如果 `key_type` 为
"var_combination",那么 key 会当作变量组合,如 "$remote_addr $consumer_name"。 |
+| key | string | 必须 | | | 用来做请求计数的依据。如果 `key_type` 为
"var",那么 key 会被当作变量名称,如 "remote_addr" 和 "consumer_name"。如果 `key_type` 为
"var_combination",那么 key 会当作变量组合,如 "$remote_addr $consumer_name"。如果 key
的值为空,$remote_addr 会被作为默认 key。 |
| rejected_code | string | optional | 503 | [200,...,599]
| 当请求超过 `conn`
+ `burst` 这个阈值时,返回的 HTTP 状态码
[...]
| rejected_msg | string | 可选 |
| 非空 | 当请求超过 `conn` + `burst`
这个阈值时,返回的响应体。
|
| allow_degradation | boolean | 可选
| false |
| 当插件功能临时不可用时是否允许请求继续。当值设置为 true 时则自动允许请求继续,默认值是 false。|
#### 如何启用
-下面是一个示例,在指定的 route 上开启了 limit-conn 插件:
+下面是一个示例,在指定的 route 上开启了 limit-conn 插件,并设置 `key_type` 为 `var`:
```shell
curl http://127.0.0.1:9080/apisix/admin/routes/1 -H 'X-API-KEY:
edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
@@ -53,6 +53,7 @@ curl http://127.0.0.1:9080/apisix/admin/routes/1 -H
'X-API-KEY: edd1c9f034335f13
"burst": 0,
"default_conn_delay": 0.1,
"rejected_code": 503,
+ "key_type": "var",
"key": "remote_addr"
}
},
@@ -65,6 +66,33 @@ curl http://127.0.0.1:9080/apisix/admin/routes/1 -H
'X-API-KEY: edd1c9f034335f13
}'
```
+下面是一个示例,在指定的 route 上开启了 limit-conn 插件,并设置 `key_type` 为 `var_combination`:
+
+```shell
+curl http://127.0.0.1:9080/apisix/admin/routes/1 -H 'X-API-KEY:
edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
+{
+ "methods": ["GET"],
+ "uri": "/index.html",
+ "id": 1,
+ "plugins": {
+ "limit-conn": {
+ "conn": 1,
+ "burst": 0,
+ "default_conn_delay": 0.1,
+ "rejected_code": 503,
+ "key_type": "var_combination",
+ "key": "$consumer_name $remote_addr"
+ }
+ },
+ "upstream": {
+ "type": "roundrobin",
+ "nodes": {
+ "39.97.63.215:80": 1
+ }
+ }
+}'
+```
+
你也可以通过 web 界面来完成上面的操作,先增加一个 route,然后在插件页面中添加 limit-conn 插件:

diff --git a/docs/zh/latest/plugins/limit-count.md
b/docs/zh/latest/plugins/limit-count.md
index 5117364..7c9f309 100644
--- a/docs/zh/latest/plugins/limit-count.md
+++ b/docs/zh/latest/plugins/limit-count.md
@@ -43,7 +43,7 @@ title: limit-count
| count | integer | 必须 |
| count > 0
| 指定时间窗口内的请求数量阈值
[...]
| time_window | integer | 必须 |
| time_window > 0
| 时间窗口的大小(以秒为单位),超过这个时间就会重置
[...]
| key_type | string | 可选 | "var" | ["var", "var_combination"]
| key 的类型 |
-| key | string | 可选 | "remote_addr" | | 用来做请求计数的依据。如果
`key_type` 为 "var",那么 key 会被当作变量名称。如果 `key_type` 为 "var_combination",那么 key
会当作变量组。比如如果设置 "$remote_addr $consumer_name" 作为 keys,那么插件会同时受 remote_addr 和
consumer_name 两个 key 的约束。 |
+| key | string | 可选 | "remote_addr" | | 用来做请求计数的依据。如果
`key_type` 为 "var",那么 key 会被当作变量名称。如果 `key_type` 为 "var_combination",那么 key
会当作变量组。比如如果设置 "$remote_addr $consumer_name" 作为 keys,那么插件会同时受 remote_addr 和
consumer_name 两个 key 的约束。如果 key 的值为空,$remote_addr 会被作为默认 key。 |
| rejected_code | integer | 可选 | 503
| [200,...,599]
| 当请求超过阈值被拒绝时,返回的 HTTP 状态码
[...]
| rejected_msg | string | 可选 |
| 非空
| 当请求超过阈值被拒绝时,返回的响应体。
|
| policy | string | 可选 | "local"
| ["local", "redis", "redis-cluster"]
|
用于检索和增加限制的速率限制策略。可选的值有:`local`(计数器被以内存方式保存在节点本地,默认选项) 和 `redis`(计数器保存在 Redis
服务节点上,从而可以跨节点共享结果,通常用它来完成全局限速);以及`redis-cluster`,跟 redis 功能一样,只是使用 redis 集群方式。
|
@@ -72,6 +72,7 @@ curl -i http://127.0.0.1:9080/apisix/admin/routes/1 -H
'X-API-KEY: edd1c9f034335
"count": 2,
"time_window": 60,
"rejected_code": 503,
+ "key_type": "var",
"key": "remote_addr"
}
},
diff --git a/docs/zh/latest/plugins/limit-req.md
b/docs/zh/latest/plugins/limit-req.md
index d0e8dd9..a7d88ca 100644
--- a/docs/zh/latest/plugins/limit-req.md
+++ b/docs/zh/latest/plugins/limit-req.md
@@ -41,7 +41,7 @@ title: limit-req
| rate | integer | 必须 | | rate > 0
| 指定的请求速率(以秒为单位),请求速率超过 `rate` 但没有超过
(`rate` + `brust`)的请求会被加上延时。 |
| burst | integer | 必须 | | burst >= 0
| 请求速率超过 (`rate` + `brust`)的请求会被直接拒绝。
|
| key_type | string | 可选 | "var" | ["var", "var_combination"]
| key 的类型 |
-| key | string | 必须 | | | 用来做请求计数的依据。如果 `key_type` 为
"var",那么 key 会被当作变量名称,如 "remote_addr" 和 "consumer_name"。如果 `key_type` 为
"var_combination",那么 key 会当作变量组合,如 "$remote_addr $consumer_name"。 |
+| key | string | 必须 | | | 用来做请求计数的依据。如果 `key_type` 为
"var",那么 key 会被当作变量名称,如 "remote_addr" 和 "consumer_name"。如果 `key_type` 为
"var_combination",那么 key 会当作变量组合,如 "$remote_addr $consumer_name"。如果 key
的值为空,$remote_addr 会被作为默认 key。 |
| rejected_code | integer | 可选 | 503 | [200,...,599]
| 当请求超过阈值被拒绝时,返回的 HTTP 状态码。
|
| rejected_msg | string | 可选 |
| 非空 | 当请求超过阈值被拒绝时,返回的响应体。
|
| nodelay | boolean | 可选 | false |
| 如果 nodelay 为 true, 请求速率超过 `rate` 但没有超过
(`rate` + `brust`)的请求不会加上延迟, 如果是 false,则会加上延迟。 |
@@ -51,7 +51,7 @@ title: limit-req
### 如何在`route`或`service`上使用
-这里以`route`为例(`service`的使用是同样的方法),在指定的 `route` 上启用 `limit-req` 插件。
+这里以`route`为例(`service`的使用是同样的方法),在指定的 `route` 上启用 `limit-req` 插件,并设置
`key_type` 为 `var`。
```shell
curl http://127.0.0.1:9080/apisix/admin/routes/1 -H 'X-API-KEY:
edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
@@ -63,6 +63,7 @@ curl http://127.0.0.1:9080/apisix/admin/routes/1 -H
'X-API-KEY: edd1c9f034335f13
"rate": 1,
"burst": 2,
"rejected_code": 503,
+ "key_type": "var",
"key": "remote_addr"
}
},
@@ -75,6 +76,31 @@ curl http://127.0.0.1:9080/apisix/admin/routes/1 -H
'X-API-KEY: edd1c9f034335f13
}'
```
+这里以`route`为例(`service`的使用是同样的方法),在指定的 `route` 上启用 `limit-req` 插件,并设置
`key_type` 为 `var_combination`。
+
+```shell
+curl http://127.0.0.1:9080/apisix/admin/routes/1 -H 'X-API-KEY:
edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
+{
+ "methods": ["GET"],
+ "uri": "/index.html",
+ "plugins": {
+ "limit-req": {
+ "rate": 1,
+ "burst": 2,
+ "rejected_code": 503,
+ "key_type": "var_combination",
+ "key": "$consumer_name $remote_addr"
+ }
+ },
+ "upstream": {
+ "type": "roundrobin",
+ "nodes": {
+ "39.97.63.215:80": 1
+ }
+ }
+}'
+```
+
你也可以通过 web 界面来完成上面的操作,先增加一个 route,然后在插件页面中添加 limit-req 插件:

diff --git a/t/plugin/limit-conn2.t b/t/plugin/limit-conn2.t
index 187e3aa..75375aa 100644
--- a/t/plugin/limit-conn2.t
+++ b/t/plugin/limit-conn2.t
@@ -34,6 +34,36 @@ no_root_location();
add_block_preprocessor(sub {
my ($block) = @_;
+ my $port = $ENV{TEST_NGINX_SERVER_PORT};
+
+ my $config = $block->config // <<_EOC_;
+ location /access_root_dir {
+ content_by_lua_block {
+ local httpc = require "resty.http"
+ local hc = httpc:new()
+
+ local res, err =
hc:request_uri('http://127.0.0.1:$port/limit_conn')
+ if res then
+ ngx.exit(res.status)
+ end
+ }
+ }
+
+ location /test_concurrency {
+ content_by_lua_block {
+ local reqs = {}
+ for i = 1, 5 do
+ reqs[i] = { "/access_root_dir" }
+ end
+ local resps = { ngx.location.capture_multi(reqs) }
+ for i, resp in ipairs(resps) do
+ ngx.say(resp.status)
+ end
+ }
+ }
+_EOC_
+
+ $block->set_value("config", $config);
if (!$block->request) {
$block->set_value("request", "GET /t");
@@ -311,7 +341,7 @@ request latency is nil
-=== TEST 9: set key type to var_combination
+=== TEST 9: update plugin to set key_type to var_combination
--- config
location /t {
content_by_lua_block {
@@ -321,8 +351,8 @@ request latency is nil
[[{
"plugins": {
"limit-conn": {
- "conn": 2,
- "burst": 1,
+ "conn": 1,
+ "burst": 0,
"default_conn_delay": 0.1,
"rejected_code": 503,
"key": "$http_a $http_b",
@@ -342,8 +372,8 @@ request latency is nil
"value": {
"plugins": {
"limit-conn": {
- "conn": 2,
- "burst": 1,
+ "conn": 1,
+ "burst": 0,
"default_conn_delay": 0.1,
"rejected_code": 503,
"key": "$http_a $http_b",
@@ -410,32 +440,77 @@ GET /t
-=== TEST 11: bypass empty key
+=== TEST 11: request when key is missing
+--- request
+GET /test_concurrency
+--- timeout: 10s
+--- response_body
+200
+503
+503
+503
+503
+--- no_error_log
+[error]
+--- error_log
+The value of the configured key is empty, use client IP instead
+
+
+
+=== TEST 12: update plugin to set invalid key
--- config
location /t {
content_by_lua_block {
- local json = require "t.toolkit.json"
- local http = require "resty.http"
- local uri = "http://127.0.0.1:" .. ngx.var.server_port
- .. "/limit_conn"
- local ress = {}
- for i = 1, 2 do
- local httpc = http.new()
- local res, err = httpc:request_uri(uri)
- if not res then
- ngx.say(err)
- return
- end
- table.insert(ress, res.status)
+ local t = require("lib.test_admin").test
+ local code, body = t('/apisix/admin/routes/1',
+ ngx.HTTP_PUT,
+ [[{
+ "plugins": {
+ "limit-conn": {
+ "conn": 1,
+ "burst": 0,
+ "default_conn_delay": 0.1,
+ "rejected_code": 503,
+ "key": "abcdefgh",
+ "key_type": "var_combination"
+ }
+ },
+ "upstream": {
+ "nodes": {
+ "127.0.0.1:1980": 1
+ },
+ "type": "roundrobin"
+ },
+ "uri": "/limit_conn"
+ }]]
+ )
+
+ if code >= 300 then
+ ngx.status = code
end
- ngx.say(json.encode(ress))
+ ngx.say(body)
}
}
--- request
GET /t
+--- response_body
+passed
--- no_error_log
[error]
+
+
+
+=== TEST 13: request when key is invalid
+--- request
+GET /test_concurrency
+--- timeout: 10s
--- response_body
-[200,200]
+200
+503
+503
+503
+503
+--- no_error_log
+[error]
--- error_log
-bypass the limit conn as the key is empty
+The value of the configured key is empty, use client IP instead
diff --git a/t/plugin/limit-count2.t b/t/plugin/limit-count2.t
index 016fb29..ea4a675 100644
--- a/t/plugin/limit-count2.t
+++ b/t/plugin/limit-count2.t
@@ -279,11 +279,11 @@ GET /t
--- no_error_log
[error]
--- response_body
-[200,200,200,200]
+[200,200,503,503]
-=== TEST 9: update route, set key type to var_combination
+=== TEST 9: update plugin to set key_type to var_combination
--- config
location /t {
content_by_lua_block {
@@ -385,7 +385,7 @@ GET /t
-=== TEST 12: bypass empty key when key_type is var_combination
+=== TEST 12: request when key is missing
--- config
location /t {
content_by_lua_block {
@@ -394,7 +394,81 @@ GET /t
local uri = "http://127.0.0.1:" .. ngx.var.server_port
.. "/hello"
local ress = {}
- for i = 1, 2 do
+ for i = 1, 4 do
+ local httpc = http.new()
+ local res, err = httpc:request_uri(uri)
+ if not res then
+ ngx.say(err)
+ return
+ end
+ table.insert(ress, res.status)
+ end
+ ngx.say(json.encode(ress))
+ }
+ }
+--- request
+GET /t
+--- no_error_log
+[error]
+--- response_body
+[200,200,503,503]
+--- error_log
+The value of the configured key is empty, use client IP instead
+
+
+
+=== TEST 13: update plugin to set invalid key
+--- 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,
+ [[{
+ "plugins": {
+ "limit-count": {
+ "count": 2,
+ "time_window": 60,
+ "rejected_code": 503,
+ "key": "abcdefgh",
+ "key_type": "var_combination"
+ }
+ },
+ "upstream": {
+ "nodes": {
+ "127.0.0.1:1980": 1
+ },
+ "type": "roundrobin"
+ },
+ "uri": "/hello"
+ }]]
+ )
+
+ if code >= 300 then
+ ngx.status = code
+ end
+ ngx.say(body)
+ }
+ }
+--- request
+GET /t
+--- response_body
+passed
+--- no_error_log
+[error]
+
+
+
+=== TEST 14: request when key is invalid
+--- config
+ location /t {
+ content_by_lua_block {
+ local json = require "t.toolkit.json"
+ local http = require "resty.http"
+ local uri = "http://127.0.0.1:" .. ngx.var.server_port
+ .. "/hello"
+ local ress = {}
+ for i = 1, 4 do
local httpc = http.new()
local res, err = httpc:request_uri(uri)
if not res then
@@ -411,6 +485,6 @@ GET /t
--- no_error_log
[error]
--- response_body
-[200,200]
+[200,200,503,503]
--- error_log
-bypass the limit count as the key is empty
+The value of the configured key is empty, use client IP instead
diff --git a/t/plugin/limit-req.t b/t/plugin/limit-req.t
index d3d03e3..d0634cb 100644
--- a/t/plugin/limit-req.t
+++ b/t/plugin/limit-req.t
@@ -696,7 +696,7 @@ GET /hello
--- response_body
hello world
--- error_log
-bypass the limit req as the key is empty
+The value of the configured key is empty, use client IP instead
diff --git a/t/plugin/limit-req2.t b/t/plugin/limit-req2.t
index dc3e4ce..4e37933 100644
--- a/t/plugin/limit-req2.t
+++ b/t/plugin/limit-req2.t
@@ -226,7 +226,7 @@ GET /t
-=== TEST 8: bypass empty key
+=== TEST 8: request when key is missing
--- config
location /t {
content_by_lua_block {
@@ -253,6 +253,81 @@ GET /t
--- no_error_log
[error]
--- response_body
-[200,200]
+[200,503]
+--- error_log
+The value of the configured key is empty, use client IP instead
+
+
+
+=== TEST 9: update plugin to set invalid key
+--- 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,
+ [[{
+ "plugins": {
+ "limit-req": {
+ "rate": 0.1,
+ "burst": 0.1,
+ "rejected_code": 503,
+ "key": "abcdefgh",
+ "key_type": "var_combination"
+ }
+ },
+ "upstream": {
+ "nodes": {
+ "127.0.0.1:1980": 1
+ },
+ "type": "roundrobin"
+ },
+ "uri": "/hello"
+ }]]
+ )
+
+ if code >= 300 then
+ ngx.status = code
+ end
+ ngx.say(body)
+ }
+ }
+--- request
+GET /t
+--- response_body
+passed
+--- no_error_log
+[error]
+
+
+
+=== TEST 10: request when key is invalid
+--- config
+ location /t {
+ content_by_lua_block {
+ local json = require "t.toolkit.json"
+ local http = require "resty.http"
+ local uri = "http://127.0.0.1:" .. ngx.var.server_port
+ .. "/hello"
+
+ local ress = {}
+ for i = 1, 2 do
+ local httpc = http.new()
+ local res, err = httpc:request_uri(uri)
+ if not res then
+ ngx.say(err)
+ return
+ end
+ table.insert(ress, res.status)
+ end
+ ngx.say(json.encode(ress))
+ }
+ }
+--- request
+GET /t
+--- no_error_log
+[error]
+--- response_body
+[200,503]
--- error_log
-bypass the limit req as the key is empty
+The value of the configured key is empty, use client IP instead
diff --git a/t/stream-plugin/limit-conn.t b/t/stream-plugin/limit-conn.t
index c166aac..c6c7c89 100644
--- a/t/stream-plugin/limit-conn.t
+++ b/t/stream-plugin/limit-conn.t
@@ -329,8 +329,8 @@ GET /test_concurrency
200
200
200
-200
-200
+503
+503
--- error_log
-bypass the limit conn as the key is empty
+The value of the configured key is empty, use client IP instead
--- stream_enable