From e3bdf277f7539cadf95e12859981e43f82aa8469 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=BD=97=E6=B3=BD=E8=BD=A9?= Date: Mon, 21 Nov 2022 14:57:01 +0800 Subject: [PATCH] feat: proxy-mirror plugin resolve host (#7861) (#8356) Co-authored-by: Strangevy Fixes https://github.com/apache/apisix/issues/8351 --- apisix/plugins/proxy-mirror.lua | 27 +++++++++- t/plugin/proxy-mirror.t | 90 +++++++++++++++++++++++++++++++++ 2 files changed, 115 insertions(+), 2 deletions(-) diff --git a/apisix/plugins/proxy-mirror.lua b/apisix/plugins/proxy-mirror.lua index fcbfba036b09..74ec93fd1837 100644 --- a/apisix/plugins/proxy-mirror.lua +++ b/apisix/plugins/proxy-mirror.lua @@ -15,6 +15,8 @@ -- limitations under the License. -- local core = require("apisix.core") +local url = require("net.url") + local math_random = math.random local has_mod, apisix_ngx_client = pcall(require, "resty.apisix.client") @@ -59,9 +61,30 @@ function _M.check_schema(conf) end +local function resolver_host(prop_host) + local url_decoded = url.parse(prop_host) + local decoded_host = url_decoded.host + if not core.utils.parse_ipv4(decoded_host) and not core.utils.parse_ipv6(decoded_host) then + local ip, err = core.resolver.parse_domain(decoded_host) + + if not ip then + core.log.error("dns resolver resolves domain: ", decoded_host," error: ", err, + " will continue to use the host: ", decoded_host) + return prop_host + end + + local host = url_decoded.scheme .. '://' .. ip .. + (url_decoded.port and ':' .. url_decoded.port or '') + core.log.info(prop_host, " is resolved to: ", host) + return host + end + return prop_host +end + + 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 '') + ctx.var.upstream_mirror_uri = resolver_host(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() diff --git a/t/plugin/proxy-mirror.t b/t/plugin/proxy-mirror.t index a95c238d9f88..eb5db12eb18f 100644 --- a/t/plugin/proxy-mirror.t +++ b/t/plugin/proxy-mirror.t @@ -696,3 +696,93 @@ passed passed passed passed + + + +=== TEST 23: set mirror requests host to domain +--- 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://httpbin.org", + "path": "/get" + } + }, + "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 24: hit route resolver domain +--- request +GET /hello +--- response_body +hello world +--- error_log_like eval +qr/http:\/\/httpbin\.org is resolved to: http:\/\/((2(5[0-5]|[0-4]\d))|[0-1]?\d{1,2})(\.((2(5[0-5]|[0-4]\d))|[0-1]?\d{1,2})){3}/ + + + +=== TEST 25: set as a domain name that cannot be found. +--- 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://not-find-domian.notfind", + "path": "/get" + } + }, + "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 26: hit route resolver error domain +--- request +GET /hello +--- response_body +hello world +--- error_log +dns resolver resolves domain: not-find-domian.notfind error: