[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: advice on a http client library?
- From: Alexandre Erwin Ittner <alexandre@...>
- Date: Thu, 7 Jan 2010 11:13:11 -0200
Cosmin Apreutesei <cosmin.apreutesei@gmail.com> wrote
> I was also thinking about LuaSec for https + LuaSocket for TCP +
> LuaSocket.http for encoding/decoding the http stream. Did anyone tried
> such a crazy scheme?
Sometime ago, I wrote this HTTPS module, using some code taken from
a previous post by James McLaughlin [1]. It emulates the
socket.http.request() interface, so, there is no much things to learn
before start using it. But I advice some caution -- It's almost untested.
[1] http://lua-users.org/lists/lua-l/2009-02/msg00270.html
--
Alexandre Erwin Ittner - alexandre@ittner.com.br
OpenPGP pubkey 0x0041A1FB @ http://pgp.mit.edu
----
module("https", package.seeall)
local socket = require "socket"
local http = require "socket.http"
local ssl = require "ssl"
local ltn12 = require "ltn12"
local try = socket.try
local protect = socket.protect
local DEFAULT_PROTOCOL = "sslv23"
local DEFAULT_CAFILE = "/etc/ssl/certs/ca-certificates.crt"
local DEFAULT_VERIFY = "peer"
local DEFAULT_OPTIONS = "all"
local DEFAULT_CIPHERS = "ADH-AES256-SHA:ADH-AES128-SHA:HIGH:MEDIUM"
local DEFAULT_HTTPS_PORT = 443
local https_mt = {
-- Create proxy functions for each call through the metatable
__index = function(tbl, key)
local f = function(prxy, ...)
local c = prxy.c
return c[key](c, ...)
end
tbl[key] = f -- Save new proxy function in cache for speed
return f
end
}
local function new_create(params)
return function()
local t = { c = try(socket.tcp()) }
function t:connect(host, port)
try(self.c:connect(host, port))
self.c = try(ssl.wrap(self.c, params))
try(self.c:dohandshake())
return 1
end
return setmetatable(t, https_mt)
end
end
local function request_generic(args)
local sslparams = {
mode = "client",
protocol = args.protocol or DEFAULT_PROTOCOL,
cafile = args.cafile or DEFAULT_CAFILE,
verify = args.verify or DEFAULT_VERIFY,
options = args.options or DEFAULT_OPTIONS,
ciphers = args.ciphers or DEFAULT_CIPHERS
}
local req = {
url = args.url,
port = args.port or DEFAULT_HTTPS_PORT,
sink = args.sink,
method = args.method,
headers = args.headers,
source = args.source,
step = args.step,
proxy = args.proxy, -- Buggy?
redirect = args.redirect,
create = new_create(sslparams)
}
return http.request(req)
end
local function request_simple(url, body)
local tbl = { }
local req = {
url = url,
sink = ltn12.sink.table(tbl)
}
if body then
req.method = "POST"
req.source = ltn12.source.string(body)
req.headers = {
["Content-length"] = #body,
["Content-type"] = "application/x-www-form-urlencoded"
}
end
local _, status, headers = request_generic(req)
return table.concat(tbl), status, headers
end
function request(req_or_url, body)
if type(req_or_url) == "string" then
return request_simple(req_or_url, body)
else
return request_generic(req_or_url)
end
end