down 5.0.1 → 5.1.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: 5845204de4f09b03621e6474e9f3032ae9c0ce9823dac21cfc8f435c184c4a30
4
- data.tar.gz: f7f65817661dfc62c4ab74da59ef5f8ad6b90927c50b62da0bf77f833f79c139
3
+ metadata.gz: 8945c6eac12d64c95b935a7142c3e946c7c793500c309adc3e3f381381ab4540
4
+ data.tar.gz: 510058d6f151ca64b02d8ae807dc6239ba19819091dd3311669363f65dd848d6
5
5
  SHA512:
6
- metadata.gz: 12b2ab829b2912913dc9ba6bfb77dcd8e9a8e909cc58cdc09b25567a936baf361657785a386766a4e6bc01d50c900240af7be694e88d4e68d829dfe0f5b09bef
7
- data.tar.gz: '08ec832345fb6a41ba8888c15f3879a437dce282b809d236b08310dfd2ce9881df18cf663f6a11a69182af47dcc20d3bcf2688f4b32d278cfa5dbe75b9553417'
6
+ metadata.gz: d53aadc7031714fa16ef8dc8fcf9cb0af56cc43b761c00b52cbfd71d81dc1e68ceb88a4152d23205aaec45920ffa588aaedec64b433698b7da6294a077893ceb
7
+ data.tar.gz: 21c1114b5b6f87d35a332e7e6cab025b361117bc2b6b38b8236b64991f6468fc73d1576d772eb5f709d07a416c63299a6e9891c7452367fd64d0224fa2be00c8
@@ -1,3 +1,11 @@
1
+ ## 5.1.0 (2020-01-09)
2
+
3
+ * Fix keyword arguments warnings on Ruby 2.7 (@janko)
4
+
5
+ * Fix `FrozenError` exception in `Down::ChunkedIO#readpartial` (@janko)
6
+
7
+ * Deprecate passing headers as top-level options in `Down::NetHttp` (@janko)
8
+
1
9
  ## 5.0.1 (2019-12-20)
2
10
 
3
11
  * In `Down::NetHttp` only use Addressable normalization if `URI.parse` fails (@coding-chimp)
@@ -9,12 +9,12 @@ require "fileutils"
9
9
 
10
10
  module Down
11
11
  class Backend
12
- def self.download(*args, &block)
13
- new.download(*args, &block)
12
+ def self.download(*args, **options, &block)
13
+ new.download(*args, **options, &block)
14
14
  end
15
15
 
16
- def self.open(*args, &block)
17
- new.open(*args, &block)
16
+ def self.open(*args, **options, &block)
17
+ new.open(*args, **options, &block)
18
18
  end
19
19
 
20
20
  private
@@ -63,7 +63,9 @@ module Down
63
63
  def read(length = nil, outbuf = nil)
64
64
  fail IOError, "closed stream" if closed?
65
65
 
66
- data = outbuf.to_s.clear.force_encoding(Encoding::BINARY)
66
+ data = outbuf.clear.force_encoding(Encoding::BINARY) if outbuf
67
+ data ||= "".b
68
+
67
69
  remaining_length = length
68
70
 
69
71
  until remaining_length == 0 || eof?
@@ -142,7 +144,8 @@ module Down
142
144
  # or the next chunk. This is useful when you don't care about the size of
143
145
  # chunks and you want to minimize string allocations.
144
146
  #
145
- # With `maxlen` argument returns maximum of that amount of bytes.
147
+ # With `maxlen` argument returns maximum of that amount of bytes (default
148
+ # is 16KB).
146
149
  #
147
150
  # With `outbuf` argument each call will return that same string object,
148
151
  # where the value is replaced with retrieved content.
@@ -154,7 +157,8 @@ module Down
154
157
  maxlen ||= 16*1024
155
158
 
156
159
  data = cache.read(maxlen, outbuf) if cache && !cache.eof?
157
- data ||= outbuf.to_s.clear
160
+ data ||= outbuf.clear.force_encoding(Encoding::BINARY) if outbuf
161
+ data ||= "".b
158
162
 
159
163
  return data if maxlen == 0
160
164
 
@@ -17,7 +17,7 @@ module Down
17
17
  class ResponseError < Error
18
18
  attr_reader :response
19
19
 
20
- def initialize(message, response: nil)
20
+ def initialize(message, response = nil)
21
21
  super(message)
22
22
  @response = response
23
23
  end
@@ -12,7 +12,7 @@ module Down
12
12
  # Provides streaming downloads implemented with HTTP.rb.
13
13
  class Http < Backend
14
14
  # Initializes the backend with common defaults.
15
- def initialize(options = {}, &block)
15
+ def initialize(**options, &block)
16
16
  @method = options.delete(:method) || :get
17
17
  @client = HTTP
18
18
  .headers("User-Agent" => "Down/#{Down::VERSION}")
@@ -106,7 +106,7 @@ module Down
106
106
 
107
107
  # Raises non-sucessful response as a Down::ResponseError.
108
108
  def response_error!(response)
109
- args = [response.status.to_s, response: response]
109
+ args = [response.status.to_s, response]
110
110
 
111
111
  case response.code
112
112
  when 404 then raise Down::NotFound.new(*args)
@@ -13,26 +13,26 @@ module Down
13
13
  # Provides streaming downloads implemented with Net::HTTP and open-uri.
14
14
  class NetHttp < Backend
15
15
  # Initializes the backend with common defaults.
16
- def initialize(options = {})
17
- @options = {
18
- "User-Agent" => "Down/#{Down::VERSION}",
16
+ def initialize(*args, **options)
17
+ @options = merge_options({
18
+ headers: { "User-Agent" => "Down/#{Down::VERSION}" },
19
19
  max_redirects: 2,
20
20
  open_timeout: 30,
21
21
  read_timeout: 30,
22
- }.merge(options)
22
+ }, *args, **options)
23
23
  end
24
24
 
25
25
  # Downloads a remote file to disk using open-uri. Accepts any open-uri
26
26
  # options, and a few more.
27
- def download(url, options = {})
28
- options = @options.merge(options)
27
+ def download(url, *args, **options)
28
+ options = merge_options(@options, *args, **options)
29
29
 
30
30
  max_size = options.delete(:max_size)
31
31
  max_redirects = options.delete(:max_redirects)
32
32
  progress_proc = options.delete(:progress_proc)
33
33
  content_length_proc = options.delete(:content_length_proc)
34
34
  destination = options.delete(:destination)
35
- headers = options.delete(:headers) || {}
35
+ headers = options.delete(:headers)
36
36
 
37
37
  # Use open-uri's :content_lenth_proc or :progress_proc to raise an
38
38
  # exception early if the file is too large.
@@ -95,13 +95,15 @@ module Down
95
95
 
96
96
  # Starts retrieving the remote file using Net::HTTP and returns an IO-like
97
97
  # object which downloads the response body on-demand.
98
- def open(url, options = {})
98
+ def open(url, *args, **options)
99
99
  uri = ensure_uri(addressable_normalize(url))
100
- options = @options.merge(options)
100
+ options = merge_options(@options, *args, **options)
101
+
102
+ max_redirects = options.delete(:max_redirects)
101
103
 
102
104
  # Create a Fiber that halts when response headers are received.
103
105
  request = Fiber.new do
104
- net_http_request(uri, options) do |response|
106
+ net_http_request(uri, options, follows_remaining: max_redirects) do |response|
105
107
  Fiber.yield response
106
108
  end
107
109
  end
@@ -131,7 +133,7 @@ module Down
131
133
  private
132
134
 
133
135
  # Calls open-uri's URI::HTTP#open method. Additionally handles redirects.
134
- def open_uri(uri, options, follows_remaining: 0)
136
+ def open_uri(uri, options, follows_remaining:)
135
137
  uri.open(options)
136
138
  rescue OpenURI::HTTPRedirect => exception
137
139
  raise Down::TooManyRedirects, "too many redirects" if follows_remaining == 0
@@ -186,7 +188,7 @@ module Down
186
188
  end
187
189
 
188
190
  # Makes a Net::HTTP request and follows redirects.
189
- def net_http_request(uri, options, follows_remaining: options.fetch(:max_redirects, 2), &block)
191
+ def net_http_request(uri, options, follows_remaining:, &block)
190
192
  http, request = create_net_http(uri, options)
191
193
 
192
194
  begin
@@ -251,8 +253,7 @@ module Down
251
253
  http.read_timeout = options[:read_timeout] if options.key?(:read_timeout)
252
254
  http.open_timeout = options[:open_timeout] if options.key?(:open_timeout)
253
255
 
254
- headers = options.select { |key, value| key.is_a?(String) }
255
- headers.merge!(options[:headers]) if options[:headers]
256
+ headers = options[:headers].to_h
256
257
  headers["Accept-Encoding"] = "" # Net::HTTP's inflater causes FiberErrors
257
258
 
258
259
  get = Net::HTTP::Get.new(uri.request_uri, headers)
@@ -312,7 +313,7 @@ module Down
312
313
  code = response.code.to_i
313
314
  message = response.message.split(" ").map(&:capitalize).join(" ")
314
315
 
315
- args = ["#{code} #{message}", response: response]
316
+ args = ["#{code} #{message}", response]
316
317
 
317
318
  case response.code.to_i
318
319
  when 404 then raise Down::NotFound.new(*args)
@@ -338,6 +339,24 @@ module Down
338
339
  end
339
340
  end
340
341
 
342
+ # Merge default and ad-hoc options, merging nested headers.
343
+ def merge_options(options, headers = {}, **new_options)
344
+ # Deprecate passing headers as top-level options, taking into account
345
+ # that Ruby 2.7+ accepts kwargs with string keys.
346
+ if headers.any?
347
+ warn %([Down::NetHttp] Passing headers as top-level options has been deprecated, use the :headers option instead, e.g: `Down::NetHttp.download(headers: { "Key" => "Value", ... }, ...)`)
348
+ new_options[:headers] = headers
349
+ elsif new_options.any? { |key, value| key.is_a?(String) }
350
+ warn %([Down::NetHttp] Passing headers as top-level options has been deprecated, use the :headers option instead, e.g: `Down::NetHttp.download(headers: { "Key" => "Value", ... }, ...)`)
351
+ new_options[:headers] = new_options.select { |key, value| key.is_a?(String) }
352
+ new_options.reject! { |key, value| key.is_a?(String) }
353
+ end
354
+
355
+ options.merge(new_options) do |key, value1, value2|
356
+ key == :headers ? value1.merge(value2) : value2
357
+ end
358
+ end
359
+
341
360
  # Defines some additional attributes for the returned Tempfile (on top of what
342
361
  # OpenURI::Meta already defines).
343
362
  module DownloadedFile
@@ -1,5 +1,5 @@
1
1
  # frozen-string-literal: true
2
2
 
3
3
  module Down
4
- VERSION = "5.0.1"
4
+ VERSION = "5.1.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.0.1
4
+ version: 5.1.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: 2019-12-20 00:00:00.000000000 Z
11
+ date: 2020-01-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: addressable
@@ -161,7 +161,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
161
161
  - !ruby/object:Gem::Version
162
162
  version: '0'
163
163
  requirements: []
164
- rubygems_version: 3.1.1
164
+ rubygems_version: 3.1.2
165
165
  signing_key:
166
166
  specification_version: 4
167
167
  summary: Robust streaming downloads using Net::HTTP, HTTP.rb or wget.