Example: Accessing request attributes (body, headers)

Similar to Reflect back to the client their IP address, we have a use case where we need to be able to see specific attributes of the incoming request.

Mainly: the request body. Some of our customers use a proxy in front of our service and we sometimes need to diagnose whether their proxy is inappropriately modifying incoming requests to Discourse.

The below function reflects back to the client the body their originally submitted, then we can check that for mangling:

showrequest = function(applet)
  local content_type
  if applet.headers["content-type"] then
    content_type = applet.headers["content-type"][0]
  else
    content_type = ""
  end

  local content_length
  if applet.headers["content-length"] then
    content_length = applet.headers["content-length"][0]
  else
    content_length = ""
  end

  local method
  method = applet.method

  local body
  body = applet.c:base64(applet:receive(4096))

  applet:set_status(200)
  applet:add_header("cache-control", "none")
  applet:add_header("content-type", "application/json")
  applet:start_response()

  template = [[{"method":"%s","content-type":"%s","content-length":"%s","body":"%s"}]]
  applet:send(
    string.format(
      template,
      method,
      content_type,
      content_length,
      body
    )
  )
end

core.register_service("showrequest", "http", showrequest)

(also demonstrated here: use of the base64 converter which I hadn’t found an example of before)

Example:

○ → curl -s https://some.host/path_to_this_lua_script -X FROB -H 'content-type: application/json' -d "$(jo foo=bar baz=quux)"
{"method":"FROB","content-type":"application/json","content-length":"26","body":"eyJmb28iOiJiYXIiLCJiYXoiOiJxdXV4In0="}
1 Like

How this is implemented in HaProxy side? Any example? Thanks.