diff --git a/lualib/resty/kong/upstream.lua b/lualib/resty/kong/upstream.lua index 91fab174..bb3bd071 100644 --- a/lualib/resty/kong/upstream.lua +++ b/lualib/resty/kong/upstream.lua @@ -20,7 +20,7 @@ base.allows_subsystem("http") ffi.cdef([[ int -ngx_http_lua_ffi_set_upstream_next(ngx_http_request_t *r, uint next_upstream, char **err); +ngx_http_lua_ffi_set_upstream_next(ngx_http_request_t *r, uint32_t next_upstream, char **err); ]]) local type = type @@ -58,15 +58,20 @@ function _M.set_upstream_next(...) error("no request found") end - local next_upstream_table = { ... } + local arg_table = { ... } local next_upstream = 0 for i = 1, nargs do - local v = next_upstream_table[i] - if type(v) ~= "number" then + local v = arg_table[i] + if type(v) ~= "string" then error("argument #" .. i .. " is not a valid argument") end - next_upstream = bit.bor(next_upstream, v) + local next_upstream_value = next_upstream_table[v] + if not next_upstream_value then + error("argument #" .. i .. " is not a valid argument") + end + + next_upstream = bit.bor(next_upstream, next_upstream_value) end local err = ffi.new("char *[1]") diff --git a/t/013-upstream.t b/t/013-upstream.t new file mode 100644 index 00000000..ee6593c1 --- /dev/null +++ b/t/013-upstream.t @@ -0,0 +1,240 @@ +# vim:set ft= ts=4 sw=4 et fdm=marker: + +use Test::Nginx::Socket::Lua; + +#worker_connections(1014); +#master_on(); +#workers(2); +log_level('info'); + +repeat_each(2); +#repeat_each(1); + +plan tests => repeat_each() * (blocks() * 2) + 8; + +#no_diff(); +#no_long_string(); +run_tests(); + +__DATA__ +=== TEST 1: default behavior +--- http_config + upstream balancer { + server 127.0.0.1; + balancer_by_lua_block { + local balancer = require "ngx.balancer" + local host = "127.0.0.1" + local port + ngx.ctx.count = (ngx.ctx.count or 0) + 1 + if ngx.ctx.count == 1 then + port = $TEST_NGINX_RAND_PORT_1 + elseif ngx.ctx.count == 2 then + port = $TEST_NGINX_RAND_PORT_2 + elseif ngx.ctx.count == 3 then + port = $TEST_NGINX_RAND_PORT_3 + else + port = $TEST_NGINX_RAND_PORT_4 + end + ngx.log(ngx.ERR, "balancer_by_lua_block: host: ", host, ", port: ", port, ", count: ", ngx.ctx.count) + local ok, err = balancer.set_current_peer(host, port) + if not ok then + ngx.log(ngx.ERR, "failed to set the current peer: ", err) + return ngx.exit(500) + end + balancer.set_more_tries(4) + } + } + server { + # this is the real entry point + listen $TEST_NGINX_RAND_PORT_1; + location / { + content_by_lua_block{ + ngx.exit(404) + } + } + } + server { + # this is the real entry point + listen $TEST_NGINX_RAND_PORT_2; + location / { + content_by_lua_block{ + ngx.exit(404) + } + } + } + server { + # this is the real entry point + listen $TEST_NGINX_RAND_PORT_3; + location / { + content_by_lua_block{ + ngx.exit(404) + } + } + } + server { + # this is the real entry point + listen $TEST_NGINX_RAND_PORT_4; + location / { + content_by_lua_block{ + ngx.print("this is backend peer $TEST_NGINX_RAND_PORT_4") + } + } + } +--- config + location =/balancer { + proxy_pass http://balancer; + } +--- pipelined_requests eval +["GET /balancer", "GET /balancer"] +--- error_code eval +[404, 404] + +=== TEST 2: proxy_next_upstream directive behavior +--- http_config + upstream balancer { + server 127.0.0.1; + balancer_by_lua_block { + local balancer = require "ngx.balancer" + local host = "127.0.0.1" + local port + ngx.ctx.count = (ngx.ctx.count or 0) + 1 + if ngx.ctx.count == 1 then + port = $TEST_NGINX_RAND_PORT_1 + elseif ngx.ctx.count == 2 then + port = $TEST_NGINX_RAND_PORT_2 + elseif ngx.ctx.count == 3 then + port = $TEST_NGINX_RAND_PORT_3 + else + port = $TEST_NGINX_RAND_PORT_4 + end + ngx.log(ngx.ERR, "balancer_by_lua_block: host: ", host, ", port: ", port, ", count: ", ngx.ctx.count) + local ok, err = balancer.set_current_peer(host, port) + if not ok then + ngx.log(ngx.ERR, "failed to set the current peer: ", err) + return ngx.exit(500) + end + balancer.set_more_tries(4) + } + } + server { + # this is the real entry point + listen $TEST_NGINX_RAND_PORT_1; + location / { + content_by_lua_block{ + ngx.exit(404) + } + } + } + server { + # this is the real entry point + listen $TEST_NGINX_RAND_PORT_2; + location / { + content_by_lua_block{ + ngx.exit(404) + } + } + } + server { + # this is the real entry point + listen $TEST_NGINX_RAND_PORT_3; + location / { + content_by_lua_block{ + ngx.exit(404) + } + } + } + server { + # this is the real entry point + listen $TEST_NGINX_RAND_PORT_4; + location / { + content_by_lua_block{ + ngx.print("this is backend peer $TEST_NGINX_RAND_PORT_4") + } + } + } +--- config + proxy_next_upstream error timeout http_404; + location =/balancer { + proxy_pass http://balancer; + } +--- pipelined_requests eval +["GET /balancer", "GET /balancer"] +--- response_body eval +["this is backend peer \$TEST_NGINX_RAND_PORT_4", "this is backend peer \$TEST_NGINX_RAND_PORT_4"] + +=== TEST 3: lua resty.kong.upstream.set_upstream_next() behavior +--- timeout: 1000 +--- http_config + upstream balancer { + server 127.0.0.1; + balancer_by_lua_block { + local balancer = require "ngx.balancer" + local host = "127.0.0.1" + local port + ngx.ctx.count = (ngx.ctx.count or 0) + 1 + if ngx.ctx.count == 1 then + port = $TEST_NGINX_RAND_PORT_1 + elseif ngx.ctx.count == 2 then + port = $TEST_NGINX_RAND_PORT_2 + elseif ngx.ctx.count == 3 then + port = $TEST_NGINX_RAND_PORT_3 + else + port = $TEST_NGINX_RAND_PORT_4 + end + ngx.log(ngx.ERR, "balancer_by_lua_block: host: ", host, ", port: ", port, ", count: ", ngx.ctx.count) + local ok, err = balancer.set_current_peer(host, port) + if not ok then + ngx.log(ngx.ERR, "failed to set the current peer: ", err) + return ngx.exit(500) + end + balancer.set_more_tries(4) + } + } + server { + # this is the real entry point + listen $TEST_NGINX_RAND_PORT_1; + location / { + content_by_lua_block{ + ngx.exit(404) + } + } + } + server { + # this is the real entry point + listen $TEST_NGINX_RAND_PORT_2; + location / { + content_by_lua_block{ + ngx.exit(404) + } + } + } + server { + # this is the real entry point + listen $TEST_NGINX_RAND_PORT_3; + location / { + content_by_lua_block{ + ngx.exit(404) + } + } + } + server { + # this is the real entry point + listen $TEST_NGINX_RAND_PORT_4; + location / { + content_by_lua_block{ + ngx.print("this is backend peer $TEST_NGINX_RAND_PORT_4") + } + } + } +--- config + access_by_lua_block { + local upstream = require "resty.kong.upstream" + upstream.set_upstream_next("error", "timeout", "http_404") + } + location =/balancer { + proxy_pass http://balancer; + } +--- pipelined_requests eval +["GET /balancer", "GET /balancer"] +--- response_body eval +["this is backend peer \$TEST_NGINX_RAND_PORT_4", "this is backend peer \$TEST_NGINX_RAND_PORT_4"]