Sunday 30 April 2017

HTTPS with Lua Sockets

I noticed that a couple of people a week are reading Busted or LuaUnit?. If they were looking for some comparison, they would have been disappointed. Especially as they didn't look at Lua Test Doubles which does give some feedback on Busted and LuaUnit.

I've started out to complete the test-driven development of the stockfetch program using both Busted and LuaUnit. The next step in the project is to read the stock prices from Yahoo. On the surface this didn't seem to be difficult as when I tried GETting a webpage using Lua Socket, it was pretty simple.

But I found that the Lua Socket HTTP "simple" form is unable to handle https. To GET data from an https source you need to use the Lua Socket HTTP "generic" form and the Lua Sec module. Lua Socket HTTP generic form uses LTN12 sinks to collect the content rather than returning a simple string.

Here is a simple example of GETting the content of the Lua Home Page. I hope it is sufficiently self-explanatory.

local https = require('ssl.https')
local ltn12 = require('ltn12')

local responseContent = {}
local returnCode, httpResponseCode, httpHeaders, htttpStatus = https.request{
  url = 'https://www.lua.org',
  sink = ltn12.sink.table(responseContent)
}

if returnCode then
  print('httpResponseCode: ' .. httpResponseCode)
  print('date: ' .. httpHeaders.date)
  print('server: ' .. httpHeaders.server)
  print('last-modified: ' .. httpHeaders['last-modified'])
  print('content-length: ' .. httpHeaders['content-length'])
  print('content-type: ' .. httpHeaders['content-type'])
  print(table.concat(responseContent));
else
  print(httpResponseCode)       -- this will contain a lua socket error message
end

Note: I used Lua Rocks to install the Lua Sec module. It requires OpenSSL to be installed. If you running Lua under macOS, you might find these instructions helpful. I did.