Skip to content

Commit a1d80a7

Browse files
Allow setting global hooks to modify Easy object
1 parent 11b6bb7 commit a1d80a7

File tree

2 files changed

+63
-1
lines changed

2 files changed

+63
-1
lines changed

src/Downloads.jl

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ using ArgTools
2020
include("Curl/Curl.jl")
2121
using .Curl
2222

23-
export download, request, Downloader, Response, RequestError
23+
export download, request, Downloader, Response, RequestError, pushhook!, deletehook!
2424

2525
## public API types ##
2626

@@ -65,6 +65,44 @@ const DOWNLOAD_LOCK = ReentrantLock()
6565
const DOWNLOADER = Ref{Union{Downloader, Nothing}}(nothing)
6666
const EASY_HOOK = Ref{Union{Function, Nothing}}(nothing)
6767

68+
## Allow for a set of global hooks that can customize each download (via setting parameters on the
69+
## `Easy` object associated with a request
70+
const HookKey = Int
71+
current_key = 0
72+
GlobalHookEntry = Tuple{HookKey, Function}
73+
const GLOBAL_HOOK_LOCK = ReentrantLock()
74+
const GLOBAL_HOOKS = Array{GlobalHookEntry,1}(undef, 0)
75+
76+
## Add hook
77+
function pushhook!(hook::Function) :: HookKey
78+
global current_key
79+
key = -1
80+
lock(GLOBAL_HOOK_LOCK) do
81+
key = current_key
82+
push!(GLOBAL_HOOKS, (key, hook))
83+
current_key += 1
84+
end
85+
return key
86+
end
87+
88+
function deletehook!(key::HookKey)
89+
keep = x -> x[1] != key
90+
lock(GLOBAL_HOOK_LOCK) do
91+
count(keep, GLOBAL_HOOKS) < length(GLOBAL_HOOKS) ||
92+
warn("Downloads.jl: Hook key $(key) not found in global hooks")
93+
filter!(keep, GLOBAL_HOOKS)
94+
end
95+
end
96+
97+
function apply_global_hooks(easy::Easy, info::NamedTuple)
98+
lock(GLOBAL_HOOK_LOCK) do
99+
for (_,h) in GLOBAL_HOOKS
100+
h(easy, info)
101+
end
102+
end
103+
end
104+
105+
68106
"""
69107
struct Response
70108
proto :: String
@@ -358,6 +396,8 @@ function request(
358396
progress !== nothing && enable_progress(easy)
359397
set_ca_roots(downloader, easy)
360398
info = (url = url, method = method, headers = headers)
399+
400+
apply_global_hooks(easy, info)
361401
easy_hook(downloader, easy, info)
362402

363403
# do the request

test/runtests.jl

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,27 @@
11
include("setup.jl")
22

33
@testset "Downloads.jl" begin
4+
@testset "Global easy hooks" begin
5+
trip_wire = 0
6+
original_hook_count = length(Downloads.GLOBAL_HOOKS)
7+
url = "$server/get"
8+
hook = (easy, info) -> trip_wire += 1
9+
key1 = pushhook!(hook)
10+
_ = download_body(url)
11+
@test trip_wire == 1
12+
key2 = pushhook!(hook)
13+
_ = download_body(url)
14+
@test trip_wire == 3
15+
deletehook!(key1)
16+
_ = download_body(url)
17+
@test trip_wire == 4
18+
deletehook!(key2)
19+
_ = download_body(url)
20+
@test trip_wire == 4
21+
22+
@test length(Downloads.GLOBAL_HOOKS) == original_hook_count
23+
end
24+
#=
425
@testset "libcurl configuration" begin
526
julia = "$(VERSION.major).$(VERSION.minor)"
627
@test Curl.USER_AGENT == "curl/$(Curl.CURL_VERSION) julia/$julia"
@@ -560,6 +581,7 @@ include("setup.jl")
560581
@test Downloads.content_length(["Accept"=>"*/*",]) === nothing
561582
@test Downloads.content_length(["Accept"=>"*/*", "Content-Length"=>"100"]) == 100
562583
end
584+
=#
563585
end
564586

565587
Downloads.DOWNLOADER[] = nothing

0 commit comments

Comments
 (0)