Implement iterator multi.iperform and method easy.perform for easy.
```Lua local cURL = require("lcurl") c1 = cURL.easy{url = "http://www.lua.org/"} c2 = cURL.easy{url ="http://luajit.org/"} m = cURL.multi() :add_handle(c1) :add_handle(c2) for a,b,c in m:iperform() do ... end ```
This commit is contained in:
parent
9127efffc2
commit
8d3c696c4c
@ -30,6 +30,69 @@ local function wrap_setopt_flags(k, flags)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local function make_iterator(self, perform)
|
||||||
|
local curl = require "lcurl.safe"
|
||||||
|
|
||||||
|
local buffers = {resp = {}, _ = {}} do
|
||||||
|
|
||||||
|
function buffers:append(e, ...)
|
||||||
|
local resp = assert(e:getinfo_response_code())
|
||||||
|
if not self._[e] then self._[e] = {} end
|
||||||
|
|
||||||
|
local b = self._[e]
|
||||||
|
|
||||||
|
if self.resp[e] ~= resp then
|
||||||
|
b[#b + 1] = {"response", resp}
|
||||||
|
self.resp[e] = resp
|
||||||
|
end
|
||||||
|
|
||||||
|
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 remain = #self._easy
|
||||||
|
for _, e in ipairs(self._easy) do
|
||||||
|
e:setopt_writefunction (function(str) buffers:append(e, "data", str) end)
|
||||||
|
e:setopt_headerfunction(function(str) buffers:append(e, "header", str) end)
|
||||||
|
end
|
||||||
|
|
||||||
|
assert(perform(self))
|
||||||
|
|
||||||
|
return function()
|
||||||
|
while true do
|
||||||
|
local e, t = buffers:next()
|
||||||
|
if t then return t[2], t[1], e end
|
||||||
|
if remain == 0 then break end
|
||||||
|
|
||||||
|
self:wait()
|
||||||
|
|
||||||
|
local n, err = assert(perform(self))
|
||||||
|
|
||||||
|
if n <= remain then
|
||||||
|
while true do
|
||||||
|
local e, ok, err = assert(self:info_read())
|
||||||
|
if e == 0 then break end
|
||||||
|
for _, a in ipairs(self._easy) do
|
||||||
|
if e == a:handle() then e = a break end
|
||||||
|
end
|
||||||
|
if ok then buffers:append(e, "done", ok)
|
||||||
|
else buffers:append(e, "error", err) end
|
||||||
|
end
|
||||||
|
remain = n
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
local function class(ctor)
|
local function class(ctor)
|
||||||
local C = {}
|
local C = {}
|
||||||
C.__index = function(self, k)
|
C.__index = function(self, k)
|
||||||
@ -42,7 +105,7 @@ local function class(ctor)
|
|||||||
return fn
|
return fn
|
||||||
end
|
end
|
||||||
|
|
||||||
function C:new()
|
function C:new(...)
|
||||||
local h, err = ctor()
|
local h, err = ctor()
|
||||||
if not h then return nil, err end
|
if not h then return nil, err end
|
||||||
|
|
||||||
@ -50,6 +113,8 @@ local function class(ctor)
|
|||||||
_handle = h
|
_handle = h
|
||||||
}, self)
|
}, self)
|
||||||
|
|
||||||
|
if self.__init then return self.__init(o, ...) end
|
||||||
|
|
||||||
return o
|
return o
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -207,74 +272,17 @@ local perform = wrap_function("perform")
|
|||||||
local add_handle = wrap_function("add_handle")
|
local add_handle = wrap_function("add_handle")
|
||||||
local remove_handle = wrap_function("remove_handle")
|
local remove_handle = wrap_function("remove_handle")
|
||||||
|
|
||||||
local function make_iterator(self)
|
function Multi:__init()
|
||||||
local curl = require "lcurl.safe"
|
self._easy = {}
|
||||||
|
return self
|
||||||
local buffers = {resp = {}, _ = {}} do
|
|
||||||
|
|
||||||
function buffers:append(e, ...)
|
|
||||||
local resp = assert(e:getinfo_response_code())
|
|
||||||
if not self._[e] then self._[e] = {} end
|
|
||||||
|
|
||||||
local b = self._[e]
|
|
||||||
|
|
||||||
if self.resp[e] ~= resp then
|
|
||||||
b[#b + 1] = {"response", resp}
|
|
||||||
self.resp[e] = resp
|
|
||||||
end
|
|
||||||
|
|
||||||
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 remain = #self._easy
|
|
||||||
for _, e in ipairs(self._easy) do
|
|
||||||
e:setopt_writefunction (function(str) buffers:append(e, "data", str) end)
|
|
||||||
e:setopt_headerfunction(function(str) buffers:append(e, "header", str) end)
|
|
||||||
end
|
|
||||||
|
|
||||||
assert(perform(self))
|
|
||||||
|
|
||||||
return function()
|
|
||||||
while true do
|
|
||||||
local e, t = buffers:next()
|
|
||||||
if t then return t[2], t[1], e end
|
|
||||||
if remain == 0 then break end
|
|
||||||
|
|
||||||
self:wait()
|
|
||||||
|
|
||||||
local n, err = assert(perform(self))
|
|
||||||
|
|
||||||
if n <= remain then
|
|
||||||
while true do
|
|
||||||
local e, ok, err = assert(self:info_read())
|
|
||||||
if e == 0 then break end
|
|
||||||
for _, a in ipairs(self._easy) do
|
|
||||||
if e == a:handle() then e = a break end
|
|
||||||
end
|
|
||||||
if ok then buffers:append(e, "done", ok)
|
|
||||||
else buffers:append(e, "error", err) end
|
|
||||||
end
|
|
||||||
remain = n
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function Multi:perform()
|
function Multi:perform()
|
||||||
return make_iterator(self)
|
return make_iterator(self, perform)
|
||||||
end
|
end
|
||||||
|
|
||||||
function Multi:add_handle(e)
|
function Multi:add_handle(e)
|
||||||
|
self._easy = self._easy or {}
|
||||||
self._easy[#self._easy + 1] = e
|
self._easy[#self._easy + 1] = e
|
||||||
return add_handle(self, e:handle())
|
return add_handle(self, e:handle())
|
||||||
end
|
end
|
||||||
@ -311,8 +319,61 @@ function cURL.share_init() return Share:new() end
|
|||||||
end
|
end
|
||||||
|
|
||||||
local function Load_cURLv3(cURL, curl)
|
local function Load_cURLv3(cURL, curl)
|
||||||
setmetatable(cURL, {__index = curl})
|
|
||||||
-- @todo implement new API
|
-------------------------------------------
|
||||||
|
local Easy = class(curl.easy) do
|
||||||
|
|
||||||
|
function Easy:__init(opt)
|
||||||
|
if opt then return self:setopt(opt) end
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
local perform = wrap_function("perform")
|
||||||
|
function Easy:perform(opt)
|
||||||
|
if opt then
|
||||||
|
local ok, err = self:setopt(opt)
|
||||||
|
if not ok then return nil, err end
|
||||||
|
end
|
||||||
|
|
||||||
|
return perform(self)
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
-------------------------------------------
|
||||||
|
|
||||||
|
-------------------------------------------
|
||||||
|
local Multi = class(curl.multi) do
|
||||||
|
|
||||||
|
function Multi:__init()
|
||||||
|
self._easy = {}
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
function Multi:iperform()
|
||||||
|
return make_iterator(self, self.perform)
|
||||||
|
end
|
||||||
|
|
||||||
|
local add_handle = wrap_function("add_handle")
|
||||||
|
function Multi:add_handle(e)
|
||||||
|
self._easy[#self._easy + 1] = e
|
||||||
|
return add_handle(self, e:handle())
|
||||||
|
end
|
||||||
|
|
||||||
|
local remove_handle = wrap_function("remove_handle")
|
||||||
|
function Multi:remove_handle(e)
|
||||||
|
self._easy[#self._easy + 1] = e
|
||||||
|
return remove_handle(self, e:handle())
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
-------------------------------------------
|
||||||
|
|
||||||
|
setmetatable(cURL, {__index = curl})
|
||||||
|
|
||||||
|
function cURL.easy(...) return Easy:new(...) end
|
||||||
|
|
||||||
|
function cURL.multi(...) return Multi:new(...) end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
return function(curl)
|
return function(curl)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user