How to Make HA Proxy to Follow Redirects by Itself

2019-08-08 19:16发布

问题:

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)

回答1:

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


回答2:

It seems like you are trying to solve the wrong problem.

It sounds like the site is returning 302 because you are not using HTTPS. So, configure the proxy to use HTTPS.

server foo foo.example.com:443 ssl verify none

You don't have to access the proxy using HTTPS, but the proxy needs to make the outbound request using HTTPS.

Additionally, HAProxy doesn't do what you are asking about. Responses can be modified as they are being returned, but you cannot force the proxy to follow a redirect.