Skip to content

Commit a7ea0cb

Browse files
rectify control of read callback
1 parent c7e3409 commit a7ea0cb

File tree

3 files changed

+14
-42
lines changed

3 files changed

+14
-42
lines changed

src/Curl/Easy.jl

Lines changed: 12 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
mutable struct Easy
22
handle :: Ptr{Cvoid}
3-
input :: Union{Vector{UInt8},Nothing}
3+
input :: IO
44
ready :: Threads.Event
55
seeker :: Union{Function,Nothing}
66
output :: IO
@@ -9,17 +9,17 @@ mutable struct Easy
99
res_hdrs :: Vector{String}
1010
code :: CURLcode
1111
errbuf :: Vector{UInt8}
12+
readbuf :: Vector{UInt8}
1213
end
1314

14-
const EMPTY_BYTE_VECTOR = UInt8[]
15-
1615
function Easy(
17-
output::IO,
18-
progress::Union{Function,Nothing},
16+
input :: IO,
17+
output :: IO,
18+
progress :: Union{Function,Nothing},
1919
)
2020
easy = Easy(
2121
curl_easy_init(),
22-
EMPTY_BYTE_VECTOR,
22+
input,
2323
Threads.Event(),
2424
nothing,
2525
output,
@@ -28,6 +28,7 @@ function Easy(
2828
String[],
2929
typemax(CURLcode),
3030
zeros(UInt8, CURL_ERROR_SIZE),
31+
zeros(UInt8, 0),
3132
)
3233
finalizer(done!, easy)
3334
add_callbacks(easy)
@@ -293,44 +294,22 @@ function header_callback(
293294
easy_p :: Ptr{Cvoid},
294295
)::Csize_t
295296
easy = unsafe_pointer_to_objref(easy_p)::Easy
296-
n = size * count
297+
n = size*count
297298
hdr = unsafe_string(data, n)
298299
push!(easy.res_hdrs, hdr)
299300
return n
300301
end
301302

302-
# feed data to read_callback
303-
function upload_data(easy::Easy, input::IO)
304-
while true
305-
data = eof(input) ? nothing : readavailable(input)
306-
easy.input === nothing && break
307-
easy.input = data
308-
curl_easy_pause(easy.handle, Curl.CURLPAUSE_CONT)
309-
wait(easy.ready)
310-
easy.input === nothing && break
311-
easy.ready = Threads.Event()
312-
end
313-
end
314-
315303
function read_callback(
316304
data :: Ptr{Cchar},
317305
size :: Csize_t,
318306
count :: Csize_t,
319307
easy_p :: Ptr{Cvoid},
320308
)::Csize_t
321309
easy = unsafe_pointer_to_objref(easy_p)::Easy
322-
buf = easy.input
323-
if buf === nothing
324-
notify(easy.ready)
325-
return 0 # done uploading
326-
end
327-
if isempty(buf)
328-
notify(easy.ready)
329-
return CURL_READFUNC_PAUSE # wait for more data
330-
end
331-
n = min(size * count, length(buf))
332-
ccall(:memcpy, Ptr{Cvoid}, (Ptr{Cvoid}, Ptr{Cvoid}, Csize_t), data, buf, n)
333-
deleteat!(buf, 1:n)
310+
eof(easy.input) && return 0
311+
n = readbytes!(easy.input, easy.readbuf, size*count)
312+
ccall(:memcpy, Ptr{Cvoid}, (Ptr{Cvoid}, Ptr{Cvoid}, Csize_t), data, easy.readbuf, n)
334313
return n
335314
end
336315

@@ -347,7 +326,7 @@ function seek_callback(
347326
easy.seeker === nothing && return CURL_SEEKFUNC_CANTSEEK
348327
try easy.seeker(offset)
349328
catch err
350-
@async @error("seek_callback: seeker failed", err)
329+
@async @error("seek_callback: seek failed", err)
351330
return CURL_SEEKFUNC_FAIL
352331
end
353332
return CURL_SEEKFUNC_OK

src/Curl/Multi.jl

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,6 @@ function check_multi_info(multi::Multi)
8585
easy = unsafe_pointer_to_objref(easy_p_ref[])::Easy
8686
@assert easy_handle == easy.handle
8787
easy.code = message.code
88-
easy.input = nothing
8988
notify(easy.ready)
9089
else
9190
@async @error("curl_multi_info_read: unknown message", message)

src/Downloads.jl

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -308,7 +308,7 @@ function request(
308308
progress = p_func(progress, input, output)
309309
arg_read(input) do input
310310
arg_write(output) do output
311-
with_handle(Easy(output, progress)) do easy
311+
with_handle(Easy(input, output, progress)) do easy
312312
# setup the request
313313
set_url(easy, url)
314314
set_timeout(easy, timeout)
@@ -343,13 +343,7 @@ function request(
343343

344344
# do the request
345345
add_handle(downloader.multi, easy)
346-
try # ensure handle is removed
347-
@sync begin
348-
if have_input
349-
@async upload_data(easy, input)
350-
end
351-
@async wait(easy.ready)
352-
end
346+
try wait(easy.ready) # can this throw?
353347
finally
354348
remove_handle(downloader.multi, easy)
355349
end

0 commit comments

Comments
 (0)