Quantcast
Channel: HAProxy community - Latest topics
Viewing all articles
Browse latest Browse all 4849

Have backend follow multiple redirects

$
0
0

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 then I want it to follow all the redirects starting with the URL I pull from a JSON service.

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),
    }

    -- Collecting initial request headers
    for name, value in pairs(applet.headers) do
        headers[name:lower()] = value[0]
    end

    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?

1 post - 1 participant

Read full topic


Viewing all articles
Browse latest Browse all 4849

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>