I'm setting nginx as a load balance for web applications and in one of them we have to filter the last character of a document field to decide where to send that request. So I decided to set a flag "target" on the nginx location block to load/change it inside a lua script block with values 1 or 2 so I can use an IF inside the location block to proxy_pass to different upstreams.
location /payload-test { set $target '0'; content_by_lua_block { ngx.req.read_body() local body = ngx.req.get_body_data() if body then local document = string.sub(body, string.find(body, "documentNumber") + 16, string.find(body, "documentNumber")+30) ngx.print(document) local documentNum = string.match(document, "%d+") ngx.print(documentNum) local lastDigit = string.sub(documentNum, string.len(documentNum)) if math.fmod(lastDigit, 2) == 0 then ngx.var.target = "1" else ngx.var.target = "2" end ngx.print(ngx.var.target) end } #updated block if ($target = "1") { proxy_pass http://port_23301; } if ($target = "2") { proxy_pass http://port_23501; } } The code itself works fine on lua, when I print the data, it shows the right info on Postman. The problem is that when I try to return the value of $target, nginx returns only the initial value "0" and not 1 or 2, set by lua block.
After the sugestions, i split the code and created an access_by_lua_block, to be able to get the payload, extract the document and store it on ngx.ctx.target variable:
access_by_lua_block { ngx.req.read_body() local body = ngx.req.get_body_data() if body then local document = string.sub(body, string.find(body, "documentNumber") + 16, string.find(body, "documentNumber")+30) local documentNum = string.match(document, "%d+") local lastDigit = string.sub(documentNum, string.len(documentNum)) if math.fmod(lastDigit, 2) == 0 then ngx.ctx.target = "1" else ngx.ctx.target = "2" end end } Then, on the upstream, i created a balancer_by_lua_block?
balancer_by_lua_block { local balancer = require('ngx.balancer') ngx.log(1,"Target Variable: ",ngx.ctx.target) if ngx.ctx.target == "1" then local ok, err = balancer.set_current_peer("192.168.72.133", "23301") ngx.log(2,"STATUS: ",ok) ngx.log(2,"ERROR: ",err) if not ok then ok, err = balancer.set_current_peer("192.168.72.133", "23502") end else local ok, err = balancer.set_current_peer("192.168.72.133", "23502") ngx.log(2,"STATUS: ",ok) ngx.log(2,"ERROR: ",err) if not ok then ok, err = balancer.set_current_peer("192.168.72.133", "23301") end end } The nginx log says:
2024/10/29 09:58:30 [emerg] 3517796#3517796: *30 [lua] p_consult.conf:4):8: Target Variable: 2 2024/10/29 09:58:30 [alert] 3517796#3517796: *30 [lua] p_consult.conf:4):26: STATUS: true 2024/10/29 09:58:30 [alert] 3517796#3517796: *30 [lua] p_consult.conf:4):27: ERRO: nil 2024/10/29 09:58:30 [error] 3517796#3517796: *30 connect() failed (111: Connection refused) while connecting to upstream, client: 192.168.72.199, server: 192.168.72.190 