@@ -7,6 +7,8 @@ More generally, the module exports functions and types that provide lower-level
7
7
for file downloading:
8
8
- [`download`](@ref) — download a file from a URL, erroring if it can't be downloaded
9
9
- [`request`](@ref) — request a URL, returning a `Response` object indicating success
10
+ - [`pushhook!`](@ref) — add a hook which allows for customizing downloading parameters
11
+ - [`deletehook!`](@ref) — remove a previously added parameter customization hook
10
12
- [`Response`](@ref) — a type capturing the status and other metadata about a request
11
13
- [`RequestError`](@ref) — an error type thrown by `download` and `request` on error
12
14
- [`Downloader`](@ref) — an object encapsulating shared resources for downloading
@@ -77,30 +79,75 @@ const EASY_HOOK = Ref{Union{Function, Nothing}}(nothing)
77
79
# # Allow for a set of global hooks that can customize each download (via setting parameters on the
78
80
# # `Easy` object associated with a request
79
81
const HookKey = Int
80
- current_key = 0
82
+ CURRENT_KEY = 0
81
83
GlobalHookEntry = Tuple{HookKey, Function}
82
84
const GLOBAL_HOOK_LOCK = ReentrantLock ()
83
85
const GLOBAL_HOOKS = Array {GlobalHookEntry,1} (undef, 0 )
84
86
85
87
# # Add hook
88
+ """
89
+ pushhook!(hook) -> key
90
+
91
+ hook :: Function
92
+ key :: HookKey
93
+ Add a hook to customize download parameters for all downloads.
94
+
95
+ The signature `hook` should be `(easy::Easy, info::Dict) -> Nothing``.
96
+ Mulitple hooks can be added with repeated calls to `pushhook!`. Hooks are
97
+ applied in the order they were added.
98
+
99
+ The returned `key` maybe used to remove a previously added `hook` cf. [deletehook!](@ref)
100
+
101
+ Examples:
102
+ ```jl
103
+ # define hook
104
+ hook = (easy, info) -> begin
105
+ # allow for long pauses during downloads (perhaps for malware scanning)
106
+ setopt(easy, Downloads.Curl.CURLOPT_LOW_SPEED_LIMIT, 1 #= bytes =#)
107
+ setopt(easy, Downloads.Curl.CURLOPT_LOW_SPEED_TIME , 200 #= seconds =#)
108
+
109
+ # other possibilities
110
+ # set ca_roots
111
+ # disable certificate verification
112
+ # block or rewrite URLs
113
+
114
+ end
115
+
116
+ # add hook
117
+ key = pushhook!(hook)
118
+
119
+ # would fail with default download parameters...
120
+ download("https://httpbingo.julialang.org/delay/40", "test.txt")
121
+
122
+ # cleanup
123
+ deletehook!(key)
124
+ ```
125
+ """
86
126
function pushhook! (hook:: Function ) :: HookKey
87
- global current_key
127
+ global CURRENT_KEY
88
128
key = - 1
89
129
lock (GLOBAL_HOOK_LOCK) do
90
- key = current_key
130
+ key = CURRENT_KEY
91
131
push! (GLOBAL_HOOKS, (key, hook))
92
- current_key += 1
132
+ CURRENT_KEY += 1
93
133
end
94
- return key
134
+ key
95
135
end
96
136
137
+ """
138
+ deletehook!(key)
139
+ key :: HookKey
140
+
141
+ Remove a hook previously added with [`pushhook!`](@ref).
142
+ """
97
143
function deletehook! (key:: HookKey )
98
144
keep = x -> x[1 ] != key
99
145
lock (GLOBAL_HOOK_LOCK) do
100
146
count (keep, GLOBAL_HOOKS) < length (GLOBAL_HOOKS) ||
101
147
warn (" Downloads.jl: Hook key $(key) not found in global hooks" )
102
148
filter! (keep, GLOBAL_HOOKS)
103
149
end
150
+ nothing
104
151
end
105
152
106
153
function apply_global_hooks (easy:: Easy , info:: NamedTuple )
@@ -109,6 +156,7 @@ function apply_global_hooks(easy::Easy, info::NamedTuple)
109
156
h (easy, info)
110
157
end
111
158
end
159
+ nothing
112
160
end
113
161
114
162
0 commit comments