down 5.2.1 → 5.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1095c57cf19a452627af18374bc2a5b8db488edf1b0cb54ff52463bb3cd80cc9
4
- data.tar.gz: 6c2d515848f66b359caa03270d8ab7e9250468ee945f07d954f71dfeb9aea157
3
+ metadata.gz: eab7260ae741338fdb881a861e39cd7c2ed3a66588c52c4e18aed72c30db765a
4
+ data.tar.gz: 10d5e380f74c6cc99abc6b7be22cdf5a6d34e3641231242376df5a4cffc6fbcc
5
5
  SHA512:
6
- metadata.gz: b4dd38131e47339dae85cf1ed0b2cf903de034a25a262b10588590774fe5904d46d8ee59415dbaa7a8ba997039da09339f7c47f22666d4fe0ed53da222a14172
7
- data.tar.gz: a07b8d1eb3a4621f92d5547e45960861cd3000f609bc171631cc88138980715545463244ce8e4a1479c1bab309f1c1e76b1401c0b9d267f486784fc8355a7a97
6
+ metadata.gz: 0bbd0074ffeba8a93ab19a26d8a28e2761797d01ac348820a9b1342532daae12b9023de78bea2a20108183da0152a964e8077629653567be15e0d152dccbf7af
7
+ data.tar.gz: c3084685dc5e5115cf8843002ed5a656a89a850747a0f0f767aca99a88abe2b13a3f11cb99706f18721eaaa8cde468f47662028e36ebc4bf159a1395e4edda99
data/CHANGELOG.md CHANGED
@@ -1,3 +1,23 @@
1
+ ## 5.3.0 (2022-02-20)
2
+
3
+ * Add `:extension` argument to `Down.download` for overriding tempfile extension (@razum2um)
4
+
5
+ * Normalize response header names for http.rb and wget backends (@zarqman)
6
+
7
+ ## 5.2.4 (2021-09-12)
8
+
9
+ * Keep original cookies between redirections (@antprt)
10
+
11
+ ## 5.2.3 (2021-08-03)
12
+
13
+ * Bump addressable version requirement to 2.8+ to remediate vulnerability (@aldodelgado)
14
+
15
+ ## 5.2.2 (2021-05-27)
16
+
17
+ * Add info about received content length in `Down::TooLarge` error (@evheny0)
18
+
19
+ * Relax http.rb constraint to allow versions 5.x (@mgrunberg)
20
+
1
21
  ## 5.2.1 (2021-04-26)
2
22
 
3
23
  * Raise `Down::NotModified` on 304 response status in `Down::NetHttp#open` (@ellafeldmann)
data/README.md CHANGED
@@ -63,6 +63,13 @@ Down.download("http://example.com/image.jpg", destination: "/path/to/destination
63
63
  In this case `Down.download` won't have any return value, so if you need a File
64
64
  object you'll have to create it manually.
65
65
 
66
+ You can also keep the tempfile, but override the extension:
67
+
68
+ ```rb
69
+ tempfile = Down.download("http://example.com/some/file", extension: "txt")
70
+ File.extname(tempfile.path) #=> ".txt"
71
+ ```
72
+
66
73
  ### Basic authentication
67
74
 
68
75
  `Down.download` and `Down.open` will automatically detect and apply HTTP basic
@@ -157,7 +164,7 @@ You can access the response status and headers of the HTTP request that was made
157
164
  ```rb
158
165
  remote_file = Down.open("http://example.com/image.jpg")
159
166
  remote_file.data[:status] #=> 200
160
- remote_file.data[:headers] #=> { ... }
167
+ remote_file.data[:headers] #=> { "Content-Type" => "image/jpeg", ... } (header names are normalized)
161
168
  remote_file.data[:response] # returns the response object
162
169
  ```
163
170
 
@@ -252,10 +259,10 @@ Down.open("...")
252
259
  ### Down::NetHttp
253
260
 
254
261
  The `Down::NetHttp` backend implements downloads using [open-uri] and
255
- [Net::HTTP].
262
+ [Net::HTTP] standard libraries.
256
263
 
257
264
  ```rb
258
- gem "down", "~> 4.4"
265
+ gem "down", "~> 5.0"
259
266
  ```
260
267
  ```rb
261
268
  require "down/net_http"
@@ -371,8 +378,8 @@ net_http.open("http://example.com/image.jpg")
371
378
  The `Down::Http` backend implements downloads using the [http.rb] gem.
372
379
 
373
380
  ```rb
374
- gem "down", "~> 4.4"
375
- gem "http", "~> 4.0"
381
+ gem "down", "~> 5.0"
382
+ gem "http", "~> 5.0"
376
383
  ```
377
384
  ```rb
378
385
  require "down/http"
@@ -441,7 +448,7 @@ The `Down::Wget` backend implements downloads using the `wget` command line
441
448
  utility.
442
449
 
443
450
  ```rb
444
- gem "down", "~> 4.4"
451
+ gem "down", "~> 5.0"
445
452
  gem "posix-spawn" # omit if on JRuby
446
453
  gem "http_parser.rb"
447
454
  ```
data/down.gemspec CHANGED
@@ -15,14 +15,19 @@ Gem::Specification.new do |spec|
15
15
  spec.files = Dir["README.md", "LICENSE.txt", "CHANGELOG.md", "*.gemspec", "lib/**/*.rb"]
16
16
  spec.require_path = "lib"
17
17
 
18
- spec.add_dependency "addressable", "~> 2.5"
18
+ spec.add_dependency "addressable", "~> 2.8"
19
19
 
20
20
  spec.add_development_dependency "minitest", "~> 5.8"
21
21
  spec.add_development_dependency "mocha", "~> 1.5"
22
22
  spec.add_development_dependency "rake"
23
- spec.add_development_dependency "http", "~> 4.3"
23
+ # http 5.0 drop support of ruby 2.3 and 2.4. We still support those versions.
24
+ if RUBY_VERSION >= "2.5"
25
+ spec.add_development_dependency "http", "~> 5.0"
26
+ else
27
+ spec.add_development_dependency "http", "~> 4.3"
28
+ end
24
29
  spec.add_development_dependency "posix-spawn" unless RUBY_ENGINE == "jruby"
25
- spec.add_development_dependency "http_parser.rb"
30
+ spec.add_development_dependency "http_parser.rb" unless RUBY_ENGINE == "jruby"
26
31
  spec.add_development_dependency "docker-api"
27
32
  spec.add_development_dependency "warning" if RUBY_VERSION >= "2.4"
28
33
  end
data/lib/down/backend.rb CHANGED
@@ -29,5 +29,12 @@ module Down
29
29
 
30
30
  nil
31
31
  end
32
+
33
+ def normalize_headers(response_headers)
34
+ response_headers.inject({}) do |headers, (downcased_name, value)|
35
+ name = downcased_name.split("-").map(&:capitalize).join("-")
36
+ headers.merge!(name => value)
37
+ end
38
+ end
32
39
  end
33
40
  end
data/lib/down/http.rb CHANGED
@@ -1,6 +1,6 @@
1
1
  # frozen-string-literal: true
2
2
 
3
- gem "http", ">= 2.1.0", "< 5"
3
+ gem "http", ">= 2.1.0", "< 6"
4
4
 
5
5
  require "http"
6
6
 
@@ -25,16 +25,16 @@ module Down
25
25
 
26
26
  # Downlods the remote file to disk. Accepts HTTP.rb options via a hash or a
27
27
  # block, and some additional options as well.
28
- def download(url, max_size: nil, progress_proc: nil, content_length_proc: nil, destination: nil, **options, &block)
28
+ def download(url, max_size: nil, progress_proc: nil, content_length_proc: nil, destination: nil, extension: nil, **options, &block)
29
29
  response = request(url, **options, &block)
30
30
 
31
31
  content_length_proc.call(response.content_length) if content_length_proc && response.content_length
32
32
 
33
33
  if max_size && response.content_length && response.content_length > max_size
34
- raise Down::TooLarge, "file is too large (max is #{max_size/1024/1024}MB)"
34
+ raise Down::TooLarge, "file is too large (#{response.content_length/1024/1024}MB, max is #{max_size/1024/1024}MB)"
35
35
  end
36
36
 
37
- extname = File.extname(response.uri.path)
37
+ extname = extension ? ".#{extension}" : File.extname(response.uri.path)
38
38
  tempfile = Tempfile.new(["down-http", extname], binmode: true)
39
39
 
40
40
  stream_body(response) do |chunk|
@@ -44,7 +44,7 @@ module Down
44
44
  progress_proc.call(tempfile.size) if progress_proc
45
45
 
46
46
  if max_size && tempfile.size > max_size
47
- raise Down::TooLarge, "file is too large (max is #{max_size/1024/1024}MB)"
47
+ raise Down::TooLarge, "file is too large (#{tempfile.size/1024/1024}MB, max is #{max_size/1024/1024}MB)"
48
48
  end
49
49
  end
50
50
 
@@ -71,7 +71,11 @@ module Down
71
71
  size: response.content_length,
72
72
  encoding: response.content_type.charset,
73
73
  rewindable: rewindable,
74
- data: { status: response.code, headers: response.headers.to_h, response: response },
74
+ data: {
75
+ status: response.code,
76
+ headers: normalize_headers(response.headers.to_h),
77
+ response: response
78
+ },
75
79
  )
76
80
  end
77
81
 
data/lib/down/net_http.rb CHANGED
@@ -40,6 +40,7 @@ module Down
40
40
  destination = options.delete(:destination)
41
41
  headers = options.delete(:headers)
42
42
  uri_normalizer = options.delete(:uri_normalizer)
43
+ extension = options.delete(:extension)
43
44
 
44
45
  # Use open-uri's :content_lenth_proc or :progress_proc to raise an
45
46
  # exception early if the file is too large.
@@ -49,13 +50,13 @@ module Down
49
50
  open_uri_options = {
50
51
  content_length_proc: proc { |size|
51
52
  if size && max_size && size > max_size
52
- raise Down::TooLarge, "file is too large (max is #{max_size/1024/1024}MB)"
53
+ raise Down::TooLarge, "file is too large (#{size/1024/1024}MB, max is #{max_size/1024/1024}MB)"
53
54
  end
54
55
  content_length_proc.call(size) if content_length_proc
55
56
  },
56
57
  progress_proc: proc { |current_size|
57
58
  if max_size && current_size > max_size
58
- raise Down::TooLarge, "file is too large (max is #{max_size/1024/1024}MB)"
59
+ raise Down::TooLarge, "file is too large (#{current_size/1024/1024}MB, max is #{max_size/1024/1024}MB)"
59
60
  end
60
61
  progress_proc.call(current_size) if progress_proc
61
62
  },
@@ -93,7 +94,8 @@ module Down
93
94
  open_uri_file = open_uri(uri, open_uri_options, follows_remaining: max_redirects)
94
95
 
95
96
  # Handle the fact that open-uri returns StringIOs for small files.
96
- tempfile = ensure_tempfile(open_uri_file, File.extname(open_uri_file.base_uri.path))
97
+ extname = extension ? ".#{extension}" : File.extname(open_uri_file.base_uri.path)
98
+ tempfile = ensure_tempfile(open_uri_file, extname)
97
99
  OpenURI::Meta.init tempfile, open_uri_file # add back open-uri methods
98
100
  tempfile.extend Down::NetHttp::DownloadedFile
99
101
 
@@ -130,10 +132,7 @@ module Down
130
132
  on_close: -> { request.resume }, # close HTTP connnection
131
133
  data: {
132
134
  status: response.code.to_i,
133
- headers: response.each_header.inject({}) { |headers, (downcased_name, value)|
134
- name = downcased_name.split("-").map(&:capitalize).join("-")
135
- headers.merge!(name => value)
136
- },
135
+ headers: normalize_headers(response.each_header),
137
136
  response: response,
138
137
  },
139
138
  )
@@ -158,7 +157,11 @@ module Down
158
157
 
159
158
  # forward cookies on the redirect
160
159
  if !exception.io.meta["set-cookie"].to_s.empty?
161
- options["Cookie"] = exception.io.meta["set-cookie"]
160
+ options["Cookie"] ||= ''
161
+ # Add new cookies avoiding duplication
162
+ new_cookies = exception.io.meta["set-cookie"].to_s.split(',').map(&:strip)
163
+ old_cookies = options["Cookie"].split(',')
164
+ options["Cookie"] = (old_cookies | new_cookies).join(',')
162
165
  end
163
166
 
164
167
  follows_remaining -= 1
@@ -202,13 +205,13 @@ module Down
202
205
 
203
206
  begin
204
207
  response = http.start do
205
- http.request(request) do |response|
206
- unless response.is_a?(Net::HTTPRedirection)
207
- yield response
208
+ http.request(request) do |resp|
209
+ unless resp.is_a?(Net::HTTPRedirection)
210
+ yield resp
208
211
  # In certain cases the caller wants to download only one portion
209
212
  # of the file and close the connection, so we tell Net::HTTP that
210
213
  # it shouldn't continue retrieving it.
211
- response.instance_variable_set("@read", true)
214
+ resp.instance_variable_set("@read", true)
212
215
  end
213
216
  end
214
217
  end
@@ -310,8 +313,8 @@ module Down
310
313
  def rebuild_response_from_open_uri_exception(exception)
311
314
  code, message = exception.io.status
312
315
 
313
- response_class = Net::HTTPResponse::CODE_TO_OBJ.fetch(code) do |code|
314
- Net::HTTPResponse::CODE_CLASS_TO_OBJ.fetch(code[0]) do
316
+ response_class = Net::HTTPResponse::CODE_TO_OBJ.fetch(code) do |c|
317
+ Net::HTTPResponse::CODE_CLASS_TO_OBJ.fetch(c[0]) do
315
318
  Net::HTTPUnknownResponse
316
319
  end
317
320
  end
data/lib/down/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen-string-literal: true
2
2
 
3
3
  module Down
4
- VERSION = "5.2.1"
4
+ VERSION = "5.3.0"
5
5
  end
data/lib/down/wget.rb CHANGED
@@ -29,16 +29,16 @@ module Down
29
29
 
30
30
  # Downlods the remote file to disk. Accepts wget command-line options and
31
31
  # some additional options as well.
32
- def download(url, *args, max_size: nil, content_length_proc: nil, progress_proc: nil, destination: nil, **options)
32
+ def download(url, *args, max_size: nil, content_length_proc: nil, progress_proc: nil, destination: nil, extension: nil, **options)
33
33
  io = open(url, *args, **options, rewindable: false)
34
34
 
35
35
  content_length_proc.call(io.size) if content_length_proc && io.size
36
36
 
37
37
  if max_size && io.size && io.size > max_size
38
- raise Down::TooLarge, "file is too large (max is #{max_size/1024/1024}MB)"
38
+ raise Down::TooLarge, "file is too large (#{io.size/1024/1024}MB, max is #{max_size/1024/1024}MB)"
39
39
  end
40
40
 
41
- extname = File.extname(URI(url).path)
41
+ extname = extension ? ".#{extension}" : File.extname(URI(url).path)
42
42
  tempfile = Tempfile.new(["down-wget", extname], binmode: true)
43
43
 
44
44
  until io.eof?
@@ -49,7 +49,7 @@ module Down
49
49
  progress_proc.call(tempfile.size) if progress_proc
50
50
 
51
51
  if max_size && tempfile.size > max_size
52
- raise Down::TooLarge, "file is too large (max is #{max_size/1024/1024}MB)"
52
+ raise Down::TooLarge, "file is too large (#{tempfile.size/1024/1024}MB, max is #{max_size/1024/1024}MB)"
53
53
  end
54
54
  end
55
55
 
@@ -94,7 +94,7 @@ module Down
94
94
  raise Down::Error, "failed to parse response headers"
95
95
  end
96
96
 
97
- headers = parser.headers
97
+ headers = normalize_headers(parser.headers)
98
98
  status = parser.status_code
99
99
 
100
100
  content_length = headers["Content-Length"].to_i if headers["Content-Length"]
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: down
3
3
  version: !ruby/object:Gem::Version
4
- version: 5.2.1
4
+ version: 5.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Janko Marohnić
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-04-26 00:00:00.000000000 Z
11
+ date: 2022-02-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: addressable
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '2.5'
19
+ version: '2.8'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '2.5'
26
+ version: '2.8'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: minitest
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -72,14 +72,14 @@ dependencies:
72
72
  requirements:
73
73
  - - "~>"
74
74
  - !ruby/object:Gem::Version
75
- version: '4.3'
75
+ version: '5.0'
76
76
  type: :development
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
80
  - - "~>"
81
81
  - !ruby/object:Gem::Version
82
- version: '4.3'
82
+ version: '5.0'
83
83
  - !ruby/object:Gem::Dependency
84
84
  name: posix-spawn
85
85
  requirement: !ruby/object:Gem::Requirement
@@ -175,7 +175,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
175
175
  - !ruby/object:Gem::Version
176
176
  version: '0'
177
177
  requirements: []
178
- rubygems_version: 3.2.3
178
+ rubygems_version: 3.3.3
179
179
  signing_key:
180
180
  specification_version: 4
181
181
  summary: Robust streaming downloads using Net::HTTP, HTTP.rb or wget.