@@ -20,7 +20,7 @@ using ArgTools
2020include (" Curl/Curl.jl" )
2121using . 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()
6565const DOWNLOADER = Ref {Union{Downloader, Nothing}} (nothing )
6666const 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
0 commit comments