HAProxy community

Is it possible to do string match with Host header & a custom variable?

I am trying to see if i can stamp a response header with boolean value true, if the Host header & my custom variable match

   http-response set-header x-prefdomain-match bool(true) if { hdr(Host) -m str %[var(txn.prefdomain)] } 

Can anyone suggest if i am missing anything in the above config line?

Hi,

I have also not been able to string compare a host header with a custom variable. Though i am not sure as to why the comparison does not work out, but one of the possible reasons could be the mismatch between the type of value stored in host header, which is IP, and the string type value stored in the variable.

Nevertheless, i was able to find a solution to your requirement and that is to make use of lua. For the this solution to work, you would have to first build HAProxy with lua support. Below are the steps to be followed:

  1. Build lua to be used:

curl -R -O http://www.lua.org/ftp/lua-5.3.5.tar.gz
tar -zxvf lua-5.3.5.tar.gz
cd lua-5.3.5
make linux test
make linux install

  1. Build HAProxy with lua:

cd haproxy-1.7.8
make TARGET=linux2628 USE_PCRE=1 USE_PCRE_JIT=1 USE_OPENSSL=1 USE_ZLIB=1 USE_LINUX_TPROXY=1 USE_REGPARM=1 USE_LUA=1 USE_THREAD=1 USE_TFO=1
make install
cp examples/haproxy.init /etc/init.d/haproxy
chmod 755 /etc/init.d/haproxy
systemctl daemon-reload

Now, you need to create a lua script that would compare two headers and return TRUE if both the headers match. Below is the script:

function compare_header_value(txn, h1, h2)
local hdr = txn.http:req_get_headers()

  if hdr[h1] == nil or hdr[h2] == nil then
    return false
  end

  if hdr[h1][0] == hdr[h2] then
    return true
  end

  return false

end

core.register_fetches("compare_header_value", compare_header_value)

Now, the custom variable to be compared has to be set in a request header and compared with the host header using the above lua script. Below is the HAProxy configuration for the same:

global
    lua-load /opt/hap_lua/compare_header_value.lua

frontend ft
    bind *:80
    http-request set-var(txn.varcus) req.hdr(Host)
    http-request set-header X-varheader %[var(txn.varcus)]
    http-request set-var(txn.script_result) lua.compare_header_value(host,X-varheader)
    default_backend bt

backend bt
    balance roundrobin
    acl aclt var(txn.script_result) equal 0
    http-response set-header X-reshead true if aclt
    server IP:Port  IP:Port

Hope this is helpful !

Thanks,
Shivharsh