Q: luasocket https client?

classic Classic list List threaded Threaded
7 messages Options
Reply | Threaded
Open this post in threaded view
|

Q: luasocket https client?

jomclaughlin
I need to build a lua https client and would like to base it on the
excellent lua socket.http module and luasec. Has anyone had any luck
doing this? It seems I need to override the trequest function to pass
ssl params to a new  open function (which would wrap the original open
function). However, trequest calls functions that are local to the
socket.http module, so I would have to duplicate a bunch of code,
which I would like to avoid doing. Thanks in advance for any advice.

jim

Reply | Threaded
Open this post in threaded view
|

Re: Q: luasocket https client?

Diego Nehab-3
Hi,

I need to build a lua https client and would like to base it on the
excellent lua socket.http module and luasec. Has anyone had any luck
doing this? It seems I need to override the trequest function to pass
ssl params to a new  open function (which would wrap the original open
function). However, trequest calls functions that are local to the
socket.http module, so I would have to duplicate a bunch of code,
which I would like to avoid doing. Thanks in advance for any advice.

Could you use the "create" request field? It allows you to
pass a function that will be used to create the socket
object. As long as your object respects the standard socket
interface, http.request won't even notice.

Regards,
Diego

Reply | Threaded
Open this post in threaded view
|

Re: Q: luasocket https client?

jomclaughlin
>
> Could you use the "create" request field? It allows you to
> pass a function that will be used to create the socket
> object. As long as your object respects the standard socket
> interface, http.request won't even notice.
>
Hi Diego,
Thanks for your response. I am not sure this will work. The example
from luasec has some work done after the call to "connect", which http
calls after "create" in the "open" function:

(from luasec http://www.inf.puc-rio.br/~brunoos/luasec/)
local conn = socket.tcp()
conn:connect("127.0.0.1", 8888)

 -- TLS/SSL initialization
conn = ssl.wrap(conn, params)
conn:dohandshake()

but maybe my "create" function can return a proxy for socket with an
overide for "connect" that does the ssl initialization. Not entirely
clear how this would work since the ssl.wrap function seems to return
a proxy of its own. Should I set a new metatable on self inside the
proxy "connect" method? Are we allowed to do that?

thanks again,
jim

Reply | Threaded
Open this post in threaded view
|

Re: Q: luasocket https client?

Diego Nehab-3
Hi Jim,

I don't see why you wouldn't be able to nest as many proxies
as you need.

maybe my "create" function can return a proxy for socket with an
overide for "connect" that does the ssl initialization.

That is exactly right.

Not entirely clear how this would work since the ssl.wrap function seems to return a proxy of its own. Should I set a new metatable on self inside the proxy "connect" method? Are we allowed to do that?

Why not?

The function you pass to "create" returns an object that
does all that. It starts as a table that has a field 'c', a
field connect, and a metatable that forwards all other
requests to 'c'. When somebody calls connect on this table, it simply calls connect on c, replaces c with a ssl.wrap, and
calls dohandshake on the new c. That's it, right?

[]s,
Diego

Reply | Threaded
Open this post in threaded view
|

Re: Q: luasocket https client?

Diego Nehab-3
In reply to this post by jomclaughlin
Hi,

-- TLS/SSL initialization
conn = ssl.wrap(conn, params)
conn:dohandshake()

Does this SSL wrapped connection support the same interface
as a regular LuaSocket socket? (i.e., receive patterns etc?)

Regards,
Diego

Reply | Threaded
Open this post in threaded view
|

Re: Q: luasocket https client?

jomclaughlin
In reply to this post by Diego Nehab-3
>
> The function you pass to "create" returns an object that
> does all that. It starts as a table that has a field 'c', a
> field connect, and a metatable that forwards all other
> requests to 'c'. When somebody calls connect on this table, it simply calls
> connect on c, replaces c with a ssl.wrap, and
> calls dohandshake on the new c. That's it, right?
>
> []s,
> Diego
>

Ah, thats it. Many thanks. I didn't think of just replacing c...

jim

Reply | Threaded
Open this post in threaded view
|

Re: Q: luasocket https client?

jomclaughlin
In reply to this post by Diego Nehab-3
On Fri, Feb 13, 2009 at 10:16 PM, Diego Nehab <[hidden email]> wrote:
> Hi,
>
>> -- TLS/SSL initialization
>> conn = ssl.wrap(conn, params)
>> conn:dohandshake()
>
> Does this SSL wrapped connection support the same interface
> as a regular LuaSocket socket? (i.e., receive patterns etc?)
>
> Regards,
> Diego
>

Yes, works like a charm. Below is a simple example. Thanks for the
help and the excellent library!

=====================================

local socket = require "socket"
local http = require "socket.http"
local ltn12 = require "ltn12"
local ssl = require "ssl"

local params = {
    mode = "client",
    protocol = "sslv23",
    cafile = "/etc/ssl/certs/ca-certificates.crt",
    verify = "peer",
    options = "all",
}

local try = socket.try
local protect = socket.protect

function create()
    local t = {c=try(socket.tcp())}

    function idx (tbl, key)
        print("idx " .. key)
        return function (prxy, ...)
                   local c = prxy.c
                   return c[key](c,...)
               end
    end


    function t:connect(host, port)
        print ("proxy connect ", host, port)
        try(self.c:connect(host, port))
        print ("connected")
        self.c = try(ssl.wrap(self.c,params))
        print("wrapped")
        try(self.c:dohandshake())
        print("handshaked")
        return 1
    end

    return setmetatable(t, {__index = idx})
end

local response_body = {}


b, c, h = http.request{
    url = "https://www.example.com:443/";,
    sink = ltn12.sink.table(response_body),
    create = create,
}

print(b, c, h)

print(table.concat(response_body))

=====================================