How could I correctly fetch the request domain in Lua?

I need to fetch the HTTP request’s domain to perform domain whitelist verification, but sometimes I cannot retrieve the host value—it returns nil. My HAProxy version is 3.1.5, and I’m using the following Lua script to get the host:

function get_host(txn)
    local sni = txn.sf:ssl_fc_sni()
    -- HTTP request Host header
    local host = txn.sf:req_fhdr("Host")

    -- In some cases (HTTP/2), domain is in :authority
    if (not host or host == "") then
        host = txn.sf:req_fhdr(":authority")
    end

    local domain = host or sni

    return domain
end

core.register_action("set_proxy_extra", { "http-req", "http-res" }, function(txn)
    local host = get_host(txn)
    --
    -- other codes has removed
    --
end)
  • haproxy.cfg:
global
    tune.lua.bool-sample-conversion normal
    lua-load /usr/local/etc/haproxy/parse_proxy_auth.lua

frontend proxy_default_frontend
    bind *:80
    mode http
    http-request lua.set_proxy_extra

However, when I use the log-format to print the request-line with %{+Q}r, it does have a value. Could anyone provide a complete working code example?

Thank you!

Please provide relevant haproxy config (where the get_host lua fetch is used)

@adarragon The following is part of the HAProxy and Lua code:

  • haproxy.cfg:
global
    tune.lua.bool-sample-conversion normal
    lua-load /usr/local/etc/haproxy/parse_proxy_auth.lua


frontend proxy_default_frontend
    bind *:80
    mode http
    http-request lua.set_proxy_extra


  • parse_proxy_auth.lua:
function get_host(txn)
    local sni = txn.sf:ssl_fc_sni()
    -- HTTP request Host header
    local host = txn.sf:req_fhdr("Host")

    -- In some cases (HTTP/2), domain is in :authority
    if (not host or host == "") then
        host = txn.sf:req_fhdr(":authority")
    end

    local domain = host or sni

    return domain
end


core.register_action("set_proxy_extra", { "http-req", "http-res" }, function(txn)
    local host = get_host(txn)
end)

hope for your reply, thank you!

I don’t see errors in the way the txn.sf:req_fhdr() fetch is used from Lua

However since haproxy will accept HTTP1.X requests without host header, I’m wondering if some clients are (purposely or not) omitting that header and could explain that your get_host() Lua function sometimes returns NULL.

You may want to protect against that, see No Host header accepted in 1.1 requests · Issue #1299 · haproxy/haproxy · GitHub

I found that HTTP/1.0 requests do not correctly retrieve the Host.