Lua-cURLv3/examples/lcurl/multi_iterator.lua

79 lines
1.8 KiB
Lua

--
local function multi_iterator(...)
local curl = require "lcurl.safe"
local buffers = {_ = {}} do
function buffers:append(e, ...)
local b = self._[e] or {}
self._[e] = b
b[#b + 1] = {...}
end
function buffers:next()
for e, t in pairs(self._) do
local m = table.remove(t, 1)
if m then return e, m end
end
end
end
local function multi_init(...)
local remain = 0
local m = curl.multi()
for _, e in ipairs{...} do
e:setopt_writefunction(function(str) buffers:append(e, "data", str) end)
e:setopt_headerfunction(function(str) buffers:append(e, "header", str) end)
m:add_handle(e)
remain = remain + 1
end
return m, remain
end
local m, remain = multi_init(...)
m:perform()
return function()
while true do
local e, t = buffers:next()
if t then return e, unpack(t) end
if remain == 0 then break end
m:wait()
local n, err = m:perform()
if not n then m:close() error(err) end
if n <= remain then
while true do
local e, ok, err = m:info_read()
if not e then m:close() error(err) end
if e == 0 then break end
if ok then buffers:append(e, "done", ok)
else buffers:append(e, "error", err) end
end
remain = n
end
end
m:close()
end
end
--
local curl = require "lcurl"
c1 = curl.easy()
:setopt_url("http://www.lua.org/")
c2 = curl.easy()
:setopt_url("http://luajit.org/")
for easy, type, data in multi_iterator(c1, c2) do
if type == 'header' then print(easy, type, (data:gsub("%s*$", "")))
elseif type == 'data' then print(easy, type, #data)
elseif type == 'error' then print(easy, type, data)
elseif type == 'done' then print(easy, type, data)
end
end