Have backend follow multiple redirects

I am trying to improve the user experience by having haproxy handle multiple redirects.

haproxy 2.8
lua 5.6

The initial request is identified by a leading A in the path, and if it starts with then, I want it to follow all the redirects starting with the URL I pull from a JSON service. Haproxy should still proxy normal requests that don’t match the /A pattern to the backend loadbalancer.

The lua script loops through each request and if it’s a 301/302 then it follows that request until it’s not or it hits the max redirects limit. Then it should send the final response as the response to the initial request.

global
    log         127.0.0.1 local2
    log         127.0.0.1 local0
    log         127.0.0.1 local1 notice
    chroot      /var/lib/haproxy
    maxconn     4000
    lua-load    /etc/haproxy/follow_redirects.lua
    daemon

defaults
    mode                    http
    option                  httplog
    log                     global
    option                  dontlognull
    option 		            http-server-close
    option                  redispatch
    retries                 3
    timeout http-request    10s
    timeout queue           1m
    timeout connect         10s
    timeout client          1m
    timeout server          1m
    timeout http-keep-alive 10s
    timeout check           10s
    maxconn                 3000

frontend http_front
    bind *:80
    bind *:443 ssl crt /etc/haproxy/ssl

    # Use the Lua script for initial requests starting with /A
    http-request lua.follow_redirects if { path_beg /A }
    default_backend web_backend

backend web_backend
    option forwardfor

    server webserver loadbalancer.com:443 ssl verify none

Then in the lua script I have this.

http = require("http")

core.register_service("follow_redirects", "http", function(applet)
    local max_redirects = 2 -- You can change this to your preferred maximum number of redirects
    local user_id = applet.path:sub(3)  -- assuming the path starts with '/A'
    local url = "http://backendsystem.com/find_user?user_id=" .. user_id
    local headers = {}
    local count = 0

    local response, status_code, response_headers, status_line = http.request {
        url = url,
        sink = ltn12.sink.table(response.body),
    }
 
    while count < max_redirects do
        -- Sending the request
        local response, err = http.get({url = url, headers = headers})
        if not response then
            applet:set_status(500)
            applet:add_header("Content-Type", "text/plain")
            applet:start_response()
            applet:send(err)
            return
        end

        -- If the response is not a redirect, break the loop
        if response.status ~= 301 and response.status ~= 302 then
            break
        end

        -- Updating URL for the next request
        url = response.headers["location"]
        count = count + 1
    end

    -- Responding with the final fetched content or redirect
    applet:set_status(response.status)

    for k, v in pairs(response.headers) do
        applet:add_header(k, v)
    end

    applet:start_response()

    if response.body then
        applet:send(response.body)
    end
end)

It never completes the chain and gets to the last redirect. What am I doing wrong?

@lukastribus do you have any suggestions for me to look at?