Skip to content

Commit

Permalink
Allow setting global hooks to modify Easy object
Browse files Browse the repository at this point in the history
  • Loading branch information
habemus-papadum committed Oct 27, 2022
1 parent 11b6bb7 commit a1d80a7
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 1 deletion.
42 changes: 41 additions & 1 deletion src/Downloads.jl
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ using ArgTools
include("Curl/Curl.jl")
using .Curl

export download, request, Downloader, Response, RequestError
export download, request, Downloader, Response, RequestError, pushhook!, deletehook!

## public API types ##

Expand Down Expand Up @@ -65,6 +65,44 @@ const DOWNLOAD_LOCK = ReentrantLock()
const DOWNLOADER = Ref{Union{Downloader, Nothing}}(nothing)
const EASY_HOOK = Ref{Union{Function, Nothing}}(nothing)

## Allow for a set of global hooks that can customize each download (via setting parameters on the
## `Easy` object associated with a request
const HookKey = Int
current_key = 0
GlobalHookEntry = Tuple{HookKey, Function}
const GLOBAL_HOOK_LOCK = ReentrantLock()
const GLOBAL_HOOKS = Array{GlobalHookEntry,1}(undef, 0)

## Add hook
function pushhook!(hook::Function) :: HookKey
global current_key
key = -1
lock(GLOBAL_HOOK_LOCK) do
key = current_key
push!(GLOBAL_HOOKS, (key, hook))
current_key += 1
end
return key
end

function deletehook!(key::HookKey)
keep = x -> x[1] != key
lock(GLOBAL_HOOK_LOCK) do
count(keep, GLOBAL_HOOKS) < length(GLOBAL_HOOKS) ||
warn("Downloads.jl: Hook key $(key) not found in global hooks")
filter!(keep, GLOBAL_HOOKS)
end
end

function apply_global_hooks(easy::Easy, info::NamedTuple)
lock(GLOBAL_HOOK_LOCK) do
for (_,h) in GLOBAL_HOOKS
h(easy, info)
end
end
end


"""
struct Response
proto :: String
Expand Down Expand Up @@ -358,6 +396,8 @@ function request(
progress !== nothing && enable_progress(easy)
set_ca_roots(downloader, easy)
info = (url = url, method = method, headers = headers)

apply_global_hooks(easy, info)
easy_hook(downloader, easy, info)

# do the request
Expand Down
22 changes: 22 additions & 0 deletions test/runtests.jl
Original file line number Diff line number Diff line change
@@ -1,6 +1,27 @@
include("setup.jl")

@testset "Downloads.jl" begin
@testset "Global easy hooks" begin
trip_wire = 0
original_hook_count = length(Downloads.GLOBAL_HOOKS)
url = "$server/get"
hook = (easy, info) -> trip_wire += 1
key1 = pushhook!(hook)
_ = download_body(url)
@test trip_wire == 1
key2 = pushhook!(hook)
_ = download_body(url)
@test trip_wire == 3
deletehook!(key1)
_ = download_body(url)
@test trip_wire == 4
deletehook!(key2)
_ = download_body(url)
@test trip_wire == 4

@test length(Downloads.GLOBAL_HOOKS) == original_hook_count
end
#=
@testset "libcurl configuration" begin
julia = "$(VERSION.major).$(VERSION.minor)"
@test Curl.USER_AGENT == "curl/$(Curl.CURL_VERSION) julia/$julia"
Expand Down Expand Up @@ -560,6 +581,7 @@ include("setup.jl")
@test Downloads.content_length(["Accept"=>"*/*",]) === nothing
@test Downloads.content_length(["Accept"=>"*/*", "Content-Length"=>"100"]) == 100
end
=#
end

Downloads.DOWNLOADER[] = nothing
Expand Down

0 comments on commit a1d80a7

Please sign in to comment.