Skip to content

Commit b4deff3

Browse files
committed
Merge pull request #22 from moteus/master
Fix. Remove easy handle from multi handle
2 parents 06df328 + b2e6bca commit b4deff3

4 files changed

Lines changed: 130 additions & 23 deletions

File tree

examples/cURLv3/file.lua

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
local cURL = require "cURL"
2+
3+
-- open output file
4+
f = io.open("example_homepage", "w")
5+
6+
cURL.easy{
7+
url = "http://www.example.com/",
8+
writefunction = f
9+
}
10+
:perform()
11+
:close()
12+
13+
-- close output file
14+
f:close()
15+
16+
print("Done")

examples/cURLv3/multi.lua

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
local cURL = require("cURL")
2+
3+
-- setup easy and url
4+
c1 = cURL.easy{url = "http://www.lua.org/"}
5+
c2 = cURL.easy{url = "http://luajit.org/"}
6+
7+
m = cURL.multi()
8+
:add_handle(c1)
9+
:add_handle(c2)
10+
11+
local f1 = io.open("lua.html", "w+b")
12+
local f2 = io.open("luajit.html", "w+b")
13+
14+
for data, type, easy in m:iperform() do
15+
if type == "data" and c1 == easy then f1:write(data) end
16+
if type == "data" and c2 == easy then f2:write(data) end
17+
end

examples/cURLv3/rss.lua

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
-- use LuaExpat and Lua-CuRL together for On-The-Fly XML parsing
2+
local lxp = require "lxp"
3+
local cURL = require "cURL"
4+
5+
-- create XML parser
6+
items, tags = {}, {}
7+
p = lxp.new{
8+
StartElement = function (parser, tagname)
9+
tags[#tags + 1] = tagname
10+
if (tagname == "item") then
11+
items[#items + 1] = {}
12+
end
13+
end;
14+
15+
CharacterData = function (parser, str)
16+
if (tags[#tags -1] == "item") then
17+
--we are parsing a item, get rid of trailing whitespace
18+
items[#items][tags[#tags]] = string.gsub(str, "%s*$", "")
19+
end
20+
end;
21+
22+
EndElement = function (parser, tagname)
23+
--assuming well formed xml
24+
tags[#tags] = nil
25+
end;
26+
}
27+
28+
-- create and setup easy handle
29+
c = cURL.easy{url = "http://www.lua.org/news.rss"}
30+
31+
-- setup writer function with context
32+
c:setopt_writefunction(p.parse, p)
33+
34+
-- perform request and close easy handle
35+
-- perform raise error if parser fail
36+
c:perform():close()
37+
38+
--finish document
39+
assert(p:parse())
40+
p:close()
41+
42+
for i, item in ipairs(items) do
43+
for k, v in pairs(item) do
44+
print(k,v)
45+
end
46+
print()
47+
end

src/lua/cURL/impl/cURL.lua

Lines changed: 50 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -58,10 +58,12 @@ local function make_iterator(self, perform)
5858

5959
end
6060

61-
local remain = #self._easy
62-
for _, e in ipairs(self._easy) do
63-
e:setopt_writefunction (function(str) buffers:append(e, "data", str) end)
64-
e:setopt_headerfunction(function(str) buffers:append(e, "header", str) end)
61+
local remain = self._easy.n
62+
for h, e in pairs(self._easy) do
63+
if h ~= 'n' then
64+
e:setopt_writefunction (function(str) buffers:append(e, "data", str) end)
65+
e:setopt_headerfunction(function(str) buffers:append(e, "header", str) end)
66+
end
6567
end
6668

6769
assert(perform(self))
@@ -78,19 +80,16 @@ local function make_iterator(self, perform)
7880

7981
if n <= remain then
8082
while true do
81-
local e, ok, err = assert(self:info_read())
82-
if e == 0 then break end
83-
for _, a in ipairs(self._easy) do
84-
if e == a:handle() then e = a break end
85-
end
83+
local h, ok, err = assert(self:info_read())
84+
if h == 0 then break end
85+
local e = assert(self._easy[h])
8686
if ok then
8787
ok = e:getinfo_response_code() or ok
8888
buffers:append(e, "done", ok)
8989
else buffers:append(e, "error", err) end
9090
end
9191
remain = n
9292
end
93-
9493
end
9594
end
9695
end
@@ -276,7 +275,7 @@ local add_handle = wrap_function("add_handle")
276275
local remove_handle = wrap_function("remove_handle")
277276

278277
function Multi:__init()
279-
self._easy = {}
278+
self._easy = {n = 0}
280279
return self
281280
end
282281

@@ -285,14 +284,26 @@ function Multi:perform()
285284
end
286285

287286
function Multi:add_handle(e)
288-
self._easy = self._easy or {}
289-
self._easy[#self._easy + 1] = e
290-
return add_handle(self, e:handle())
287+
assert(self._easy.n >= 0)
288+
289+
local h = e:handle()
290+
if self._easy[h] then return self end
291+
292+
local ok, err = add_handle(self, h)
293+
if not ok then return nil, err end
294+
self._easy[h], self._easy.n = e, self._easy.n + 1
295+
return self
291296
end
292297

293298
function Multi:remove_handle(e)
294-
self._easy[#self._easy + 1] = e
295-
return remove_handle(self, e:handle())
299+
local h = e:handle()
300+
301+
if self._easy[h] then
302+
self._easy[h], self._easy.n = nil, self._easy.n - 1
303+
end
304+
assert(self._easy.n >= 0)
305+
306+
return remove_handle(self, h)
296307
end
297308

298309
end
@@ -347,27 +358,43 @@ end
347358
-------------------------------------------
348359
local Multi = class(curl.multi) do
349360

361+
local add_handle = wrap_function("add_handle")
362+
local remove_handle = wrap_function("remove_handle")
363+
350364
function Multi:__init()
351-
self._easy = {}
365+
self._easy = {n = 0}
352366
return self
353367
end
354368

355369
function Multi:iperform()
356370
return make_iterator(self, self.perform)
357371
end
358372

359-
local add_handle = wrap_function("add_handle")
360373
function Multi:add_handle(e)
361-
self._easy[#self._easy + 1] = e
362-
return add_handle(self, e:handle())
374+
assert(self._easy.n >= 0)
375+
376+
local h = e:handle()
377+
if self._easy[h] then return self end
378+
379+
local ok, err = add_handle(self, h)
380+
if not ok then return nil, err end
381+
self._easy[h], self._easy.n = e, self._easy.n + 1
382+
return self
363383
end
364384

365-
local remove_handle = wrap_function("remove_handle")
366385
function Multi:remove_handle(e)
367-
self._easy[#self._easy + 1] = e
368-
return remove_handle(self, e:handle())
386+
local h = e:handle()
387+
388+
if self._easy[h] then
389+
self._easy[h], self._easy.n = nil, self._easy.n - 1
390+
end
391+
assert(self._easy.n >= 0)
392+
393+
return remove_handle(self, h)
369394
end
370395

396+
--! @fixme Multi:info_read(true) should also remove easy handle from self._easy
397+
371398
end
372399
-------------------------------------------
373400

0 commit comments

Comments
 (0)