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.

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

    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:add_header("Content-Type", "text/plain")

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

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

    -- Responding with the final fetched content or redirect

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


    if response.body then

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?