Making a separate HTTP Request from Lua ("http-req" action)


#1

Has any of you guys been able to successfully do a separate HTTP-Request from a HAProxy Lua “http-req” action handler?

Overview:
In my setup I have a HAProxy with the frontends facing the internet and the backends pointing to HTTP/Rest-services on internal servers.

I’m trying to create a HTTP header rewrite mechanism in HAProxy (with Lua) that automatically translates opaque identification tokens (similar to random session strings), coming as headers from the internet requests, to JWT-tokens as Authorization: Bearer

Rewriting a header with a Lua action is easy enough following the docs:
$ cat /etc/haproxy/haproxy_test.lua

counter = 0

core.register_action("hello_world", {"http-req"}, function(txn)
        txn:Info("Hello world")
        txn.http:req_del_header("MH-Header")
        counter = counter + 1
        txn.http:req_add_header("MH-Header", "1337" .. counter)
end)

What I want to do with my mechanism is:

  1. Get the value of the opaque identification token OIT from an incoming HTTP header.
  2. Make a completely separate HTTP request from a HAProxy Lua script to an Identification Service that can translate the OIT to a JWT-Token
  3. Use the resulting JWT-Token (from #2) and insert it as a header into the request making it available to the target service(s) in the backend.

My problem is that I cannot get the HTTP-request to work from the HAProxy Lua environment.

$ cat /etc/haproxy/haproxy_test2.lua


http = require("socket.http")
counter = 0

core.register_action("hello_world", {"http-req"}, function(txn)

        txn:Info("Hello world1")
        local resp = {}
        local r, c, h, s = http.request{
                url = "http://localhost:8002/index.html",
                sink = ltn12.sink.table(resp)
                --create = core.tcp
        }

        txn:Info("Hello world2")
        txn.http:req_del_header("MH-Header")
        counter = counter + 1
        txn:Info("Hello world3")
        txn.http:req_add_header("MH-Header", "1337 " .. counter .. r)
        txn:Info("Hello world4")
end)

This simply does not work.

I’m no experienced Lua programmer but i managed to get a similar Lua program to work from the command line, outside the HAProxy environment, like this (uses https://github.com/kikito/inspect.lua):

$ cat test3.lua

inspect = require('inspect')
http = require("socket.http")

function a()
        local resp = {}
        local r, c, h, s = http.request{
                url = "http://localhost:8002/",
                sink = ltn12.sink.table(resp)
        }
        print(r)
        print(c)
        print(inspect(h))
        print(s)
        print(inspect(resp))
end

a()

I guess this might have to do with the non-blocking sockets and Lua environment when running inside HAProxy, but I’m currently stuck.