Skip to content

Commit 76336c5

Browse files
committed
Merge pull request #33 from moteus/master
Add. Ability to add easy handle during iteration.(close #25)
2 parents 0568097 + ba7aede commit 76336c5

5 files changed

Lines changed: 148 additions & 12 deletions

File tree

.travis.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ script:
3131
- lunit.sh test_safe.lua
3232
- lunit.sh test_form.lua
3333
- lunit.sh test_pause02.c.lua
34+
- lunit.sh test_curl.lua
3435

3536
after_success:
3637
- coveralls -b .. -r ..

examples/cURLv3/multi3.lua

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
local cURL = require("cURL")
2+
3+
local urls = {
4+
"http://httpbin.org/get?key=1",
5+
"http://httpbin.org/get?key=2",
6+
"http://httpbin.org/get?key=3",
7+
"http://httpbin.org/get?key=4",
8+
}
9+
10+
local function next_easy()
11+
local url = table.remove(urls, 1)
12+
if url then return cURL.easy{url = url} end
13+
end
14+
15+
m = cURL.multi():add_handle(next_easy())
16+
for data, type, easy in m:iperform() do
17+
18+
if type == "done" or type == "error" then
19+
print("Done", easy:getinfo_effective_url(), ":", data)
20+
easy:close()
21+
easy = next_easy()
22+
if easy then m:add_handle(easy) end
23+
end
24+
25+
if type == "data" then print(data) end
26+
27+
end
28+

lakefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ target('test', install, function()
2929
run_test('test_safe.lua')
3030
run_test('test_form.lua')
3131
run_test('test_pause02.c.lua')
32+
run_test('test_curl.lua')
3233

3334
if not test_summary() then
3435
quit("test fail")

src/lua/cURL/impl/cURL.lua

Lines changed: 29 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,8 @@ local function wrap_setopt_flags(k, flags)
3636
end
3737
end
3838

39-
local function make_iterator(self, perform)
40-
local curl = require "lcurl.safe"
41-
42-
local buffers = {resp = {}, _ = {}} do
39+
local function new_buffers()
40+
local buffers = {resp = {}, _ = {}}
4341

4442
function buffers:append(e, ...)
4543
local resp = assert(e:getinfo_response_code())
@@ -62,27 +60,43 @@ local function make_iterator(self, perform)
6260
end
6361
end
6462

65-
end
63+
return buffers
64+
end
6665

67-
local remain = self._easy.n
68-
for h, e in pairs(self._easy) do
69-
if h ~= 'n' then
70-
e:setopt_writefunction (function(str) buffers:append(e, "data", str) end)
71-
e:setopt_headerfunction(function(str) buffers:append(e, "header", str) end)
66+
local function make_iterator(self, perform)
67+
local curl = require "lcurl.safe"
68+
69+
local buffers = new_buffers()
70+
71+
-- reset callbacks to all easy handles
72+
local function reset_easy(self)
73+
if not self._easy_mark then -- that means we have some new easy handles
74+
for h, e in pairs(self._easy) do if h ~= 'n' then
75+
e:setopt_writefunction (function(str) buffers:append(e, "data", str) end)
76+
e:setopt_headerfunction(function(str) buffers:append(e, "header", str) end)
77+
end end
78+
self._easy_mark = true
7279
end
80+
return self._easy.n
7381
end
7482

83+
if 0 == reset_easy(self) then return end
84+
7585
assert(perform(self))
7686

7787
return function()
88+
-- we can add new handle during iteration
89+
local remain = reset_easy(self)
90+
91+
-- wait next event
7892
while true do
7993
local e, t = buffers:next()
8094
if t then return t[2], t[1], e end
8195
if remain == 0 then break end
8296

8397
self:wait()
8498

85-
local n, err = assert(perform(self))
99+
local n = assert(perform(self))
86100

87101
if n <= remain then
88102
while true do
@@ -95,8 +109,9 @@ local function make_iterator(self, perform)
95109
else buffers:append(e, "error", err) end
96110
self:remove_handle(e)
97111
end
98-
remain = n
99112
end
113+
114+
remain = n
100115
end
101116
end
102117
end
@@ -502,6 +517,8 @@ function Multi:add_handle(e)
502517
local ok, err = add_handle(self, h)
503518
if not ok then return nil, err end
504519
self._easy[h], self._easy.n = e, self._easy.n + 1
520+
self._easy_mark = nil
521+
505522
return self
506523
end
507524

test/test_curl.lua

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
local HAS_RUNNER = not not lunit
2+
local lunit = require "lunit"
3+
local TEST_CASE = assert(lunit.TEST_CASE)
4+
local skip = lunit.skip or function() end
5+
6+
local curl = require "cURL"
7+
local scurl = require "cURL.safe"
8+
local json = require "dkjson"
9+
local fname = "./test.download"
10+
11+
local ENABLE = true
12+
13+
local _ENV = TEST_CASE'multi_iterator' if ENABLE then
14+
15+
local url = "http://httpbin.org/get"
16+
17+
local c, t, m
18+
19+
local function json_data()
20+
return json.decode(table.concat(t))
21+
end
22+
23+
function setup()
24+
t = {}
25+
m = assert(scurl.multi())
26+
end
27+
28+
function teardown()
29+
if m then m:close() end
30+
if c then c:close() end
31+
m, c, t = nil
32+
end
33+
34+
function test_add_handle()
35+
36+
local base_url = 'http://httpbin.org/get?key='
37+
local urls = {
38+
base_url .. "1",
39+
base_url .. "2",
40+
"###" .. base_url .. "3",
41+
base_url .. "4",
42+
base_url .. "5",
43+
}
44+
45+
local i = 0
46+
local function next_easy()
47+
i = i + 1
48+
local url = urls[i]
49+
if url then
50+
c = assert(scurl.easy{url = url})
51+
t = {}
52+
return c
53+
end
54+
end
55+
56+
m = assert_equal(m, m:add_handle(next_easy()))
57+
58+
for data, type, easy in m:iperform() do
59+
60+
if type == "done" or type == "error" then
61+
assert_equal(urls[i], easy:getinfo_effective_url())
62+
assert_equal(easy, c)
63+
easy:close()
64+
c = nil
65+
66+
if i == 3 then
67+
assert_equal(curl.error(curl.ERROR_EASY, curl.E_UNSUPPORTED_PROTOCOL), data)
68+
else
69+
local data = json_data()
70+
assert_table(data.args)
71+
assert_equal(tostring(i), data.args.key)
72+
end
73+
74+
easy = next_easy()
75+
if easy then m:add_handle(easy) end
76+
end
77+
78+
if type == "data" then table.insert(t, data) end
79+
80+
end
81+
82+
assert_equal(#urls + 1, i)
83+
assert_nil(c)
84+
end
85+
86+
end
87+
88+
89+
if not HAS_RUNNER then lunit.run() end

0 commit comments

Comments
 (0)