zip_tricks 4.2.2 → 4.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
  SHA1:
3
- metadata.gz: 62ea03396a8a75e72000952d6c5ff69b9d8f0a80
4
- data.tar.gz: 6cf0bca2293065a1b5430e73d26a9a0117064adb
3
+ metadata.gz: cc23010c353f0d1118cdbb38649c1363ffe34b7c
4
+ data.tar.gz: 8be7f24974d25870fd0b9c6852e0ad8fcff1ff0b
5
5
  SHA512:
6
- metadata.gz: c5ca0c25882b1770b663b199bc6f00b4763691f51f9bc34cd9594442be37e942738c1fbbcf6eff0d8aac56e99a81310f4e691a32aed3a84647e0a8e3d48aa9f2
7
- data.tar.gz: 4d53363180343a0017e4054c2d55b40da0c74213a75a3aaf1e339715a6a3ad5ae9b7150abb79685f9cc9d19822d84e9122a12399a75f5488fccad18e35b31357
6
+ metadata.gz: 15d547d8f049bd7eb71470632c43ccd836d24908d5e98061421caa0af28f8e1747bcbc993906e112fc2874af8b423d879510be2b6a49d1c346f820058f715e11
7
+ data.tar.gz: b16df9dcbb072b215f866f83cfd073157d21ca2d7e5f336e0226c509b858925e12149f831d816dbf159d041f0cfab27d16bb934692c66b7eefa5bdc048cbb5e1
data/README.md CHANGED
@@ -3,17 +3,28 @@
3
3
  [![Build Status](https://travis-ci.org/WeTransfer/zip_tricks.svg?branch=master)](https://travis-ci.org/WeTransfer/zip_tricks)
4
4
 
5
5
  Allows streaming, non-rewinding ZIP file output from Ruby.
6
- Spiritual successor to [zipline](https://github.com/fringd/zipline)
7
- Requires Ruby 2.1+ syntax support and a working zlib (all available to jRuby as well).
6
+
7
+ Initially written and as a spiritual successor to [zipline](https://github.com/fringd/zipline)
8
+ and now proudly powering it under the hood.
8
9
 
9
10
  Allows you to write a ZIP archive out to a File, Socket, String or Array without having to rewind it at any
10
11
  point. Usable for creating very large ZIP archives for immediate sending out to clients, or for writing
11
12
  large ZIP archives without memory inflation.
12
13
 
13
- ## Create a ZIP file without size estimation, compress on-the-fly)
14
+ zip_tricks currently handles all our zipping needs (millions of ZIP files generated per day), so we are
15
+ pretty confident it is widely compatible with a large number of unarchiving end-user applications.
16
+
17
+ ## Requirements
18
+
19
+ Ruby 2.1+ syntax support (keyword arguments with defaults) and a working zlib (all available to jRuby as well).
20
+ jRuby might experience problems when using the reader methods due to the argument of `IO#seek` being limited
21
+ to [32 bit sizes.](https://github.com/jruby/jruby/issues/3817)
22
+
23
+ ## Create a ZIP file without size estimation, compress on-the-fly during writes
14
24
 
15
- When you compress on the fly and use data descriptors it is not really possible to compute the file size upfront.
16
- But it is very likely to yield good compression - especially if you send things like CSV files.
25
+ Basic use case is compressing on the fly. Some data will be buffered by the Zlib deflater, but
26
+ memory inflation is going to be very constrained. Data will be written to destination at fairly regular
27
+ intervals. Deflate compression will work best for things like text files.
17
28
 
18
29
  ```ruby
19
30
  out = my_tempfile # can also be a socket
@@ -26,8 +37,10 @@ ZipTricks::Streamer.open(out) do |zip|
26
37
  end
27
38
  end
28
39
  ```
40
+ Unfortunately with this approach it is impossible to compute the size of the ZIP file being output,
41
+ since you do not know how large the compressed data segments are going to be.
29
42
 
30
- ## Send the same ZIP file from a Rack response
43
+ ## Send a ZIP from a Rack response
31
44
 
32
45
  Create a `RackBody` object and give it's constructor a block that adds files.
33
46
  The block will only be called when actually sending the response to the client
@@ -50,6 +63,12 @@ end
50
63
  Use the `SizeEstimator` to compute the correct size of the resulting archive.
51
64
 
52
65
  ```ruby
66
+ # Precompute the Content-Length ahead of time
67
+ bytesize = ZipTricks::SizeEstimator.estimate do |z|
68
+ z.add_stored_entry(filename: 'myfile1.bin', size: 9090821)
69
+ z.add_stored_entry(filename: 'myfile2.bin', size: 458678)
70
+ end
71
+
53
72
  # Prepare the response body. The block will only be called when the response starts to be written.
54
73
  zip_body = ZipTricks::RackBody.new do | zip |
55
74
  zip.add_stored_entry(filename: "myfile1.bin", size: 9090821, crc32: 12485)
@@ -58,20 +77,9 @@ zip_body = ZipTricks::RackBody.new do | zip |
58
77
  zip << read_file('myfile2.bin')
59
78
  end
60
79
 
61
- # Precompute the Content-Length ahead of time
62
- bytesize = ZipTricks::SizeEstimator.estimate do |z|
63
- z.add_stored_entry(filename: 'myfile1.bin', size: 9090821)
64
- z.add_stored_entry(filename: 'myfile2.bin', size: 458678)
65
- end
66
-
67
80
  [200, {'Content-Length' => bytesize.to_s}, zip_body]
68
81
  ```
69
82
 
70
- ## Other usage examples
71
-
72
- Check out the `examples/` directory at the root of the project. This will give you a good idea
73
- of various use cases the library supports.
74
-
75
83
  ## Writing ZIP files using the Streamer bypass
76
84
 
77
85
  You do not have to "feed" all the contents of the files you put in the archive through the Streamer object.
@@ -94,6 +102,11 @@ ZipTricks::Streamer.open(io) do | zip |
94
102
  end
95
103
  ```
96
104
 
105
+ ## Other usage examples
106
+
107
+ Check out the `examples/` directory at the root of the project. This will give you a good idea
108
+ of various use cases the library supports.
109
+
97
110
  ## Computing the CRC32 value of a large file
98
111
 
99
112
  `BlockCRC32` computes the CRC32 checksum of an IO in a streaming fashion.
@@ -110,6 +123,13 @@ crc.to_i # Returns the actual CRC32 value computed so far
110
123
  crc.append(precomputed_crc32, size_of_the_blob_computed_from)
111
124
  ```
112
125
 
126
+ ## Reading ZIP files
127
+
128
+ The library contains a reader module, play with it to see what is possible. It is not a complete ZIP reader
129
+ but it was designed for a specific purpose (highly-parallel unpacking of remotely stored ZIP files), and
130
+ as such it performs it's function quite well. Please beware of the security implications of using ZIP readers
131
+ that have not been formally verified (ours hasn't been).
132
+
113
133
  ## Contributing to zip_tricks
114
134
 
115
135
  * Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet.
@@ -119,6 +139,7 @@ crc.append(precomputed_crc32, size_of_the_blob_computed_from)
119
139
  * Commit and push until you are happy with your contribution.
120
140
  * Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
121
141
  * Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
142
+ * If you alter the `ZipWriter`, please take the time to run the test in the `testing/` directory and verify the generated files do open. You will need fast storage to run those tests.
122
143
 
123
144
  ## Copyright
124
145
 
data/lib/zip_tricks.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  module ZipTricks
2
- VERSION = '4.2.2'
2
+ VERSION = '4.2.3'
3
3
 
4
4
  # Require all the sub-components except myself
5
5
  Dir.glob(__dir__ + '/**/*.rb').sort.each {|p| require p unless p == __FILE__ }
@@ -1,21 +1,29 @@
1
1
  class ZipTricks::Streamer::DeflatedWriter
2
+ # After how many bytes of incoming data the deflater for the
3
+ # contents must be flushed. This is done to prevent unreasonable
4
+ # memory use when archiving large files.
5
+ FLUSH_EVERY_N_BYTES = 1024 * 1024 * 5
6
+
2
7
  def initialize(io)
3
8
  @io = io
4
9
  @uncompressed_size = 0
5
10
  @started_at = @io.tell
6
11
  @crc = ZipTricks::StreamCRC32.new
12
+ @deflater = ::Zlib::Deflate.new(Zlib::DEFAULT_COMPRESSION, -::Zlib::MAX_WBITS)
7
13
  @bytes_since_last_flush = 0
8
14
  end
9
15
 
10
16
  def finish
11
- ZipTricks::BlockDeflate.write_terminator(@io)
17
+ @io << @deflater.finish until @deflater.finished?
12
18
  [@crc.to_i, @io.tell - @started_at, @uncompressed_size]
13
19
  end
14
20
 
15
21
  def <<(data)
16
22
  @uncompressed_size += data.bytesize
17
- @io << ZipTricks::BlockDeflate.deflate_chunk(data)
23
+ @bytes_since_last_flush += data.bytesize
24
+ @io << @deflater.deflate(data)
18
25
  @crc << data
26
+ interim_flush
19
27
  self
20
28
  end
21
29
 
@@ -23,4 +31,12 @@ class ZipTricks::Streamer::DeflatedWriter
23
31
  self << data
24
32
  data.bytesize
25
33
  end
26
- end
34
+
35
+ private
36
+
37
+ def interim_flush
38
+ return if @bytes_since_last_flush < FLUSH_EVERY_N_BYTES
39
+ @io << @deflater.flush
40
+ @bytes_since_last_flush = 0
41
+ end
42
+ end
data/zip_tricks.gemspec CHANGED
@@ -2,16 +2,16 @@
2
2
  # DO NOT EDIT THIS FILE DIRECTLY
3
3
  # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
4
  # -*- encoding: utf-8 -*-
5
- # stub: zip_tricks 4.2.2 ruby lib
5
+ # stub: zip_tricks 4.2.3 ruby lib
6
6
 
7
7
  Gem::Specification.new do |s|
8
8
  s.name = "zip_tricks"
9
- s.version = "4.2.2"
9
+ s.version = "4.2.3"
10
10
 
11
11
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
12
12
  s.require_paths = ["lib"]
13
13
  s.authors = ["Julik Tarkhanov"]
14
- s.date = "2016-11-13"
14
+ s.date = "2016-11-18"
15
15
  s.description = "Stream out ZIP files from Ruby"
16
16
  s.email = "me@julik.nl"
17
17
  s.extra_rdoc_files = [
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: zip_tricks
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.2.2
4
+ version: 4.2.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Julik Tarkhanov
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-11-13 00:00:00.000000000 Z
11
+ date: 2016-11-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rubyzip