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