From 06f6137b4912b1cb9f640c83e2220c292643766c Mon Sep 17 00:00:00 2001 From: Gallardot Date: Tue, 15 Nov 2022 09:27:52 +0800 Subject: [PATCH] feat(proxy-mirror): support prefix mode (#8261) Fixes https://github.com/apache/apisix/issues/8260 --- apisix/plugins/proxy-mirror.lua | 15 ++++++- docs/en/latest/plugins/proxy-mirror.md | 1 + docs/zh/latest/plugins/proxy-mirror.md | 1 + t/plugin/proxy-mirror.t | 56 ++++++++++++++++++++++++++ 4 files changed, 71 insertions(+), 2 deletions(-) diff --git a/apisix/plugins/proxy-mirror.lua b/apisix/plugins/proxy-mirror.lua index 74ec93fd1837..460f0e4f6a57 100644 --- a/apisix/plugins/proxy-mirror.lua +++ b/apisix/plugins/proxy-mirror.lua @@ -33,6 +33,12 @@ local schema = { type = "string", pattern = [[^/[^?&]+$]], }, + path_concat_mode = { + type = "string", + default = "replace", + enum = {"replace", "prefix"}, + description = "the concatenation mode for custom path" + }, sample_ratio = { type = "number", minimum = 0.00001, @@ -83,8 +89,13 @@ end local function enable_mirror(ctx, conf) - ctx.var.upstream_mirror_uri = resolver_host(conf.host) .. (conf.path or ctx.var.uri) .. - ctx.var.is_args .. (ctx.var.args or '') + if conf.path and conf.path_concat_mode == "prefix" then + ctx.var.upstream_mirror_uri = resolver_host(conf.host) .. conf.path .. ctx.var.uri .. + ctx.var.is_args .. (ctx.var.args or '') + else + ctx.var.upstream_mirror_uri = resolver_host(conf.host) .. (conf.path or ctx.var.uri) .. + ctx.var.is_args .. (ctx.var.args or '') + end if has_mod then apisix_ngx_client.enable_mirror() diff --git a/docs/en/latest/plugins/proxy-mirror.md b/docs/en/latest/plugins/proxy-mirror.md index 3b6f2e46f849..6bd9e11bcec6 100644 --- a/docs/en/latest/plugins/proxy-mirror.md +++ b/docs/en/latest/plugins/proxy-mirror.md @@ -41,6 +41,7 @@ The response returned by the mirror request is ignored. |--------------|--------|----------|---------|--------------|---------------------------------------------------------------------------------------------------------------------------| | host | string | True | | | Address of the mirror service. It needs to contain the scheme but without the path. For example, `http://127.0.0.1:9797`. | | path | string | False | | | Path of the mirror request. If unspecified, current path will be used. | +| path_concat_mode | string | False | replace | ["replace", "prefix"] | If the path of a mirror request is specified, set the concatenation mode of request paths. The `replace` mode will directly use `path` as the path of the mirror request. The `prefix` mode will use the `path` + `source request URI` as the path to the mirror request. | | sample_ratio | number | False | 1 | [0.00001, 1] | Ratio of the requests that will be mirrored. | You can customize the proxy timeouts for the mirrored sub-requests by configuring the `plugin_attr` key in your configuration file (`conf/config.yaml`). This can be used for mirroring traffic to a slow backend. diff --git a/docs/zh/latest/plugins/proxy-mirror.md b/docs/zh/latest/plugins/proxy-mirror.md index 98a3e3db53c8..365368d8b15d 100644 --- a/docs/zh/latest/plugins/proxy-mirror.md +++ b/docs/zh/latest/plugins/proxy-mirror.md @@ -42,6 +42,7 @@ description: 本文介绍了 Apache APISIX proxy-mirror 插件的相关操作, | ---- | ------ | ------ | ------ | ------ | ------------------------------------------------------------------------------------------------------- | | host | string | 是 | | | 指定镜像服务的地址,地址中需要包含 `schema`(`http` 或 `https`),但不能包含 `path` 部分。例如 `http://127.0.0.1:9797`。 | | path | string | 否 | | | 指定镜像请求的路径。如果不指定,则默认会使用当前路径。 | +| path_concat_mode | string | 否 | replace | ["replace", "prefix"] | 当指定镜像请求的路径时,设置请求路径的拼接模式。`replace` 模式将会直接使用 `path` 作为镜像请求的路径。`prefix` 模式将会使用 `path` + `来源请求 URI` 作为镜像请求的路径。 | | sample_ratio | number | 否 | 1 | [0.00001, 1] | 镜像请求的采样率。当设置为 `1` 时为全采样。 | ## 启用插件 diff --git a/t/plugin/proxy-mirror.t b/t/plugin/proxy-mirror.t index eb5db12eb18f..34b531488236 100644 --- a/t/plugin/proxy-mirror.t +++ b/t/plugin/proxy-mirror.t @@ -786,3 +786,59 @@ GET /hello hello world --- error_log dns resolver resolves domain: not-find-domian.notfind error: + + + +=== TEST 27: custom path with prefix path_concat_mode +--- 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", + "path_concat_mode": "prefix" + } + }, + "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 28: hit route with prefix path_concat_mode +--- request +GET /hello +--- response_body +hello world +--- error_log +uri: /a/hello, + + + +=== TEST 29: hit route with args and prefix path_concat_mode +--- request +GET /hello?a=1 +--- response_body +hello world +--- error_log +uri: /a/hello?a=1