lua-users home
lua-l archive

Re: advice on a http client library?

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


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

AltStyle によって変換されたページ (->オリジナル) /