down 5.1.1 → 5.2.0

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: d48d573f542ac195a462c3bab0ebe1546c8dd78b0a5210eed1d1fed1f66b674f
4
+ data.tar.gz: 492b997d3e889475544267d753df5fb900d28728131602e6950a57dfacb7842c
5
5
  SHA512:
6
- metadata.gz: 27e94e573275c3065e77352119a7bfd2504387716411f1ea552d31a1ccc5bfe81703d15de648a58e3d588086c6d00a0bf6b03b49ea9854970467d5d7660b4d45
7
- data.tar.gz: 24f7bfc83ce5a8b9b4efd1e4fcc9192f9ebd72330722e0bd788837e1b4a14e3f5421a76debcceae8121d95232feeaa249dcdb8cbc684218951d735e86d3088ad
6
+ metadata.gz: e0fa81667368033a51588f37ae8a5fca2198ce341268e5c6fc24a8241be1af7ce88cd4bc7e8076f69af41b3e0318a4c8733c28a9d173dcdae750b59a9e2401e6
7
+ data.tar.gz: 568632e1c75daa84a838675ae49ceb844a4500e781b8303cf3c1259974b1d01a26e3d2420e08d0d544c81ef312dc790cafdd47fcdc2ed6f3a853b91f8a99bd48
@@ -1,3 +1,13 @@
1
+ ## 5.2.0 (2020-09-20)
2
+
3
+ * Add `:uri_normalizer` option to `Down::NetHttp` (@janko)
4
+
5
+ * Add `:http_basic_authentication` option to `Down::NetHttp#download` (@janko)
6
+
7
+ * Fix uninitialized instance variables warnings in `Down::ChunkedIO` (@janko)
8
+
9
+ * Handle unknown HTTP error codes in `Down::NetHttp` (@darndt)
10
+
1
11
  ## 5.1.1 (2020-02-04)
2
12
 
3
13
  * Fix keyword arguments warnings on Ruby 2.7 in `Down.download` and `Down.open` (@janko)
data/README.md CHANGED
@@ -333,6 +333,18 @@ Down::NetHttp.open("http://example.com/image.jpg",
333
333
  ssl_verify_mode: OpenSSL::SSL::VERIFY_PEER)
334
334
  ```
335
335
 
336
+ #### URI normalization
337
+
338
+ If the URL isn't parseable by `URI.parse`, `Down::NetHttp` will
339
+ attempt to normalize the URL using [Addressable::URI], URI-escaping
340
+ any potentially unescaped characters. You can change the normalizer
341
+ via the `:uri_normalizer` option:
342
+
343
+ ```rb
344
+ # this skips URL normalization
345
+ Down::NetHttp.download("http://example.com/image.jpg", uri_normalizer: -> (url) { url })
346
+ ```
347
+
336
348
  #### Additional options
337
349
 
338
350
  Any additional options passed to `Down.download` will be forwarded to
@@ -24,4 +24,5 @@ Gem::Specification.new do |spec|
24
24
  spec.add_development_dependency "posix-spawn" unless RUBY_ENGINE == "jruby"
25
25
  spec.add_development_dependency "http_parser.rb"
26
26
  spec.add_development_dependency "docker-api"
27
+ spec.add_development_dependency "warning" if RUBY_VERSION >= "2.4"
27
28
  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
@@ -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.
@@ -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
@@ -257,7 +266,9 @@ module Down
257
266
  headers["Accept-Encoding"] = "" # Net::HTTP's inflater causes FiberErrors
258
267
 
259
268
  get = Net::HTTP::Get.new(uri.request_uri, headers)
260
- get.basic_auth(uri.user, uri.password) if uri.user || uri.password
269
+
270
+ user, password = options[:http_basic_authentication] || [uri.user, uri.password]
271
+ get.basic_auth(user, password) if user || password
261
272
 
262
273
  [http, get]
263
274
  end
@@ -285,11 +296,10 @@ module Down
285
296
  end
286
297
 
287
298
  # Makes sure that the URL is properly encoded.
288
- def addressable_normalize(url)
299
+ def normalize_uri(url, uri_normalizer:)
289
300
  URI(url)
290
301
  rescue URI::InvalidURIError
291
- addressable_uri = Addressable::URI.parse(url)
292
- addressable_uri.normalize.to_s
302
+ uri_normalizer.call(url)
293
303
  end
294
304
 
295
305
  # When open-uri raises an exception, it doesn't expose the response object.
@@ -298,7 +308,11 @@ module Down
298
308
  def rebuild_response_from_open_uri_exception(exception)
299
309
  code, message = exception.io.status
300
310
 
301
- response_class = Net::HTTPResponse::CODE_TO_OBJ.fetch(code)
311
+ response_class = Net::HTTPResponse::CODE_TO_OBJ.fetch(code) do |code|
312
+ Net::HTTPResponse::CODE_CLASS_TO_OBJ.fetch(code[0]) do
313
+ Net::HTTPUnknownResponse
314
+ end
315
+ end
302
316
  response = response_class.new(nil, code, message)
303
317
 
304
318
  exception.io.metas.each do |name, values|
@@ -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.0"
5
5
  end
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.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: 2020-02-04 00:00:00.000000000 Z
11
+ date: 2020-09-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: addressable
@@ -122,6 +122,20 @@ dependencies:
122
122
  - - ">="
123
123
  - !ruby/object:Gem::Version
124
124
  version: '0'
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'
125
139
  description:
126
140
  email:
127
141
  - janko.marohnic@gmail.com
@@ -161,7 +175,7 @@ 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
178
+ rubygems_version: 3.1.1
165
179
  signing_key:
166
180
  specification_version: 4
167
181
  summary: Robust streaming downloads using Net::HTTP, HTTP.rb or wget.