This is an automated email from the ASF dual-hosted git repository.
tokers 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 4462e11 fix(balancer): ensure fallback for chash balancer with
vars_combinations can work (#4779)
4462e11 is described below
commit 4462e11b29d94ba855f976ee36ff704511f21f04
Author: 罗泽轩 <[email protected]>
AuthorDate: Mon Aug 9 19:11:24 2021 +0800
fix(balancer): ensure fallback for chash balancer with vars_combinations
can work (#4779)
Signed-off-by: spacewander <[email protected]>
---
apisix/balancer/chash.lua | 8 ++++++--
apisix/core/utils.lua | 9 ++++++---
t/core/utils.t | 3 ++-
t/node/chash-hashon.t | 44 ++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 58 insertions(+), 6 deletions(-)
diff --git a/apisix/balancer/chash.lua b/apisix/balancer/chash.lua
index 3b260a2..018914a 100644
--- a/apisix/balancer/chash.lua
+++ b/apisix/balancer/chash.lua
@@ -42,11 +42,15 @@ local function fetch_chash_hash_key(ctx, upstream)
elseif hash_on == "cookie" then
chash_key = ctx.var["cookie_" .. key]
elseif hash_on == "vars_combinations" then
- local err
- chash_key, err = core.utils.resolve_var(key, ctx.var);
+ local err, n_resolved
+ chash_key, err, n_resolved = core.utils.resolve_var(key, ctx.var);
if err then
core.log.error("could not resolve vars in ", key, " error: ", err)
end
+
+ if n_resolved == 0 then
+ chash_key = nil
+ end
end
if not chash_key then
diff --git a/apisix/core/utils.lua b/apisix/core/utils.lua
index 1b304f7..7fb1493 100644
--- a/apisix/core/utils.lua
+++ b/apisix/core/utils.lua
@@ -257,6 +257,7 @@ _M.sleep = sleep
local resolve_var
do
local _ctx
+ local n_resolved
local pat = [[(?<!\\)\$\{?(\w+)\}?]]
local function resolve(m)
@@ -264,17 +265,19 @@ do
if v == nil then
return ""
end
+ n_resolved = n_resolved + 1
return tostring(v)
end
function resolve_var(tpl, ctx)
+ n_resolved = 0
if not tpl then
- return tpl
+ return tpl, nil, n_resolved
end
local from = core_str.find(tpl, "$")
if not from then
- return tpl
+ return tpl, nil, n_resolved
end
-- avoid creating temporary function
@@ -285,7 +288,7 @@ do
return nil, err
end
- return res
+ return res, nil, n_resolved
end
end
-- Resolve ngx.var in the given string
diff --git a/t/core/utils.t b/t/core/utils.t
index 3126c09..481a704 100644
--- a/t/core/utils.t
+++ b/t/core/utils.t
@@ -226,7 +226,8 @@ close: 1 nil}
me = "David",
}
for _, case in ipairs(cases) do
- ngx.say("res:", resolve_var(case, ctx))
+ local res = resolve_var(case, ctx)
+ ngx.say("res:", res)
end
}
}
diff --git a/t/node/chash-hashon.t b/t/node/chash-hashon.t
index a9770d8..0b9c161 100644
--- a/t/node/chash-hashon.t
+++ b/t/node/chash-hashon.t
@@ -716,3 +716,47 @@ hash_on: vars_combinations
chash_key: "custom-one-custom-two"
hash_on: vars_combinations
chash_key: "custom-one-custom-two"
+
+
+
+=== TEST 15: hit routes, hash_on custom header combinations
+--- config
+ location /t {
+ content_by_lua_block {
+ local http = require "resty.http"
+ local uri = "http://127.0.0.1:" .. ngx.var.server_port
+ .. "/server_port"
+
+ local ports_count = {}
+ 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
+ ports_count[res.body] = (ports_count[res.body] or 0) + 1
+ end
+
+ local ports_arr = {}
+ for port, count in pairs(ports_count) do
+ table.insert(ports_arr, {port = port, count = count})
+ end
+
+ local function cmd(a, b)
+ return a.port > b.port
+ end
+ table.sort(ports_arr, cmd)
+
+ ngx.say(require("toolkit.json").encode(ports_arr))
+ }
+ }
+--- request
+GET /t
+--- response_body
+[{"count":2,"port":"1980"}]
+--- grep_error_log eval
+qr/chash_key fetch is nil, use default chash_key remote_addr: 127.0.0.1/
+--- grep_error_log_out
+chash_key fetch is nil, use default chash_key remote_addr: 127.0.0.1
+chash_key fetch is nil, use default chash_key remote_addr: 127.0.0.1