Search code examples
javahttphttp-redirectwebhaproxy

How to Make HA Proxy to Follow Redirects by Itself?


I have java client which talks to 3rd party service through HA Proxy. 3rd party service was recently changed, so now it is returning 302(Moved Temporarily) instead of 200(Ok) which causes failure on my java client cause it expects 200 with actual response. For a number of reasons I want to avoid any code changes to the java client.

So, here is the question: Is there a way to make HA Proxy to follow redirects by itself and only return result(not 3xx http code) to the client?

One more thing to mention: I access HA Proxy via http, HA proxy accesses 3rd party resource via https, and returns 302 with location on https. Location varies, so configure HA Proxy to the new location is not an option.

HA Proxy version: HA-Proxy version 1.7.5 2017/04/03

OS: CentOS Linux release 7.2.1511 (Core)


Solution

  • You can use this

    $ haproxy -v
    Nuster version 1.8.8.2.2
    Copyright (C) 2017-2018, Jiang Wenyuan, <koubunen AT gmail DOT com >
    
    HA-Proxy version 1.8.8.2 2018/05/29
    Copyright 2000-2018 Willy Tarreau <willy@haproxy.org>
    

    haproxy.conf

    global
        debug
        lua-load handle_redirect.lua
    
    frontend web1
        bind *:8080
        mode http
    
        default_backend app1
    
    backend app1
        mode http
    
        http-response lua.handle_redirect if { status eq 301 }
    
        server s1 127.0.0.1:9000
    

    handle_redirect.lua

    http = require("http")
    
    core.register_action("handle_redirect", {"http-res"}, function(txn)
    
      local hdr = txn.http:res_get_headers()
      if hdr["location"] == nil then
        return nil
      end
    
    
      local r, msg = http.get{
        url = hdr["location"][0]
      }
    
      if r == nil then
        return msg
      end
    
      local res = "HTTP/1.1 " .. r.status_code .. " " .. r.reason .. "\r\n"
      for k, v in pairs(r.headers) do
        res = res .. k .. ": " .. v .. "\r\n"
      end
      res = res .. "\r\n"
      res = res .. r.content
    
    
      txn.res:set(res)
      txn.done(txn)
    
    end)
    

    Download http.lua from https://github.com/haproxytech/haproxy-lua-http/blob/master/http.lua

    haproxy -f haproxy.conf