http_zip 2.0.0 → 2.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: e045495a2ce12199f65be5bf20671418ad350c81ae91fa59c574229ed20eaa22
4
- data.tar.gz: fed79c7c440c3323204e105ba449c92bb26d8a1a8b47b258ef1215865a30d7c2
3
+ metadata.gz: 19b6d04b94e6807748d28eaa6efd8fea800ffa3954483f6054d9a72ffc33c5d6
4
+ data.tar.gz: 43616195f5b74a786b384757a5cad9ee0928dc7b9b13ec7f43294abe036a1f33
5
5
  SHA512:
6
- metadata.gz: 39861993eeb2e36bbbb0e96cf620afcc94935dc11160a676ec9c65657cfca840ab98d0c57ab51fd8272ca10ac1d46c37be6f6d866598410bd13012cba3c0e262
7
- data.tar.gz: 348b335d82a78a8b37c075981370996723b977ce3ce68c18db72a1e68f64c6ec100ac922ff7303bbafd885fc6360e7d676a980407e65048d51415bcedd26f6d2
6
+ metadata.gz: 6b4f9b7fccbefa2a04bb61a7127ac70fad27129f58b0bbe0a7081e4e175359272de6f4db2ec98fc73887adfe34b339823b13606a3f9dc9afe9df7cba932fe4d4
7
+ data.tar.gz: f280e3fcb4fef1c70a83e80ed09916eea48a6918a3055b41b099b88365dcd2a569e516a1cb86b9b56a9e35ee414b02aece303796f3c4da47e3eef476a03673d0
data/.gitignore CHANGED
@@ -7,4 +7,6 @@
7
7
  /spec/reports/
8
8
  /tmp/
9
9
  .DS_Store
10
- Gemfile.lock
10
+ Gemfile.lock
11
+ .devenv
12
+ .direnv
data/Gemfile CHANGED
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- source 'https://rubygems.org'
3
+ source "https://rubygems.org"
4
4
 
5
5
  # Specify your gem's dependencies in http_zip.gemspec
6
6
  gemspec
data/Rakefile CHANGED
@@ -1,12 +1,12 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'bundler/gem_tasks'
4
- require 'rake/testtask'
3
+ require "bundler/gem_tasks"
4
+ require "rake/testtask"
5
5
 
6
6
  Rake::TestTask.new(:test) do |t|
7
- t.libs << 'test'
8
- t.libs << 'lib'
9
- t.test_files = FileList['test/**/*_test.rb']
7
+ t.libs << "test"
8
+ t.libs << "lib"
9
+ t.test_files = FileList["test/**/*_test.rb"]
10
10
  end
11
11
 
12
12
  task default: :test
data/http_zip.gemspec CHANGED
@@ -1,34 +1,36 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- lib = File.expand_path('lib', __dir__)
3
+ lib = File.expand_path("lib", __dir__)
4
4
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
- require 'http_zip/version'
5
+ require "http_zip/version"
6
6
 
7
7
  Gem::Specification.new do |spec|
8
- spec.name = 'http_zip'
9
- spec.version = HttpZip::VERSION
10
- spec.authors = ['Marvin Killing', 'Peter Retzlaff']
11
- spec.email = ['pe.retzlaff@gmail.com']
8
+ spec.name = "http_zip"
9
+ spec.version = HttpZip::VERSION
10
+ spec.authors = ["Marvin Killing", "Peter Retzlaff"]
11
+ spec.email = ["pe.retzlaff@gmail.com"]
12
12
 
13
- spec.summary = 'HttpZip is a gem to extract individual files from a remote ZIP archive, without the need to download the entire file.'
14
- spec.homepage = 'https://github.com/peret/http_zip'
15
- spec.license = 'MIT'
13
+ spec.summary = "HttpZip is a gem to extract individual files from a remote ZIP archive, without the need to download the entire file."
14
+ spec.homepage = "https://github.com/peret/http_zip"
15
+ spec.license = "MIT"
16
16
 
17
- spec.metadata['homepage_uri'] = spec.homepage
18
- spec.metadata['source_code_uri'] = 'https://github.com/peret/http_zip'
17
+ spec.metadata["homepage_uri"] = spec.homepage
18
+ spec.metadata["source_code_uri"] = "https://github.com/peret/http_zip"
19
19
 
20
20
  # Specify which files should be added to the gem when it is released.
21
21
  # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
22
22
  spec.files = Dir.chdir(File.expand_path(__dir__)) do
23
23
  `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
24
24
  end
25
- spec.bindir = 'exe'
26
- spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
27
- spec.require_paths = ['lib']
25
+ spec.bindir = "exe"
26
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
27
+ spec.require_paths = ["lib"]
28
28
 
29
- spec.add_development_dependency 'bundler', '~> 2.0'
30
- spec.add_development_dependency 'minitest', '~> 5.15'
31
- spec.add_development_dependency 'rake', '~> 12.3', '>= 12.3.3'
32
- spec.add_development_dependency 'simplecov', '~> 0.21'
33
- spec.add_development_dependency 'webmock', '~> 3.14'
29
+ spec.add_development_dependency "bundler", "~> 2.0"
30
+ spec.add_development_dependency "minitest", "~> 5.15"
31
+ spec.add_development_dependency "rake", "~> 12.3", ">= 12.3.3"
32
+ spec.add_development_dependency "simplecov", "~> 0.21"
33
+ spec.add_development_dependency "webmock", "~> 3.14"
34
+ spec.add_development_dependency "solargraph", "~> 0.50"
35
+ spec.add_development_dependency "standard", "~> 1.31.0"
34
36
  end
@@ -7,7 +7,8 @@ module HttpZip
7
7
  input
8
8
  end
9
9
 
10
- def finish; end
10
+ def finish
11
+ end
11
12
  end
12
13
  end
13
14
  end
@@ -4,13 +4,14 @@ module HttpZip
4
4
  # Describes one entry in an HTTP zip archive
5
5
  # @attr_reader [String] name filename of the entry
6
6
  class Entry
7
- attr_reader :name, :compressed_size
7
+ attr_reader :name, :compressed_size, :uncompressed_size
8
8
 
9
- def initialize(url, name, header_offset, central_directory_file_compressed_size)
9
+ def initialize(url, name, header_offset, central_directory_file_compressed_size, central_directory_file_uncompressed_size)
10
10
  @range_request = HttpZip::RangeRequest.new(url)
11
11
  @name = name
12
12
  @header_offset = header_offset
13
13
  @compressed_size = central_directory_file_compressed_size
14
+ @uncompressed_size = central_directory_file_uncompressed_size
14
15
  end
15
16
 
16
17
  # Get the decompressed content of the file entry
@@ -32,7 +33,7 @@ module HttpZip
32
33
  to = @header_offset + header_size + @compressed_size
33
34
 
34
35
  decompressor = compression_method
35
- ::File.open(filename, 'wb') do |out_file|
36
+ ::File.open(filename, "wb") do |out_file|
36
37
  @range_request.get(from, to) do |chunk|
37
38
  decompressed = decompressor.decompress(chunk)
38
39
  out_file.write(decompressed)
@@ -50,14 +51,14 @@ module HttpZip
50
51
 
51
52
  def header_size
52
53
  # find out where the file contents start and how large the file is
53
- file_name_length = header[26...28].unpack1('v')
54
- extra_field_length = header[28...30].unpack1('v')
54
+ file_name_length = header[26...28].unpack1("v")
55
+ extra_field_length = header[28...30].unpack1("v")
55
56
  30 + file_name_length + extra_field_length
56
57
  end
57
58
 
58
59
  def compression_method
59
60
  # which compression method is used?
60
- algorithm = header[8...10].unpack1('v')
61
+ algorithm = header[8...10].unpack1("v")
61
62
 
62
63
  case algorithm
63
64
  when 0
@@ -66,7 +67,7 @@ module HttpZip
66
67
  HttpZip::Compression::Deflate.new
67
68
  else
68
69
  raise HttpZip::ZipError,
69
- "Unsupported compression method #{algorithm}. HttpZip only supports compression methods 0 (STORED) and 8 (DEFLATE)."
70
+ "Unsupported compression method #{algorithm}. HttpZip only supports compression methods 0 (STORED) and 8 (DEFLATE)."
70
71
  end
71
72
  end
72
73
  end
@@ -2,7 +2,10 @@
2
2
 
3
3
  module HttpZip
4
4
  class Error < StandardError; end
5
+
5
6
  class RequestError < Error; end
7
+
6
8
  class ContentRangeError < RequestError; end
9
+
7
10
  class ZipError < Error; end
8
11
  end
data/lib/http_zip/file.rb CHANGED
@@ -42,7 +42,8 @@ module HttpZip
42
42
  @url,
43
43
  file_header.file_name,
44
44
  file_header.header_offset,
45
- file_header.compressed_size
45
+ file_header.compressed_size,
46
+ file_header.uncompressed_size
46
47
  )
47
48
 
48
49
  # skip ahead to next file entry
@@ -25,10 +25,10 @@ module HttpZip
25
25
  # @raise [ZipError] if the byte stream does not contain a valid EOCD64 block
26
26
  def parse_eocd64!(eocd64_block)
27
27
  unless eocd64_block.start_with?(EOCD64_BLOCK_IDENTIFER)
28
- raise ZipError, 'EOCD64 record not found'
28
+ raise ZipError, "EOCD64 record not found"
29
29
  end
30
30
 
31
- @size, @offset = eocd64_block[40..-1].unpack('Q<Q<')
31
+ @size, @offset = eocd64_block[40..-1].unpack("Q<Q<")
32
32
  end
33
33
 
34
34
  private
@@ -40,20 +40,20 @@ module HttpZip
40
40
  def parse!
41
41
  eocd_block_index = get_eocd_block_index(@bytes)
42
42
  eocd_block = @bytes[eocd_block_index..-1]
43
- @size, @offset = eocd_block[12...20].unpack('VV')
43
+ @size, @offset = eocd_block[12...20].unpack("VV")
44
44
  return if @size != 0xFFFFFFFF && @offset != 0xFFFFFFFF
45
45
 
46
46
  # there will be a zip64 EOCD locator block before the EOCD block
47
47
  # parse the EOCD locator to find out where the EOCD64 block starts
48
48
  eocd64_locator_block = @bytes[(eocd_block_index - 20)..eocd_block_index]
49
49
  unless eocd64_locator_block.start_with?(EOCD64_LOCATOR_BLOCK_IDENTIFER)
50
- raise ZipError, 'Could not locate the EOCD64 locator block'
50
+ raise ZipError, "Could not locate the EOCD64 locator block"
51
51
  end
52
52
 
53
- @eocd64_offset, total_num_disks = eocd64_locator_block[8..-1].unpack('Q<V')
53
+ @eocd64_offset, total_num_disks = eocd64_locator_block[8..-1].unpack("Q<V")
54
54
  return if total_num_disks == 1
55
55
 
56
- raise ZipError, 'Multi-disk archives are not supported'
56
+ raise ZipError, "Multi-disk archives are not supported"
57
57
  end
58
58
 
59
59
  # In order to find the central directory, we have to first find the EOCD block.
@@ -70,13 +70,13 @@ module HttpZip
70
70
  search_end_position = candidate_eocd_block.length
71
71
  loop do
72
72
  eocd_block_start_index = candidate_eocd_block.rindex(EOCD_BLOCK_IDENTIFIER,
73
- search_end_position)
73
+ search_end_position)
74
74
 
75
- raise ZipError, 'Could not locate valid EOCD block' if eocd_block_start_index.nil?
75
+ raise ZipError, "Could not locate valid EOCD block" if eocd_block_start_index.nil?
76
76
 
77
77
  # we have a candidate, verify that we found the actual eocd block start by
78
78
  # checking whether its position + length matches the end of the file
79
- comment_length = candidate_eocd_block[(eocd_block_start_index + 20)...(eocd_block_start_index + 22)].unpack1('v')
79
+ comment_length = candidate_eocd_block[(eocd_block_start_index + 20)...(eocd_block_start_index + 22)].unpack1("v")
80
80
  if (eocd_block_start_index + 22 + comment_length) == candidate_eocd_block.length
81
81
  # we found it
82
82
  break
@@ -28,7 +28,7 @@ module HttpZip
28
28
  def initialize(file_header_bytes)
29
29
  @bytes = file_header_bytes
30
30
  unless @bytes.start_with?(CENTRAL_DIRECTORY_FILE_HEADER_IDENTIFIER)
31
- raise ZipError, 'Central Directory File Header seems to be corrupt'
31
+ raise ZipError, "Central Directory File Header seems to be corrupt"
32
32
  end
33
33
 
34
34
  parse!
@@ -47,7 +47,7 @@ module HttpZip
47
47
  @disk_number,
48
48
  @internal_file_attributes,
49
49
  @external_file_attributes,
50
- @header_offset = @bytes[20...46].unpack('VVvvvvvVV')
50
+ @header_offset = @bytes[20...46].unpack("VVvvvvvVV")
51
51
 
52
52
  file_name_end = 46 + file_name_length
53
53
  @file_name = @bytes[46...file_name_end]
@@ -72,7 +72,7 @@ module HttpZip
72
72
  # so we need to abort if there’s nothing of value in the extra fields
73
73
  break if remaining_extra_field_bytes.delete("\0").empty?
74
74
 
75
- record_length = remaining_extra_field_bytes[2...4].unpack1('v')
75
+ record_length = remaining_extra_field_bytes[2...4].unpack1("v")
76
76
 
77
77
  # did we find the Zip64 extra field?
78
78
  if remaining_extra_field_bytes.start_with?(ZIP64_EXTRA_FIELD_HEADER_ID)
@@ -95,19 +95,19 @@ module HttpZip
95
95
  # so only the values too large for the non-zip64 file header will be stored here
96
96
  ptr = 2 # ignore the size field, since it seems to be incorrect in some cases
97
97
  if @uncompressed_size == 0xFFFFFFFF
98
- @uncompressed_size = extra_field_bytes[ptr...(ptr + 8)].unpack1('Q<')
98
+ @uncompressed_size = extra_field_bytes[ptr...(ptr + 8)].unpack1("Q<")
99
99
  ptr += 8
100
100
  end
101
101
  if @compressed_size == 0xFFFFFFFF
102
- @compressed_size = extra_field_bytes[ptr...(ptr + 8)].unpack1('Q<')
102
+ @compressed_size = extra_field_bytes[ptr...(ptr + 8)].unpack1("Q<")
103
103
  ptr += 8
104
104
  end
105
105
  if @header_offset == 0xFFFFFFFF
106
- @header_offset = extra_field_bytes[ptr...(ptr + 8)].unpack1('Q<')
106
+ @header_offset = extra_field_bytes[ptr...(ptr + 8)].unpack1("Q<")
107
107
  ptr += 8
108
108
  end
109
109
  if @disk_number == 0xFFFF
110
- @disk_number = extra_field_bytes[ptr...(ptr + 4)].unpack1('V')
110
+ @disk_number = extra_field_bytes[ptr...(ptr + 4)].unpack1("V")
111
111
  end
112
112
  end
113
113
  end
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'net/http'
3
+ require "net/http"
4
4
 
5
5
  module HttpZip
6
6
  # Class to make Range requests to a HTTP server
@@ -11,7 +11,7 @@ module HttpZip
11
11
  def initialize(url)
12
12
  @uri = URI(url)
13
13
  @connection = Net::HTTP.new(@uri.host, @uri.port)
14
- @connection.use_ssl = true if @uri.scheme == 'https'
14
+ @connection.use_ssl = true if @uri.scheme == "https"
15
15
  end
16
16
 
17
17
  # Request a partial object via HTTP. If a block is given, yields the response body in chunks.
@@ -22,7 +22,7 @@ module HttpZip
22
22
  # @raise [ContentRangeError] if the server responds with anything other than 206 Partial Content
23
23
  def get(from, to, &block)
24
24
  request = Net::HTTP::Get.new(@uri)
25
- request['Range'] = "bytes=#{from}-#{to - 1}"
25
+ request["Range"] = "bytes=#{from}-#{to - 1}"
26
26
  make_request(request, &block)
27
27
  end
28
28
 
@@ -32,7 +32,7 @@ module HttpZip
32
32
  # @raise [ContentRangeError] if the server responds with anything other than 206 Partial Content
33
33
  def last(num_bytes)
34
34
  request = Net::HTTP::Get.new(@uri)
35
- request['Range'] = "bytes=-#{num_bytes}"
35
+ request["Range"] = "bytes=-#{num_bytes}"
36
36
  make_request(request)
37
37
  end
38
38
 
@@ -45,7 +45,7 @@ module HttpZip
45
45
  res.read_body(&block)
46
46
  end
47
47
 
48
- response.body unless block_given?
48
+ response.body unless block
49
49
  end
50
50
  end
51
51
 
@@ -55,7 +55,7 @@ module HttpZip
55
55
  end
56
56
  return if response.is_a?(Net::HTTPPartialContent)
57
57
 
58
- raise ContentRangeError, 'Server does not support the Range header'
58
+ raise ContentRangeError, "Server does not support the Range header"
59
59
  end
60
60
  end
61
61
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module HttpZip
4
- VERSION = '2.0.0'
4
+ VERSION = "2.1.0"
5
5
  end
data/lib/http_zip.rb CHANGED
@@ -1,11 +1,11 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'http_zip/version'
4
- require 'http_zip/errors'
5
- require 'http_zip/range_request'
6
- require 'http_zip/entry'
7
- require 'http_zip/file'
8
- require 'http_zip/parser/central_directory_file_header'
9
- require 'http_zip/parser/central_directory'
10
- require 'http_zip/compression/stored'
11
- require 'http_zip/compression/deflate'
3
+ require "http_zip/version"
4
+ require "http_zip/errors"
5
+ require "http_zip/range_request"
6
+ require "http_zip/entry"
7
+ require "http_zip/file"
8
+ require "http_zip/parser/central_directory_file_header"
9
+ require "http_zip/parser/central_directory"
10
+ require "http_zip/compression/stored"
11
+ require "http_zip/compression/deflate"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: http_zip
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.0
4
+ version: 2.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Marvin Killing
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: exe
11
11
  cert_chain: []
12
- date: 2022-04-13 00:00:00.000000000 Z
12
+ date: 1980-01-01 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: bundler
@@ -87,6 +87,34 @@ dependencies:
87
87
  - - "~>"
88
88
  - !ruby/object:Gem::Version
89
89
  version: '3.14'
90
+ - !ruby/object:Gem::Dependency
91
+ name: solargraph
92
+ requirement: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '0.50'
97
+ type: :development
98
+ prerelease: false
99
+ version_requirements: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: '0.50'
104
+ - !ruby/object:Gem::Dependency
105
+ name: standard
106
+ requirement: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: 1.31.0
111
+ type: :development
112
+ prerelease: false
113
+ version_requirements: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - "~>"
116
+ - !ruby/object:Gem::Version
117
+ version: 1.31.0
90
118
  description:
91
119
  email:
92
120
  - pe.retzlaff@gmail.com
@@ -135,7 +163,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
135
163
  - !ruby/object:Gem::Version
136
164
  version: '0'
137
165
  requirements: []
138
- rubygems_version: 3.0.9
166
+ rubygems_version: 3.5.6
139
167
  signing_key:
140
168
  specification_version: 4
141
169
  summary: HttpZip is a gem to extract individual files from a remote ZIP archive, without