Using HTTPS to send messages between Iguana Servers

Introduction

Ever wanted to send messages between Iguana Servers? This is how you do it!

This example uses HTTPS to send messages between two Iguana channels. For testing purposes we sent the messages to the localhost, but you can easily change this to point to a remote server.

Issue [top]

How to use HTTPS to send messages between Iguana Servers.

Solution [top]

This example uses HTTPS to send messages between two Iguana channels. For testing purposes we sent the messages to the localhost, but you can easily change the IGUANA_DEST_URL to point to a remote server.

You will need to generate your own security certificate, and change the SECRET_TOKEN to get this code to work.

It would be very easy to target multiple servers, just add more destinations and post to each one. To consolidate messages from multiple servers to a single target server, you need to create Sender channels on each source server that all point the same server.

Also when you are testing the code you need to have the Receiver channel running, as the Sender channel expects a response and will raise an error if it stopped.

You can configure where the certificate file is stored in Settings>HTTP(S) Channels:

The url for the Receiver channel can be set in the Source page of the channel properties.

The code for this example is below:

Code for the Sender channel

Use an “LLP Listener” as Source and a “To Translator” as Destination – the code is placed in the Destination script.

-- change the server url to point to your target server
local IGUANA_DEST_URL = 'https://localhost:6544'
-- change the channel url path to point to your target channel
local CHANNEL_DEST_URL = '/Receiver'

-- change the token and create your own certificate
local SECRET_TOKEN = 'w7rusnF5Y9J7Bpy'

function main(Data)
   -- We make a table with our secret token, the message, and send it to the server
   local post_params = {secret_token=SECRET_TOKEN}
   post_params['message'] = Data

   local response,code,headers,debuginfo = net.http.post{
      url=IGUANA_DEST_URL..CHANNEL_DEST_URL,
      parameters=post_params,
      debug=true,live=true
   }
   print(response,code,headers,debuginfo)
   iguana.logDebug(debuginfo)
   --parse out response and check code
   if code==200 then
      local parsed_response = json.parse{data=response}
      if not parsed_response.Success then
         --here we raise an error and stop the channel, we could
         --also do more complex retry logic depending on what we want
         error('Bad Response: '..response)
      end 
   else
      error('Unexpected code from server: '..code..' response: '..response)      
   end
end

Code for the Receiver channel

Use a “From HTTPS” as Source – the code is placed in the Source script (use whatever Destination is appropriate for your circumstances)

local SECRET_TOKEN = 'w7rusnF5Y9J7Bpy'

function main(Data)
   --parse out the request from the user
   --check for some sort of semi-secret token, or do your own 
   --authentication. In this case we'll just look for a token in
   --the post parameter
   queue.push{data=Data} -- push in the full request into the queue so we have a record of it

   local parsed = net.http.parseRequest{data=Data}
   local response = {Success=true}
   if parsed.params.secret_token == SECRET_TOKEN then
      --passed secret token, so we do some processing here, like write to a file or
      --insert into db/etc
      iguana.logInfo('Successfully processed message')
   else
      iguana.logInfo('Failed authentication')
      response.Success = false     
   end 

   -- send the response to the client based on what just happened here
   net.http.respond{body=json.serialize{data=response},entity_type='application/json'};
end

So what’s next?

  • In the real world you probably have deal with multiple security tokens/certificates so you could change the the SECRET_TOKENS local SECRET_TOKENS = {'w7rusnF5Y9J7Bpy','token 2', 'token 3', 'etc'} to be a table and process it in a loop
  • For greater security you could store the security tokens in a database and load them with a function like loadTokens()
  • You may want to keep some sort of log of the messages that have been processed
    • You may have noticed the queue.push{data=Data} in the Receiver, you could use a “To Translator” as the Destination and process/log the queued data – this will give you a separate logging for each receiving channel
    • You could also process the data in the Sender channel, save it to a file or database etc – this will give a separate logging for each sending channel