There are a few problems with that example, I will make a note to get it updated.
The api in question is using the table variant, which will require a sink property is provided to put the body data into. Also you are correct, status is going to resolve to the http status info from the first line of the http response (i.e.HTTP/1.1 200 OK) so status == 200 is always going to be falsy
I took a look at this and it is pretty nice. It is actually similar to what I was starting to build with my HttpClient module above. I’m going to explore this a bit more.
@robert.masen Can luncheon be used with https? Just want to make sure before rewriting that portion of the driver. Are there examples of using luncheon with https? I was looking in the repo for the tcp setup required on the request socket if making https requests.
It should work just fine with a wrapped socket from cosock. something like
local socket = require "cosock.socket"
local ssl = require "cosock.ssl"
local tcp = socket.tcp()
local ip = "192.168.1.1"
local port = 8888
tcp:connect(ip, port)
-- TLS/SSL initialization
local params = {
mode = "client",
protocol = "any",
verify = "none",
options = {"all", "no_sslv3"}
}
local wrapped = ssl.wrap(conn, params)
wrappeddohandshake()
--TLS/SSL initialization
--At this point wrapped will work exactly like tcp would have
--except all traffic will be encrypted
@robert.masen First off, thank you very much for working to address this.
I have this using luncheon which appears close. It is sending the request, but The code is hanging up on the response, never print the Response in this code:
local socket = require "cosock.socket"
local ssl = require "cosock.ssl"
local lunch = require 'luncheon'
local sock = socket.tcp()
local ip = self.ip
local port = self.port
sock:connect(ip, port)
-- TLS/SSL initialization
local params = {
mode = "client",
protocol = "any",
verify = "none",
options = { "all", "no_sslv3" }
}
sock = ssl.wrap(sock, params)
sock:dohandshake()
--TLS/SSL initialization
local req = assert(lunch.Request.new(args.method, args.route, sock))
if args.body then
local encoded = self:encode('application/json', args.body)
req = req:append_body(encoded):set_content_type('application/json')
end
if self.token then
req = req:add_header('hue-application-key', self.token)
end
print('Sending...')
for line in req:iter() do
print(string.gsub(line, '\r?\n$', ''))
sock:send(line)
end
print('Sent')
local res = assert(lunch.Response.tcp_source(sock))
print('Response')
print(res.status)
print(res:get_body())
sock:close()
Is tcp_source the correct method to use here? Can the socket be reused for further requests?
@robert.masen Thank you for all of the help. I ended up getting it going on v43 using a modified version of ssl/https.lua that is being bundled in the driver. I plan to use luncheon down the road as it matures. It has a very nice interface.
This is most likely because the server you are communicating with is replying with a chunk encoding which isn’t currently supported directly in Luncheon. Hopefully it will get added soon.
It is possible to reuse sockets with luncheon but you would have to manage the connection semantics with the server manually.
RBoy
(www.rboyapps.com - Making SmartThings Easy!)
29
@robert.masen what’s the advantage of the above over
local http = require "cosock.socket.http"
local https = require "cosock.ssl.https"
No, these should be equivalent. the point of cosock.asyncify is to allow for the consumption of luasocket based libraries so I would say typically you wouldn’t consume luasocket via asyncify but there isn’t anything wrong with that approach.
@RBoy If you dig into the asyncify code, it replaces the modules internally when you use it. So when you ssl.https it internally swaps it out to the cosock version and does the same with dependencies. I use it to import libraries I have written that also need to run without the use of cosock internally (used on desktop)
Just to be clear, cosock is available to use on a desktop if you wanted (luarocks install cosock), you just need to make sure you have your top level module call cosock.run() to get cosock to drive your coroutines.