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

Reply via email to