down 5.2.1 → 5.3.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: 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.