@@ -20,7 +20,7 @@ using ArgTools
2020include (" Curl/Curl.jl" )
2121using . Curl
2222
23- export download, request, Downloader, Response, RequestError, default_downloader!
23+ export download, request, Downloader, Response, RequestError, default_downloader!, pushhook!, deletehook!
2424
2525# # public API types ##
2626
@@ -74,6 +74,44 @@ It is expected to be function taking two arguments: an `Easy` struct and an
7474"""
7575const EASY_HOOK = Ref {Union{Function, Nothing}} (nothing )
7676
77+ # # Allow for a set of global hooks that can customize each download (via setting parameters on the
78+ # # `Easy` object associated with a request
79+ const HookKey = Int
80+ current_key = 0
81+ GlobalHookEntry = Tuple{HookKey, Function}
82+ const GLOBAL_HOOK_LOCK = ReentrantLock ()
83+ const GLOBAL_HOOKS = Array {GlobalHookEntry,1} (undef, 0 )
84+
85+ # # Add hook
86+ function pushhook! (hook:: Function ) :: HookKey
87+ global current_key
88+ key = - 1
89+ lock (GLOBAL_HOOK_LOCK) do
90+ key = current_key
91+ push! (GLOBAL_HOOKS, (key, hook))
92+ current_key += 1
93+ end
94+ return key
95+ end
96+
97+ function deletehook! (key:: HookKey )
98+ keep = x -> x[1 ] != key
99+ lock (GLOBAL_HOOK_LOCK) do
100+ count (keep, GLOBAL_HOOKS) < length (GLOBAL_HOOKS) ||
101+ warn (" Downloads.jl: Hook key $(key) not found in global hooks" )
102+ filter! (keep, GLOBAL_HOOKS)
103+ end
104+ end
105+
106+ function apply_global_hooks (easy:: Easy , info:: NamedTuple )
107+ lock (GLOBAL_HOOK_LOCK) do
108+ for (_,h) in GLOBAL_HOOKS
109+ h (easy, info)
110+ end
111+ end
112+ end
113+
114+
77115"""
78116 struct Response
79117 proto :: String
@@ -367,6 +405,8 @@ function request(
367405 progress != = nothing && enable_progress (easy)
368406 set_ca_roots (downloader, easy)
369407 info = (url = url, method = method, headers = headers)
408+
409+ apply_global_hooks (easy, info)
370410 easy_hook (downloader, easy, info)
371411
372412 # do the request
0 commit comments