down 5.1.1 → 5.2.3

Sign up to get free protection for your applications and to get access to all the features.
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: []