Skip to content

Commit 273212f

Browse files
committed
Fix. socket callback get correct cURLv3 easy object.
1 parent 0ba125d commit 273212f

File tree

2 files changed

+80
-26
lines changed

2 files changed

+80
-26
lines changed

examples/cURLv3/multi-uv.lua

+25-26
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,11 @@ local FLAGS = {
2727

2828
}
2929

30-
local trace = function() end or print
30+
local trace = true
3131

32-
local FILES, CONTEXT = {}, {}
32+
trace = trace and print or function() end
33+
34+
local CONTEXT = {}
3335

3436
function create_curl_context(sockfd)
3537
local context = {
@@ -58,22 +60,22 @@ function add_download(url, num)
5860
writefunction = file;
5961
}
6062

61-
FILES[handle] = file
63+
handle.data = file
6264

6365
curl_handle:add_handle(handle)
6466
fprintf(stderr, "Added download %s -> %s\n", url, filename);
6567
end
6668

6769
function check_multi_info()
6870
while true do
69-
local easy, ok, err = curl_handle:info_read()
71+
local easy, ok, err = curl_handle:info_read(true)
7072
if not easy then curl_handle:close() error(err) end
7173
if easy == 0 then break end
7274

7375
local context = CONTEXT[e]
7476
if context then destroy_curl_context(context) end
75-
local file = FILES[easy]
76-
if file then FILES[easy] = nil, file:close() end
77+
local file = assert(easy.data)
78+
file:close()
7779
local done_url = easy:getinfo_effective_url()
7880
easy:close()
7981
if ok then
@@ -116,29 +118,26 @@ function start_timeout(timeout_ms)
116118
timeout:stop():start(timeout_ms, 0, on_timeout)
117119
end
118120

119-
local handle_socket = function(...)
120-
local ok, err = pcall(handle_socket_impl, ...)
121-
if not ok then uv.defer(function() error(err) end) end
122-
end
123-
124-
function handle_socket_impl(easy, s, action)
125-
-- calls by curl --
121+
function handle_socket(easy, s, action)
122+
local ok, err = pcall(function()
123+
-- calls by curl --
124+
trace("CURL::SOCKET", easy, s, ACTION_NAMES[action] or action)
126125

127-
trace("CURL::SOCKET", easy, s, ACTION_NAMES[action] or action)
126+
local curl_context = CONTEXT[easy] or create_curl_context(s)
127+
CONTEXT[easy] = curl_context
128128

129-
local curl_context = CONTEXT[easy] or create_curl_context(s)
130-
CONTEXT[easy] = curl_context
129+
assert(curl_context.sockfd == s)
131130

132-
assert(curl_context.sockfd == s)
133-
134-
if action == curl.POLL_IN then
135-
curl_context.poll_handle:start(uv.READABLE, curl_perform)
136-
elseif action == curl.POLL_OUT then
137-
curl_context.poll_handle:start(uv.WRITABLE, curl_perform)
138-
elseif action == curl.POLL_REMOVE then
139-
CONTEXT[easy] = nil
140-
destroy_curl_context(curl_context)
141-
end
131+
if action == curl.POLL_IN then
132+
curl_context.poll_handle:start(uv.READABLE, curl_perform)
133+
elseif action == curl.POLL_OUT then
134+
curl_context.poll_handle:start(uv.WRITABLE, curl_perform)
135+
elseif action == curl.POLL_REMOVE then
136+
CONTEXT[easy] = nil
137+
destroy_curl_context(curl_context)
138+
end
139+
end)
140+
if not ok then uv.defer(function() error(err) end) end
142141
end
143142

144143
timeout = uv.timer()

src/lua/cURL/impl/cURL.lua

+55
Original file line numberDiff line numberDiff line change
@@ -571,6 +571,61 @@ function Multi:info_read(...)
571571
end
572572
end
573573

574+
function wrap_callback(...)
575+
local n = select("#", ...)
576+
local fn, ctx, has_ctx
577+
if n >= 2 then
578+
has_ctx, fn, ctx = true, assert(...)
579+
else
580+
fn = assert(...)
581+
if type(fn) ~= "function" then
582+
has_ctx, fn, ctx = true, assert(fn.socket), fn
583+
end
584+
end
585+
if has_ctx then
586+
return function(...) return fn(ctx, ...) end
587+
end
588+
return function(...) return fn(...) end
589+
end
590+
591+
function wrap_socketfunction(self, cb)
592+
return function(h, ...)
593+
local e = self._easy[h]
594+
if e then return cb(e, ...) end
595+
return 0
596+
end
597+
end
598+
599+
local setopt_socketfunction = wrap_function("setopt_socketfunction")
600+
function Multi:setopt_socketfunction(...)
601+
local cb = wrap_callback(...)
602+
603+
return setopt_socketfunction(wrap_socketfunction(self, cb))
604+
end
605+
606+
local setopt = wrap_function("setopt")
607+
function Multi:setopt(k, v)
608+
if type(k) == 'table' then
609+
local t = k
610+
611+
local socketfunction = t.socketfunction or t[curl.OPT_SOCKETFUNCTION]
612+
if socketfunction then
613+
t = clone(t)
614+
local fn = wrap_socketfunction(self, socketfunction)
615+
if t.socketfunction then t.socketfunction = fn end
616+
if t[curl.OPT_SOCKETFUNCTION] then t[curl.OPT_SOCKETFUNCTION] = fn end
617+
end
618+
619+
return setopt(self, t)
620+
end
621+
622+
if k == curl.OPT_SOCKETFUNCTION then
623+
return self:setopt_httppost(wrap_socketfunction(v))
624+
end
625+
626+
return setopt(self, k, v)
627+
end
628+
574629
end
575630
-------------------------------------------
576631

0 commit comments

Comments
 (0)