Web service FAQs

This section contains answers to common questions about using Web Services with Iguana.

Web services in Iguana can be served up either on the same HTTP(S) port as the main Iguana GUI or you can choose a separate dedicated port.

You can configure this in Settings>HTTP(S) Channels:

Note: You can set up SSL security certificates if you select a dedicated port.

Iguana’s built-in web server supports SSL, so you can connect to and create secure web services.

To connect to secure web service

You can use SSL with the net.http.xxx{} library (get, put, post and delete), just put the SSL certificate details in the ssl table parameter. For details see the API documentation net.http – using http connections.

The simplest connection code is something like this:

URL = 'https://<secure site name>'

SSL = {cert='/filepath/to/self_cert_test_keys/c', 
   key='/filepath/to/self_cert_test_keys/privkey.pem',
   verify_host=false, verify_peer=false} -- verify peer needs a "Certificate Authority file"

function main()
   -- get data from secure web service
   local R = net.http.get{url=URL, live=true, ssl = SSL}
   trace(R)
end

To create a secure web service

You must enable HTTPS in Settings>HTTP(S) Channels and enter the SSL certificate file details (no code changes are required).

Note: If you select Verify Peer you will also need a Certificate Authority File.

To set the Iguana web server to use SSL

This will apply SSL to the Iguana web APIs, i.e., monitor_query{} etc.

URL = 'https://localhost:6543/monitor_query'

SSL = {cert='/filepath/to/self_cert_test_keys/c', 
   key='/filepath/to/self_cert_test_keys/privkey.pem',
   verify_host=false, verify_peer=false} -- verify peer needs a "Certificate Authority file"

AUTH = {username='admin',password='password'}

function main()
   -- get data from secure web service
   local R = net.http.get{url=URL, live=true, 
      auth=AUTH, ssl = SSL}
   trace(R)
end

You must enable HTTPS in Settings>Web Server and enter the SSL certificate file details (no code changes are required).


How to create self-certified SSL certificates for testing

A simple way to create your certificate and public key file is to use openssl. See how to create self-certified SSL certificate and public key files for more information.

Tip: You can also use SSL with the To/From LLP components and with net.ftps, and net.smtp.

You need to choose an event or events to trigger the Web Service call, you can use any event to trigger a web service call.

For example: Use a From Translator to poll a directory or a database, use From HTTPS to receive web service calls from a web page or application (useful to respond interactively to user input), use a From Translator and conditionally call a web service to add missing data or update incomplete data, or you could just schedule an hourly web service call.

Yes!

When using “From HTTP” components in channels it is possible to serve files from the web service port. This is useful when returning page data that contains embedded resources, such as images or javascript files, to a web browser.

Here is a simple “From HTTP” script that returns HTML data with an embedded image:

function main(Data)
local TestHtml = [[
<html>
<head><title>Test Html</title></head>
<body>
<img src="http://helpdn.interfaceware.com/interfaceware.gif">
</body>
</html>]]
net.http.respond{body=TestHtml}
end

The root directory to serve files from can be configured in Settings>HTTP(S) Channels:

In this case, the returned HTML data will request an image named “interfaceware.gif”, and Iguana will look for the file in the /Applications/iNTERFACEWARE-Iguana/ directory.

Simple! Just use this is handy module for parsing URL encoded GET/POST sequences, i.e., LastName=Smith&FirstName=John&Dob=19722011 etc.

The code for the urlcode.lua module can be downloaded from our code repository.

The Translator’s ‘net.http’ module is an HTTP 1.1 compliant client that uses the standard cURL library which can reuse socket connections. To run high message loads between an Iguana client and a web server it is recommended that HTTP socket connections be reused.

To enable socket reuse both the Iguana web client and the third party web server participating in an HTTP 1.1 conversation must be configured to reuse sockets with ‘Connection=Keep-Alive’.

For more information see: Evaluating Web Client Performance.

We strongly recommend using RESTful web services to call external code. Web Services are simple and flexible, and they are easy to integrate into to your code using our built-in net.http API.

Iguana does supports plugins, but this is older legacy technology, dating back to Iguana 3. We still have a large installed base of plugins that we are committed to supporting.

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 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
Iguana itself has a web-service API which can be used to monitor it.

What is powerful about it is that we can actually call that API from within an Iguana Translator instance. This is useful since you implement powerful custom logic with respect to monitoring one, or a group of Iguana servers from within Iguana. It makes it easy to integrate with third party monitoring software like triggering a command line tool that could do an SMNP alert or you could use a web service API on a ticketing system to raise a ticket.

You have complete flexibility.

Tip: You may also want to look at the our new Channel API and the iguana.lua wrapper for the Channel API.

Here’s some code for you to try out:

function main()
local X = net.http.get{live=true,
   url="http://localhost:6543/status.html",
   auth={username='admin', password='password'},
   parameters={Format='xml'}}
   X = xml.parse{data=X}
   print(X.IguanaStatus.NumberOfChannels:nodeValue())
end

Leave A Comment?