# Remote rest call

**URL:** <https://discourse.haproxy.org/t/remote-rest-call/3911>\
**Category:** Help!\
**Created:** [June 11, 2019, 12:21am UTC](https://discourse.haproxy.org/t/remote-rest-call/3911 "2019-06-11T00:21:56Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![jbrahy](https://sea2.discourse-cdn.com/flex016/user_avatar/discourse.haproxy.org/jbrahy/32/525_2.png) [@jbrahy](https://discourse.haproxy.org/u/jbrahy)\
**Post date:** [June 11, 2019, 12:21am UTC](https://discourse.haproxy.org/t/remote-rest-call/3911/1 "2019-06-11T00:21:56Z")

</div>

I have to write and check with remote API for each request coming into my haproxy server. Is there a way to send a request with parameters to an API endpoint and based on the response of the endpoint to select a backend.

---

<div class="post-metadata">

**Author:** ![jbrahy](https://sea2.discourse-cdn.com/flex016/user_avatar/discourse.haproxy.org/jbrahy/32/525_2.png) [@jbrahy](https://discourse.haproxy.org/u/jbrahy)\
**Post date:** [June 11, 2019, 3:47pm UTC](https://discourse.haproxy.org/t/remote-rest-call/3911/2 "2019-06-11T15:47:10Z")

</div>

So I’ve found that this is possible using LUA so I’ll post some sample code if anyone is interested.

---

<div class="post-metadata">

**Author:** ![lukastribus](https://avatars.discourse-cdn.com/v4/letter/l/7ea924/32.png) [@lukastribus](https://discourse.haproxy.org/u/lukastribus)\
**Post date:** [June 11, 2019, 5:40pm UTC](https://discourse.haproxy.org/t/remote-rest-call/3911/3 "2019-06-11T17:40:00Z")

</div>

Yes, please do.

---

<div class="post-metadata">

**Author:** ![jbrahy](https://sea2.discourse-cdn.com/flex016/user_avatar/discourse.haproxy.org/jbrahy/32/525_2.png) [@jbrahy](https://discourse.haproxy.org/u/jbrahy)\
**Post date:** [June 14, 2019, 3:40pm UTC](https://discourse.haproxy.org/t/remote-rest-call/3911/4 "2019-06-14T15:40:18Z")

</div>

ok, so I’ve got it pretty much working but I’m having a problem getting the value of the web service. I’ve tried a few different libraries and rebuilding haproxy / lua / luarocks from scratch and still issues.

Pretty straightforward code and the url is valid.

```
local stream = assert(http_request.new_from_uri(api_call):go())
local body = assert(stream:get_body_as_string())

```

[ALERT] 164/081414 (14527) : Lua sample-fetch ‘forensiq’: runtime error: /root/haproxy\_build/forensiq.lua:93: attempt to call a nil value (method ‘get\_body\_as\_string’) from /root/haproxy\_build/forensiq.lua:93 C function line 2.

and using the http.get method, I get this message.

[ALERT] 164/082838 (14788) : Lua sample-fetch ‘forensiq’: runtime error: /root/haproxy\_build/forensiq.lua:92: attempt to index a nil value (global ‘http’) from /root/haproxy\_build/forensiq.lua:92 C function line 2.

```
http.get(api_call, nil, function(code, data)
    if (code ~= 200) then
            print("HTTP request failed")
    else
            print(code, data)
    end

```

end)

---

<div class="post-metadata">

**Author:** ![jbrahy](https://sea2.discourse-cdn.com/flex016/user_avatar/discourse.haproxy.org/jbrahy/32/525_2.png) [@jbrahy](https://discourse.haproxy.org/u/jbrahy)\
**Post date:** [June 20, 2019, 8:13pm UTC](https://discourse.haproxy.org/t/remote-rest-call/3911/6 "2019-06-20T20:13:23Z")

</div>

I found it’s pretty easy. Here’s the basics on how I did it. I’m always open to improvements.

In the global section you load the lua script

```
  lua-load check_fraud.lua

```

and then in the front end section I had this.

```
     frontend frontend-http-https
         bind :80
         bind :443 ssl crt /etc/haproxy/ssl
         default_backend backend-default

     backend backend-default
         option forwardfor
         http-request deny if { lua.check_fraud 0 }
         http-response set-header X-Detection passed
         server web-1 www.website.com:443 check ssl verify none

```

and in the check\_fraud.lua file

```
  core.register_fetches("check_fraud", function(txn)

      -- load up the libraries 
      local http_util = require "http.util" -- for dict_to_query
      local io = require("io")
      local https = require("ssl.https")
      local ltn12 = require("ltn12")
      local json = requires("json")

      -- local variables
      local api_root = "https://website.com/services/check"
      local now = os.date("*t")
      local parameters = {}
      local clientip = txn.f:src() 
      local risk_tolerance = 85
      
      parameters["client_key"] = "asdf123asdf"
      parameters["request_type"] = "click"
      parameters["ip_address"] = clientip
      parameters["click_time"] = string.format("%d-%02d-%02d %02d:%02d:%02d",now["year"],now["month"],now["day"],now["hour"],now["min"],now["sec"])
      parameters["path"] = txn.f:path()
      parameters["referrer"] = txn.sf:req_fhdr("host")
      parameters["ua"] = txn.sf:req_fhdr("User-Agent")
      parameters["output"] = "JSON"

      local api_call = api_root .. "?" .. http_util.dict_to_query(parameters)
      
      result, statuscode, content = https.request(api_call)

      local fraud_data = json:decode(result)
      fraud = fraud_data.items[1]
      
      if fraud.riskScore < risk_tolerance then
        return 1
      else
        return 0
      end
    
    end)
```
