@@ -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,43 @@ 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+ key = - 1
79+ lock (GLOBAL_HOOK_LOCK) do
80+ key = current_key
81+ push! (GLOBAL_HOOKS, (key, hook))
82+ current_key += 1
83+ end
84+ return key
85+ end
86+
87+ function deletehook! (key:: HookKey )
88+ keep = x -> x[1 ] != key
89+ lock (GLOBAL_HOOK_LOCK) do
90+ count (keep, GLOBAL_HOOKS) < length (GLOBAL_HOOK_LOCK) ||
91+ warn (" Downloads.jl: Hook key $(key) not found in global hooks" )
92+ filter! (keep, GLOBAL_HOOKS)
93+ end
94+ end
95+
96+ function apply_global_hooks (easy:: Easy , info:: NamedTuple )
97+ lock (GLOBAL_HOOK_LOCK) do
98+ for (_,h) in GLOBAL_HOOKS
99+ h (easy, info)
100+ end
101+ end
102+ end
103+
104+
68105"""
69106 struct Response
70107 proto :: String
@@ -358,6 +395,8 @@ function request(
358395 progress != = nothing && enable_progress (easy)
359396 set_ca_roots (downloader, easy)
360397 info = (url = url, method = method, headers = headers)
398+
399+ apply_global_hooks (easy, info)
361400 easy_hook (downloader, easy, info)
362401
363402 # do the request
0 commit comments