down 5.1.1 → 5.2.3

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: 9e5b173cd29f11f5870abace2dfc3903b75d186c416fcfc8bda84e9b2b3f287b
4
- data.tar.gz: c10e4d1c365341563a704c468b148728a85123ef1408b292bd4b04e1d4e332f5
3
+ metadata.gz: 0e7b49c1d00aeebc4f368c816a422aa2525461786d7530ee4e02c7cfaf2fe475
4
+ data.tar.gz: '009d5288c3aa7dbacd6cecf223352ecf05be0ab164b9e1f5e9d6f3d489c1c695'
5
5
  SHA512:
6
- metadata.gz: 27e94e573275c3065e77352119a7bfd2504387716411f1ea552d31a1ccc5bfe81703d15de648a58e3d588086c6d00a0bf6b03b49ea9854970467d5d7660b4d45
7
- data.tar.gz: 24f7bfc83ce5a8b9b4efd1e4fcc9192f9ebd72330722e0bd788837e1b4a14e3f5421a76debcceae8121d95232feeaa249dcdb8cbc684218951d735e86d3088ad
6
+ metadata.gz: 21f7f6691c45cf9a78fca48004839fdc510c6041ebbf42d15bf6f6f1334ed8a62ce8177c2888f06db7f53b8c43b605deb0a99db57545f6b7b1b391befaa2d48b
7
+ data.tar.gz: ac1cd77390f8a28ffcbdadb2c5ccede6a43af015986a6582360214c14050f3d4b118df3e5bc777a9a3abffb6050cea64b789757cf757f25215304c7e8fd54102
data/CHANGELOG.md CHANGED
@@ -1,3 +1,27 @@
1
+ ## 5.2.3 (2021-08-03)
2
+
3
+ * Bump addressable version requirement to 2.8+ to remediate vulnerability (@aldodelgado)
4
+
5
+ ## 5.2.2 (2021-05-27)
6
+
7
+ * Add info about received content length in `Down::TooLarge` error (@evheny0)
8
+
9
+ * Relax http.rb constraint to allow versions 5.x (@mgrunberg)
10
+
11
+ ## 5.2.1 (2021-04-26)
12
+
13
+ * Raise `Down::NotModified` on 304 response status in `Down::NetHttp#open` (@ellafeldmann)
14
+
15
+ ## 5.2.0 (2020-09-20)
16
+
17
+ * Add `:uri_normalizer` option to `Down::NetHttp` (@janko)
18
+
19
+ * Add `:http_basic_authentication` option to `Down::NetHttp#open` (@janko)
20
+
21
+ * Fix uninitialized instance variables warnings in `Down::ChunkedIO` (@janko)
22
+
23
+ * Handle unknown HTTP error codes in `Down::NetHttp` (@darndt)
24
+
1
25
  ## 5.1.1 (2020-02-04)
2
26
 
3
27
  * Fix keyword arguments warnings on Ruby 2.7 in `Down.download` and `Down.open` (@janko)
data/README.md CHANGED
@@ -212,6 +212,7 @@ the `Down::Error` subclasses. This is Down's exception hierarchy:
212
212
  * `Down::TooLarge`
213
213
  * `Down::InvalidUrl`
214
214
  * `Down::TooManyRedirects`
215
+ * `Down::NotModified`
215
216
  * `Down::ResponseError`
216
217
  * `Down::ClientError`
217
218
  * `Down::NotFound`
@@ -251,10 +252,10 @@ Down.open("...")
251
252
  ### Down::NetHttp
252
253
 
253
254
  The `Down::NetHttp` backend implements downloads using [open-uri] and
254
- [Net::HTTP].
255
+ [Net::HTTP] standard libraries.
255
256
 
256
257
  ```rb
257
- gem "down", "~> 4.4"
258
+ gem "down", "~> 5.0"
258
259
  ```
259
260
  ```rb
260
261
  require "down/net_http"
@@ -333,6 +334,18 @@ Down::NetHttp.open("http://example.com/image.jpg",
333
334
  ssl_verify_mode: OpenSSL::SSL::VERIFY_PEER)
334
335
  ```
335
336
 
337
+ #### URI normalization
338
+
339
+ If the URL isn't parseable by `URI.parse`, `Down::NetHttp` will
340
+ attempt to normalize the URL using [Addressable::URI], URI-escaping
341
+ any potentially unescaped characters. You can change the normalizer
342
+ via the `:uri_normalizer` option:
343
+
344
+ ```rb
345
+ # this skips URL normalization
346
+ Down::NetHttp.download("http://example.com/image.jpg", uri_normalizer: -> (url) { url })
347
+ ```
348
+
336
349
  #### Additional options
337
350
 
338
351
  Any additional options passed to `Down.download` will be forwarded to
@@ -358,8 +371,8 @@ net_http.open("http://example.com/image.jpg")
358
371
  The `Down::Http` backend implements downloads using the [http.rb] gem.
359
372
 
360
373
  ```rb
361
- gem "down", "~> 4.4"
362
- gem "http", "~> 4.0"
374
+ gem "down", "~> 5.0"
375
+ gem "http", "~> 5.0"
363
376
  ```
364
377
  ```rb
365
378
  require "down/http"
@@ -428,7 +441,7 @@ The `Down::Wget` backend implements downloads using the `wget` command line
428
441
  utility.
429
442
 
430
443
  ```rb
431
- gem "down", "~> 4.4"
444
+ gem "down", "~> 5.0"
432
445
  gem "posix-spawn" # omit if on JRuby
433
446
  gem "http_parser.rb"
434
447
  ```
data/down.gemspec CHANGED
@@ -15,13 +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
30
  spec.add_development_dependency "http_parser.rb"
26
31
  spec.add_development_dependency "docker-api"
32
+ spec.add_development_dependency "warning" if RUBY_VERSION >= "2.4"
27
33
  end
@@ -36,6 +36,8 @@ module Down
36
36
  @rewindable = rewindable
37
37
  @buffer = nil
38
38
  @position = 0
39
+ @next_chunk = nil
40
+ @closed = false
39
41
 
40
42
  retrieve_chunk # fetch first chunk so that we know whether the file is empty
41
43
  end
data/lib/down/errors.rb CHANGED
@@ -13,6 +13,9 @@ module Down
13
13
  # raised when the number of redirects was larger than the specified maximum
14
14
  class TooManyRedirects < Error; end
15
15
 
16
+ # raised when the requested resource has not been modified
17
+ class NotModified < Error; end
18
+
16
19
  # raised when response returned 4xx or 5xx response
17
20
  class ResponseError < Error
18
21
  attr_reader :response
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
 
@@ -31,7 +31,7 @@ module Down
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
37
  extname = File.extname(response.uri.path)
@@ -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
 
data/lib/down/net_http.rb CHANGED
@@ -12,13 +12,19 @@ require "fileutils"
12
12
  module Down
13
13
  # Provides streaming downloads implemented with Net::HTTP and open-uri.
14
14
  class NetHttp < Backend
15
+ URI_NORMALIZER = -> (url) do
16
+ addressable_uri = Addressable::URI.parse(url)
17
+ addressable_uri.normalize.to_s
18
+ end
19
+
15
20
  # Initializes the backend with common defaults.
16
21
  def initialize(*args, **options)
17
22
  @options = merge_options({
18
- headers: { "User-Agent" => "Down/#{Down::VERSION}" },
19
- max_redirects: 2,
20
- open_timeout: 30,
21
- read_timeout: 30,
23
+ headers: { "User-Agent" => "Down/#{Down::VERSION}" },
24
+ max_redirects: 2,
25
+ open_timeout: 30,
26
+ read_timeout: 30,
27
+ uri_normalizer: URI_NORMALIZER,
22
28
  }, *args, **options)
23
29
  end
24
30
 
@@ -33,6 +39,7 @@ module Down
33
39
  content_length_proc = options.delete(:content_length_proc)
34
40
  destination = options.delete(:destination)
35
41
  headers = options.delete(:headers)
42
+ uri_normalizer = options.delete(:uri_normalizer)
36
43
 
37
44
  # Use open-uri's :content_lenth_proc or :progress_proc to raise an
38
45
  # exception early if the file is too large.
@@ -42,13 +49,13 @@ module Down
42
49
  open_uri_options = {
43
50
  content_length_proc: proc { |size|
44
51
  if size && max_size && size > max_size
45
- raise Down::TooLarge, "file is too large (max is #{max_size/1024/1024}MB)"
52
+ raise Down::TooLarge, "file is too large (#{size/1024/1024}MB, max is #{max_size/1024/1024}MB)"
46
53
  end
47
54
  content_length_proc.call(size) if content_length_proc
48
55
  },
49
56
  progress_proc: proc { |current_size|
50
57
  if max_size && current_size > max_size
51
- raise Down::TooLarge, "file is too large (max is #{max_size/1024/1024}MB)"
58
+ raise Down::TooLarge, "file is too large (#{current_size/1024/1024}MB, max is #{max_size/1024/1024}MB)"
52
59
  end
53
60
  progress_proc.call(current_size) if progress_proc
54
61
  },
@@ -74,7 +81,7 @@ module Down
74
81
  open_uri_options.merge!(options)
75
82
  open_uri_options.merge!(headers)
76
83
 
77
- uri = ensure_uri(addressable_normalize(url))
84
+ uri = ensure_uri(normalize_uri(url, uri_normalizer: uri_normalizer))
78
85
 
79
86
  # Handle basic authentication in the remote URL.
80
87
  if uri.user || uri.password
@@ -96,10 +103,12 @@ module Down
96
103
  # Starts retrieving the remote file using Net::HTTP and returns an IO-like
97
104
  # object which downloads the response body on-demand.
98
105
  def open(url, *args, **options)
99
- uri = ensure_uri(addressable_normalize(url))
100
106
  options = merge_options(@options, *args, **options)
101
107
 
102
- max_redirects = options.delete(:max_redirects)
108
+ max_redirects = options.delete(:max_redirects)
109
+ uri_normalizer = options.delete(:uri_normalizer)
110
+
111
+ uri = ensure_uri(normalize_uri(url, uri_normalizer: uri_normalizer))
103
112
 
104
113
  # Create a Fiber that halts when response headers are received.
105
114
  request = Fiber.new do
@@ -207,7 +216,9 @@ module Down
207
216
  request_error!(exception)
208
217
  end
209
218
 
210
- if response.is_a?(Net::HTTPRedirection)
219
+ if response.is_a?(Net::HTTPNotModified)
220
+ raise Down::NotModified
221
+ elsif response.is_a?(Net::HTTPRedirection)
211
222
  raise Down::TooManyRedirects if follows_remaining == 0
212
223
 
213
224
  # fail if redirect URI is not a valid http or https URL
@@ -257,7 +268,9 @@ module Down
257
268
  headers["Accept-Encoding"] = "" # Net::HTTP's inflater causes FiberErrors
258
269
 
259
270
  get = Net::HTTP::Get.new(uri.request_uri, headers)
260
- get.basic_auth(uri.user, uri.password) if uri.user || uri.password
271
+
272
+ user, password = options[:http_basic_authentication] || [uri.user, uri.password]
273
+ get.basic_auth(user, password) if user || password
261
274
 
262
275
  [http, get]
263
276
  end
@@ -285,11 +298,10 @@ module Down
285
298
  end
286
299
 
287
300
  # Makes sure that the URL is properly encoded.
288
- def addressable_normalize(url)
301
+ def normalize_uri(url, uri_normalizer:)
289
302
  URI(url)
290
303
  rescue URI::InvalidURIError
291
- addressable_uri = Addressable::URI.parse(url)
292
- addressable_uri.normalize.to_s
304
+ uri_normalizer.call(url)
293
305
  end
294
306
 
295
307
  # When open-uri raises an exception, it doesn't expose the response object.
@@ -298,7 +310,11 @@ module Down
298
310
  def rebuild_response_from_open_uri_exception(exception)
299
311
  code, message = exception.io.status
300
312
 
301
- response_class = Net::HTTPResponse::CODE_TO_OBJ.fetch(code)
313
+ response_class = Net::HTTPResponse::CODE_TO_OBJ.fetch(code) do |code|
314
+ Net::HTTPResponse::CODE_CLASS_TO_OBJ.fetch(code[0]) do
315
+ Net::HTTPUnknownResponse
316
+ end
317
+ end
302
318
  response = response_class.new(nil, code, message)
303
319
 
304
320
  exception.io.metas.each do |name, values|
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.1.1"
4
+ VERSION = "5.2.3"
5
5
  end
data/lib/down/wget.rb CHANGED
@@ -35,7 +35,7 @@ module Down
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
41
  extname = File.extname(URI(url).path)
@@ -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
 
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.1.1
4
+ version: 5.2.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Janko Marohnić
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-02-04 00:00:00.000000000 Z
11
+ date: 2021-08-03 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
@@ -122,7 +122,21 @@ dependencies:
122
122
  - - ">="
123
123
  - !ruby/object:Gem::Version
124
124
  version: '0'
125
- description:
125
+ - !ruby/object:Gem::Dependency
126
+ name: warning
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ">="
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - ">="
137
+ - !ruby/object:Gem::Version
138
+ version: '0'
139
+ description:
126
140
  email:
127
141
  - janko.marohnic@gmail.com
128
142
  executables: []
@@ -146,7 +160,7 @@ homepage: https://github.com/janko/down
146
160
  licenses:
147
161
  - MIT
148
162
  metadata: {}
149
- post_install_message:
163
+ post_install_message:
150
164
  rdoc_options: []
151
165
  require_paths:
152
166
  - lib
@@ -161,8 +175,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
161
175
  - !ruby/object:Gem::Version
162
176
  version: '0'
163
177
  requirements: []
164
- rubygems_version: 3.1.2
165
- signing_key:
178
+ rubygems_version: 3.2.15
179
+ signing_key:
166
180
  specification_version: 4
167
181
  summary: Robust streaming downloads using Net::HTTP, HTTP.rb or wget.
168
182
  test_files: []