5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
|
# File 'lib/puppet/functions/complyadm/download_image.rb', line 5
Puppet::Functions.create_function(:'complyadm::download_image') do
dispatch :download_image do
param 'String[1]', :image_url
param 'String[1]', :dest_path
end
def download_image(image_url, dest_path)
request_uri = URI(image_url)
request_download(request_uri, dest_path)
end
def request_download(src_uri, dest_path)
image_filename = File.basename(dest_path)
Net::HTTP.start(src_uri.host, src_uri.port, use_ssl: true) do |http|
request = Net::HTTP::Get.new src_uri
out_message("Downloading '#{src_uri}' to '#{dest_path}'")
http.request request do |response|
case response
when Net::HTTPSuccess then
write_image_to_disk(response, dest_path)
when Net::HTTPRedirection then
max_redirects = 50
redirects_followed = 0
while redirects_followed < max_redirects
redir_uri = redirect_uri(response, src_uri)
Net::HTTP.start(redir_uri.host, redir_uri.port, use_ssl: true) do |redir_http|
redirect_request = Net::HTTP::Get.new redir_uri
out_message("Location for '#{image_filename}' has changed, following redirect to '#{redir_uri}'")
redir_http.request redirect_request do |redirect_response|
case redirect_response
when Net::HTTPSuccess then
write_image_to_disk(redirect_response, dest_path)
break
when Net::HTTPRedirection then
redirects_followed += 1
next
when Net::HTTPNotFound then
raise "Could not find '#{image_filename}' to download from '#{redir_uri.host}'\n#{redirect_response.body}"
else
raise "Problem following redirect to download '#{image_filename}' from '#{redir_uri.host}'\n#{redirect_response.body}"
end
end
rescue Exception => e
raise "Problem with HTTP request to follow redirect and download '#{image_filename}' from '#{redir_uri.host}': #{e}"
end
end
raise "Exceeded maximum 50 redirects attempting to download image from '#{src_uri}'." if redirects_followed >= max_redirects
when Net::HTTPNotFound then
raise "Could not find '#{image_filename}' to download from '#{src_uri.host}'\n#{response.body}"
else
raise "Problem downloading #{image_filename} from '#{src_uri.host}'\n#{response.body}"
end
end
rescue Exception => e
raise "There was a problem with the HTTP request to download '#{image_filename}' from '#{src_uri.host}': #{e}"
end
end
def write_image_to_disk(response, dest_path)
dest_dir = File.dirname(dest_path)
FileUtils.mkdir_p(dest_dir) unless File.exist?(dest_dir)
File.open dest_path, 'w' do |file|
response.read_body do |chunk|
file.write chunk
end
end
end
def redirect_uri(response, uri)
location = response['location']
location_uri = URI.parse(location)
URI(location_uri.relative? ? uri.to_s + location : uri)
end
def out_message(message)
call_function('out::message', message)
end
end
|