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 2022/03/06 10:59:47 UTC

[apisix] branch master updated: feat(proxy-mirror): support custom path (#6506)

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 0aeba95  feat(proxy-mirror): support custom path (#6506)
0aeba95 is described below

commit 0aeba95826e240b88aa8bfeac0a0e7c86ce76f90
Author: 罗泽轩 <sp...@gmail.com>
AuthorDate: Sun Mar 6 18:59:39 2022 +0800

    feat(proxy-mirror): support custom path (#6506)
---
 apisix/cli/ngx_tpl.lua                 |   6 +-
 apisix/core/ctx.lua                    |   2 +-
 apisix/plugins/proxy-mirror.lua        |  13 +++--
 docs/en/latest/plugins/proxy-mirror.md |   1 +
 docs/zh/latest/plugins/proxy-mirror.md |   3 +-
 t/APISIX.pm                            |   6 +-
 t/plugin/proxy-mirror.t                | 100 +++++++++++++++++++++++++++++++++
 7 files changed, 119 insertions(+), 12 deletions(-)

diff --git a/apisix/cli/ngx_tpl.lua b/apisix/cli/ngx_tpl.lua
index 89fc3fd..186884f 100644
--- a/apisix/cli/ngx_tpl.lua
+++ b/apisix/cli/ngx_tpl.lua
@@ -609,7 +609,7 @@ http {
         {% end %}
 
         location / {
-            set $upstream_mirror_host        '';
+            set $upstream_mirror_uri         '';
             set $upstream_upgrade            '';
             set $upstream_connection         '';
 
@@ -759,14 +759,14 @@ http {
             internal;
 
             {% if not use_apisix_openresty then %}
-            if ($upstream_mirror_host = "") {
+            if ($upstream_mirror_uri = "") {
                 return 200;
             }
             {% end %}
 
             proxy_http_version 1.1;
             proxy_set_header Host $upstream_host;
-            proxy_pass $upstream_mirror_host$request_uri;
+            proxy_pass $upstream_mirror_uri;
         }
         {% end %}
 
diff --git a/apisix/core/ctx.lua b/apisix/core/ctx.lua
index edd3f37..83b9f9a 100644
--- a/apisix/core/ctx.lua
+++ b/apisix/core/ctx.lua
@@ -190,7 +190,7 @@ do
         upstream_connection        = true,
         upstream_uri               = true,
 
-        upstream_mirror_host       = true,
+        upstream_mirror_uri        = true,
 
         upstream_cache_zone        = true,
         upstream_cache_zone_info   = true,
diff --git a/apisix/plugins/proxy-mirror.lua b/apisix/plugins/proxy-mirror.lua
index df621fd..c1c5e9e 100644
--- a/apisix/plugins/proxy-mirror.lua
+++ b/apisix/plugins/proxy-mirror.lua
@@ -28,6 +28,10 @@ local schema = {
             pattern = [[^http(s)?:\/\/[a-zA-Z0-9][-a-zA-Z0-9]{0,62}]]
                       .. [[(\.[a-zA-Z0-9][-a-zA-Z0-9]{0,62})+(:[0-9]{1,5})?$]],
         },
+        path = {
+            type = "string",
+            pattern = [[^/[^?&]+$]],
+        },
         sample_ratio = {
             type = "number",
             minimum = 0.00001,
@@ -56,8 +60,9 @@ function _M.check_schema(conf)
 end
 
 
-local function enable_mirror(ctx, host)
-    ctx.var.upstream_mirror_host = host
+local function enable_mirror(ctx, conf)
+    ctx.var.upstream_mirror_uri =
+        conf.host .. (conf.path or ctx.var.uri) .. ctx.var.is_args .. (ctx.var.args or '')
 
     if has_mod then
         apisix_ngx_client.enable_mirror()
@@ -69,13 +74,13 @@ function _M.rewrite(conf, ctx)
     core.log.info("proxy mirror plugin rewrite phase, conf: ", core.json.delay_encode(conf))
 
     if conf.sample_ratio == 1 then
-        enable_mirror(ctx, conf.host)
+        enable_mirror(ctx, conf)
     else
         local val = math_random()
         core.log.info("mirror request sample_ratio conf: ", conf.sample_ratio,
                                 ", random value: ", val)
         if val < conf.sample_ratio then
-            enable_mirror(ctx, conf.host)
+            enable_mirror(ctx, conf)
         end
     end
 
diff --git a/docs/en/latest/plugins/proxy-mirror.md b/docs/en/latest/plugins/proxy-mirror.md
index 0271e14..86abff1 100644
--- a/docs/en/latest/plugins/proxy-mirror.md
+++ b/docs/en/latest/plugins/proxy-mirror.md
@@ -30,6 +30,7 @@ The proxy-mirror plugin, which provides the ability to mirror client requests.
 | Name | Type   | Requirement | Default | Valid | Description                                                                                                                 |
 | ---- | ------ | ----------- | ------- | ----- | --------------------------------------------------------------------------------------------------------------------------- |
 | host | string | required    |         |       | Specify a mirror service address, e.g. http://127.0.0.1:9797 (address needs to contain scheme: http or https, and without the path part) |
+| path | string | optional    |         |       | Specify the mirror request's path part. Without it the current path will be used. |
 | sample_ratio | number | optional    | 1       |  [0.00001, 1]     | the sample ratio that requests will be mirrored. |
 
 ### Examples
diff --git a/docs/zh/latest/plugins/proxy-mirror.md b/docs/zh/latest/plugins/proxy-mirror.md
index 5d64b7d..cc1a29a 100644
--- a/docs/zh/latest/plugins/proxy-mirror.md
+++ b/docs/zh/latest/plugins/proxy-mirror.md
@@ -29,7 +29,8 @@ title: proxy-mirror
 
 | 名称 | 类型   | 必选项 | 默认值 | 有效值 | 描述                                                                                                    |
 | ---- | ------ | ------ | ------ | ------ | ------------------------------------------------------------------------------------------------------- |
-| host | string | 必须   |        |        | 指定镜像服务地址,例如:http://127.0.0.1:9797(地址中需要包含 schema :http或https,不能包含 URI 部分) |
+| host | string | 必须   |        |        | 指定镜像服务地址,例如:http://127.0.0.1:9797(地址中需要包含 schema :http或https,不能包含 path 部分) |
+| path | string | 可选   |        |        | 指定镜像请求的路径。如不指定,当前路径将被使用。 |
 | sample_ratio | number | 可选    | 1       |  [0.00001, 1]     | 镜像请求采样率 |
 
 ### 示例
diff --git a/t/APISIX.pm b/t/APISIX.pm
index 69d9cb8..bcd8daf 100644
--- a/t/APISIX.pm
+++ b/t/APISIX.pm
@@ -708,7 +708,7 @@ _EOC_
         }
 
         location / {
-            set \$upstream_mirror_host        '';
+            set \$upstream_mirror_uri         '';
             set \$upstream_upgrade            '';
             set \$upstream_connection         '';
 
@@ -794,7 +794,7 @@ _EOC_
 
     if ($version !~ m/\/apisix-nginx-module/) {
         $config .= <<_EOC_;
-            if (\$upstream_mirror_host = "") {
+            if (\$upstream_mirror_uri = "") {
                 return 200;
             }
 _EOC_
@@ -803,7 +803,7 @@ _EOC_
     $config .= <<_EOC_;
             proxy_http_version 1.1;
             proxy_set_header Host \$upstream_host;
-            proxy_pass \$upstream_mirror_host\$request_uri;
+            proxy_pass \$upstream_mirror_uri;
         }
 _EOC_
 
diff --git a/t/plugin/proxy-mirror.t b/t/plugin/proxy-mirror.t
index 2c0e2e8..65ed9f6 100644
--- a/t/plugin/proxy-mirror.t
+++ b/t/plugin/proxy-mirror.t
@@ -602,3 +602,103 @@ GET /t
 [error]
 --- error_log_like eval
 qr/(uri: \/hello\?sample_ratio=0\.5){75,125}/
+
+
+
+=== TEST 18: custom path
+--- 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": {
+                            "proxy-mirror": {
+                               "host": "http://127.0.0.1:1986",
+                               "path": "/a"
+                            }
+                        },
+                        "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
+
+
+
+=== TEST 19: hit route
+--- request
+GET /hello
+--- response_body
+hello world
+--- error_log
+uri: /a,
+
+
+
+=== TEST 20: hit route with args
+--- request
+GET /hello?a=1
+--- response_body
+hello world
+--- error_log
+uri: /a?a=1
+
+
+
+=== TEST 21: sanity check (path)
+--- config
+       location /t {
+           content_by_lua_block {
+               local t = require("lib.test_admin").test
+               for _, p in ipairs({
+                    "a",
+                    "/a?a=c",
+               }) do
+                    local code, body = t('/apisix/admin/routes/1',
+                        ngx.HTTP_PUT,
+                        [[{
+                            "plugins": {
+                                "proxy-mirror": {
+                                    "host": "http://127.0.0.1:1999",
+                                    "path": "]] .. p .. [["
+                                }
+                            },
+                            "upstream": {
+                                "nodes": {
+                                    "127.0.0.1:1980": 1
+                                },
+                                "type": "roundrobin"
+                            },
+                            "uri": "/hello"
+                        }]]
+                        )
+                    ngx.log(ngx.WARN, body)
+                end
+            }
+       }
+--- request
+GET /t
+--- grep_error_log eval
+qr/property \\"path\\" validation failed: failed to match pattern/
+--- grep_error_log_out
+property \"path\" validation failed: failed to match pattern
+property \"path\" validation failed: failed to match pattern
+--- no_error_log
+[error]