You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@apisix.apache.org by sp...@apache.org on 2021/11/04 01:48:11 UTC

[apisix] branch master updated: feat(limit-conn): support multiple variables as key in L4 (#5413)

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 4dafab5  feat(limit-conn): support multiple variables as key in L4 (#5413)
4dafab5 is described below

commit 4dafab5afa3293b3d72007517246e01da385f8ef
Author: 罗泽轩 <sp...@gmail.com>
AuthorDate: Thu Nov 4 09:48:02 2021 +0800

    feat(limit-conn): support multiple variables as key in L4 (#5413)
---
 apisix/stream/plugins/limit-conn.lua |   7 +-
 docs/en/latest/plugins/limit-conn.md |   4 -
 docs/en/latest/plugins/limit-req.md  |   2 -
 docs/zh/latest/plugins/limit-conn.md |   4 -
 docs/zh/latest/plugins/limit-req.md  |   2 -
 t/admin/plugins.t                    |   2 +-
 t/stream-plugin/limit-conn.t         | 145 +++++++++++++++++++++++++++++++++++
 7 files changed, 150 insertions(+), 16 deletions(-)

diff --git a/apisix/stream/plugins/limit-conn.lua b/apisix/stream/plugins/limit-conn.lua
index d2bd25e..1beb7c7 100644
--- a/apisix/stream/plugins/limit-conn.lua
+++ b/apisix/stream/plugins/limit-conn.lua
@@ -26,9 +26,10 @@ local schema = {
         burst = {type = "integer",  minimum = 0},
         default_conn_delay = {type = "number", exclusiveMinimum = 0},
         only_use_default_delay = {type = "boolean", default = false},
-        key = {
-            type = "string",
-            enum = {"remote_addr", "server_addr"}
+        key = {type = "string"},
+        key_type = {type = "string",
+            enum = {"var", "var_combination"},
+            default = "var",
         },
     },
     required = {"conn", "burst", "default_conn_delay", "key"}
diff --git a/docs/en/latest/plugins/limit-conn.md b/docs/en/latest/plugins/limit-conn.md
index 1af26f3..4790039 100644
--- a/docs/en/latest/plugins/limit-conn.md
+++ b/docs/en/latest/plugins/limit-conn.md
@@ -47,10 +47,6 @@ Limiting request concurrency plugin.
 | 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. |
 
-**Key can be customized by the user, only need to modify a line of code of the plug-in to complete. It is a security consideration that is not open in the plugin.**
-
-When used in the stream proxy, only `remote_addr` and `server_addr` can be used as key. And `rejected_code` is meaningless.
-
 ## How To Enable
 
 Here's an example, enable the limit-conn plugin on the specified route:
diff --git a/docs/en/latest/plugins/limit-req.md b/docs/en/latest/plugins/limit-req.md
index 500ed8d..0c16c76 100644
--- a/docs/en/latest/plugins/limit-req.md
+++ b/docs/en/latest/plugins/limit-req.md
@@ -47,8 +47,6 @@ limit request rate using the "leaky bucket" method.
 | nodelay       | boolean | optional    | false   |                                                                          | If nodelay flag is true, bursted requests will not get delayed  |
 | allow_degradation              | boolean  | optional                                | false       |                                                                     | Whether to enable plugin degradation when the limit-req function is temporarily unavailable. Allow requests to continue when the value is set to true, default false. |
 
-**Key can be customized by the user, only need to modify a line of code of the plug-in to complete.  It is a security consideration that is not open in the plugin.**
-
 ## Example
 
 ### How to enable on the `route` or `service`
diff --git a/docs/zh/latest/plugins/limit-conn.md b/docs/zh/latest/plugins/limit-conn.md
index 0438229..ca3a381 100644
--- a/docs/zh/latest/plugins/limit-conn.md
+++ b/docs/zh/latest/plugins/limit-conn.md
@@ -37,10 +37,6 @@ title: limit-conn
 | rejected_msg       | string | 可选                                |            | 非空                                          | 当请求超过 `conn` + `burst` 这个阈值时,返回的响应体。                                                                                                                                                                                                             |
 | allow_degradation              | boolean  | 可选                                | false       |                                                                     | 当插件功能临时不可用时是否允许请求继续。当值设置为 true 时则自动允许请求继续,默认值是 false。|
 
-**注:key 是可以被用户自定义的,只需要修改插件的一行代码即可完成。并没有在插件中放开是处于安全的考虑。**
-
-在 stream 代理中使用该插件时,只有 `remote_addr` 和 `server_addr` 可以被用作 key。另外设置 `rejected_code` 毫无意义。
-
 #### 如何启用
 
 下面是一个示例,在指定的 route 上开启了 limit-conn 插件:
diff --git a/docs/zh/latest/plugins/limit-req.md b/docs/zh/latest/plugins/limit-req.md
index e1ba284..d0e8dd9 100644
--- a/docs/zh/latest/plugins/limit-req.md
+++ b/docs/zh/latest/plugins/limit-req.md
@@ -47,8 +47,6 @@ title: limit-req
 | nodelay       | boolean | 可选   | false  |                                                                         | 如果 nodelay 为 true, 请求速率超过 `rate` 但没有超过 (`rate` + `brust`)的请求不会加上延迟, 如果是 false,则会加上延迟。 |
 | allow_degradation              | boolean  | 可选                                | false       |                                                                     | 当限速插件功能临时不可用时是否允许请求继续。当值设置为 true 时则自动允许请求继续,默认值是 false。|
 
-**key 是可以被用户自定义的,只需要修改插件的一行代码即可完成。并没有在插件中放开是处于安全的考虑。**
-
 ## 示例
 
 ### 如何在`route`或`service`上使用
diff --git a/t/admin/plugins.t b/t/admin/plugins.t
index b5196dd..2c67ef3 100644
--- a/t/admin/plugins.t
+++ b/t/admin/plugins.t
@@ -298,7 +298,7 @@ qr/\{"properties":\{"password":\{"type":"string"\},"username":\{"type":"string"\
         }
     }
 --- response_body
-{"priority":1003,"schema":{"$comment":"this is a mark for our injected plugin schema","properties":{"burst":{"minimum":0,"type":"integer"},"conn":{"exclusiveMinimum":0,"type":"integer"},"default_conn_delay":{"exclusiveMinimum":0,"type":"number"},"disable":{"type":"boolean"},"key":{"enum":["remote_addr","server_addr"],"type":"string"},"only_use_default_delay":{"default":false,"type":"boolean"}},"required":["conn","burst","default_conn_delay","key"],"type":"object"},"version":0.1}
+{"priority":1003,"schema":{"$comment":"this is a mark for our injected plugin schema","properties":{"burst":{"minimum":0,"type":"integer"},"conn":{"exclusiveMinimum":0,"type":"integer"},"default_conn_delay":{"exclusiveMinimum":0,"type":"number"},"disable":{"type":"boolean"},"key":{"type":"string"},"key_type":{"default":"var","enum":["var","var_combination"],"type":"string"},"only_use_default_delay":{"default":false,"type":"boolean"}},"required":["conn","burst","default_conn_delay","key"] [...]
 --- no_error_log
 [error]
 
diff --git a/t/stream-plugin/limit-conn.t b/t/stream-plugin/limit-conn.t
index 95e0b82..c166aac 100644
--- a/t/stream-plugin/limit-conn.t
+++ b/t/stream-plugin/limit-conn.t
@@ -189,3 +189,148 @@ GET /test_concurrency
 --- error_log
 Connection reset by peer
 --- stream_enable
+
+
+
+=== TEST 5: var combination
+--- config
+    location /t {
+        content_by_lua_block {
+            local t = require("lib.test_admin").test
+            local code, body = t('/apisix/admin/stream_routes/1',
+                 ngx.HTTP_PUT,
+                 [[{
+                    "plugins": {
+                        "limit-conn": {
+                            "conn": 2,
+                            "burst": 1,
+                            "default_conn_delay": 0.1,
+                            "key": "$remote_addr $server_addr",
+                            "key_type": "var_combination"
+                        }
+                    },
+                    "upstream_id": "1"
+                }]]
+                )
+
+            if code >= 300 then
+                ngx.status = code
+            end
+            ngx.say(body)
+        }
+    }
+--- request
+GET /t
+--- response_body
+passed
+
+
+
+=== TEST 6: exceeding the burst
+--- request
+GET /test_concurrency
+--- response_body
+200
+200
+200
+503
+503
+--- error_log
+Connection reset by peer
+--- stream_enable
+
+
+
+=== TEST 7: var combination (not exceed the burst)
+--- config
+    location /t {
+        content_by_lua_block {
+            local t = require("lib.test_admin").test
+            local code, body = t('/apisix/admin/stream_routes/1',
+                 ngx.HTTP_PUT,
+                 [[{
+                    "plugins": {
+                        "limit-conn": {
+                            "conn": 2,
+                            "burst": 1,
+                            "default_conn_delay": 0.1,
+                            "key": "$remote_port $server_addr",
+                            "key_type": "var_combination"
+                        }
+                    },
+                    "upstream_id": "1"
+                }]]
+                )
+
+            if code >= 300 then
+                ngx.status = code
+            end
+            ngx.say(body)
+        }
+    }
+--- request
+GET /t
+--- response_body
+passed
+
+
+
+=== TEST 8: hit
+--- request
+GET /test_concurrency
+--- response_body
+200
+200
+200
+200
+200
+--- stream_enable
+
+
+
+=== TEST 9: bypass empty key
+--- config
+    location /t {
+        content_by_lua_block {
+            local t = require("lib.test_admin").test
+            local code, body = t('/apisix/admin/stream_routes/1',
+                 ngx.HTTP_PUT,
+                 [[{
+                    "plugins": {
+                        "limit-conn": {
+                            "conn": 2,
+                            "burst": 1,
+                            "default_conn_delay": 0.1,
+                            "key": "$proxy_protocol_addr $proxy_protocol_port",
+                            "key_type": "var_combination"
+                        }
+                    },
+                    "upstream_id": "1"
+                }]]
+                )
+
+            if code >= 300 then
+                ngx.status = code
+            end
+            ngx.say(body)
+        }
+    }
+--- request
+GET /t
+--- response_body
+passed
+
+
+
+=== TEST 10: hit
+--- request
+GET /test_concurrency
+--- response_body
+200
+200
+200
+200
+200
+--- error_log
+bypass the limit conn as the key is empty
+--- stream_enable