ngzip 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/.rvmrc ADDED
@@ -0,0 +1,48 @@
1
+ #!/usr/bin/env bash
2
+
3
+ # This is an RVM Project .rvmrc file, used to automatically load the ruby
4
+ # development environment upon cd'ing into the directory
5
+
6
+ # First we specify our desired <ruby>[@<gemset>], the @gemset name is optional,
7
+ # Only full ruby name is supported here, for short names use:
8
+ # echo "rvm use 1.9.3" > .rvmrc
9
+ environment_id="ruby-1.9.3-p392@ngzip"
10
+
11
+ # Uncomment the following lines if you want to verify rvm version per project
12
+ # rvmrc_rvm_version="1.18.14 (version)" # 1.10.1 seams as a safe start
13
+ # eval "$(echo ${rvm_version}.${rvmrc_rvm_version} | awk -F. '{print "[[ "$1*65536+$2*256+$3" -ge "$4*65536+$5*256+$6" ]]"}' )" || {
14
+ # echo "This .rvmrc file requires at least RVM ${rvmrc_rvm_version}, aborting loading."
15
+ # return 1
16
+ # }
17
+
18
+ # First we attempt to load the desired environment directly from the environment
19
+ # file. This is very fast and efficient compared to running through the entire
20
+ # CLI and selector. If you want feedback on which environment was used then
21
+ # insert the word 'use' after --create as this triggers verbose mode.
22
+ if [[ -d "${rvm_path:-$HOME/.rvm}/environments"
23
+ && -s "${rvm_path:-$HOME/.rvm}/environments/$environment_id" ]]
24
+ then
25
+ \. "${rvm_path:-$HOME/.rvm}/environments/$environment_id"
26
+ [[ -s "${rvm_path:-$HOME/.rvm}/hooks/after_use" ]] &&
27
+ \. "${rvm_path:-$HOME/.rvm}/hooks/after_use" || true
28
+ else
29
+ # If the environment file has not yet been created, use the RVM CLI to select.
30
+ rvm --create "$environment_id" || {
31
+ echo "Failed to create RVM environment '${environment_id}'."
32
+ return 1
33
+ }
34
+ fi
35
+
36
+ # If you use bundler, this might be useful to you:
37
+ # if [[ -s Gemfile ]] && {
38
+ # ! builtin command -v bundle >/dev/null ||
39
+ # builtin command -v bundle | GREP_OPTIONS= \grep $rvm_path/bin/bundle >/dev/null
40
+ # }
41
+ # then
42
+ # printf "%b" "The rubygem 'bundler' is not installed. Installing it now.\n"
43
+ # gem install bundler
44
+ # fi
45
+ # if [[ -s Gemfile ]] && builtin command -v bundle >/dev/null
46
+ # then
47
+ # bundle install | GREP_OPTIONS= \grep -vE '^Using|Your bundle is complete'
48
+ # fi
@@ -0,0 +1,3 @@
1
+ ### 1.0.0 (2013-07-14)
2
+
3
+ * Initial public release
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in ngzip.gemspec
4
+ gemspec
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 ncode gmbh
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,34 @@
1
+ # Ngzip
2
+
3
+ This gem allows easy integration of nginx mod_zip into your ruby/rails application by providing
4
+ the formatted output list and a HTTP header to use the on-thy-fly creation of ZIP archives.
5
+
6
+ ## Installation
7
+
8
+ Add this line to your application's Gemfile:
9
+
10
+ gem 'ngzip'
11
+
12
+ And then execute:
13
+
14
+ $ bundle
15
+
16
+ Or install it yourself as:
17
+
18
+ $ gem install ngzip
19
+
20
+ ## Usage
21
+
22
+ In a controller
23
+
24
+ b = Nginx::Builder.new()
25
+ response.headers['X-Archive-Files'] = 'zip'
26
+ render :text => b.build("/data/test/Report.pdf", "/data/test/LargeArchive.tar")
27
+
28
+
29
+ ## License
30
+
31
+ Copyright (c) 2013, ncode gmbh. All Rights Reserved.
32
+
33
+ This project is licenced under the [MIT License](LICENSE.txt).
34
+
@@ -0,0 +1,11 @@
1
+ require "bundler/gem_tasks"
2
+
3
+ require "rake/testtask"
4
+
5
+ Rake::TestTask.new do |t|
6
+ t.libs << 'lib'
7
+ t.test_files = FileList['test/lib/ngzip/*_test.rb']
8
+ t.verbose = true
9
+ end
10
+
11
+ task :default => :test
@@ -0,0 +1,8 @@
1
+ require "ngzip/version"
2
+ require "ngzip/builder"
3
+
4
+ module Ngzip
5
+ def self.build
6
+
7
+ end
8
+ end
@@ -0,0 +1,106 @@
1
+ require 'zlib'
2
+
3
+ module Ngzip
4
+
5
+ class Builder
6
+
7
+ BUFFER_SIZE = 8 * 1024
8
+
9
+ # Public: Build the files manifest for mod_zip, see http://wiki.nginx.org/NginxNgxZip for the specs.
10
+ #
11
+ # files - An Array of absolute file path elements
12
+ # options - The options, see below
13
+ #
14
+ # Returns a line for each file separated by \n
15
+ #
16
+ # The following options are available:
17
+ # :crc => Enable or disable CRC-32 checksums
18
+ # :crc_cache => Allows for provided cached CRC-32 checksums in a hash where the key is the file path
19
+ def build(files, options = {})
20
+ settings = {:crc => true}
21
+ settings.merge! options
22
+
23
+ list = file_list(files)
24
+ prefix = detect_common_prefix(list)
25
+ list.map do |f|
26
+ sprintf("%s %d %s %s",
27
+ compute_crc32(f, settings),
28
+ File.size(f).to_i,
29
+ f,
30
+ f.gsub(prefix, '')
31
+ )
32
+ end.join("\n")
33
+
34
+ end
35
+
36
+ # Public: Get the special header to signal the mod_zip
37
+ #
38
+ # Returns the header as a string "key: value"
39
+ def header()
40
+ "X-Archive-Files: zip"
41
+ end
42
+
43
+ private
44
+
45
+ # Internal: Compute a common prefix from a list of path elements
46
+ #
47
+ # list - The list of file path elements
48
+ #
49
+ # Returns a common prefix
50
+ def detect_common_prefix(list)
51
+ if list.size == 1
52
+ return File.dirname(list.first) + '/'
53
+ end
54
+ prefix = ''
55
+ min, max = list.sort.values_at(0, -1)
56
+ min.split(//).each_with_index do |c, i|
57
+ break if c != max[i, 1]
58
+ prefix << c
59
+ end
60
+ prefix
61
+ end
62
+
63
+ # Internal: Compute the file list by expanding directories
64
+ #
65
+ def file_list(files)
66
+ Array(files).map do |e|
67
+ if File.directory?(e)
68
+ Dir.glob("#{e}/**/*.*")
69
+ else
70
+ e
71
+ end
72
+ end.flatten
73
+
74
+ end
75
+
76
+
77
+ # Internal: Compute the CRC-32 checksum for a file unless the settings
78
+ # disable the computation (:crc => false) and this method returns "-"
79
+ #
80
+ # file - The full path to the file
81
+ # settings - The settings hash
82
+ #
83
+ # Returns a hex string
84
+ def compute_crc32(file, settings)
85
+ return '-' unless settings[:crc]
86
+
87
+ # honor the cache
88
+ if settings[:crc_cache] && settings[:crc_cache][file]
89
+ return settings[:crc_cache][file]
90
+ end
91
+
92
+ # read using a buffer, we might operate on large files!
93
+ crc32 = 0
94
+ File.open(file,'rb') do |f|
95
+ while buffer = f.read(BUFFER_SIZE) do
96
+ crc32 = Zlib.crc32(buffer, crc32)
97
+ end
98
+ end
99
+ crc32.to_s(16)
100
+ end
101
+
102
+
103
+
104
+ end
105
+
106
+ end
@@ -0,0 +1,3 @@
1
+ module Ngzip
2
+ VERSION = "1.0.0"
3
+ end
@@ -0,0 +1,24 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'ngzip/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "ngzip"
8
+ spec.version = Ngzip::VERSION
9
+ spec.authors = ["dup2"]
10
+ spec.email = ["zarkov@ncode.ch"]
11
+ spec.description = %q{Provides a nginx mod_zip compatible file manifest for streaming support.
12
+ See http://wiki.nginx.org/NginxNgxZip for the nginx module.}
13
+ spec.summary = %q{Provides a nginx mod_zip compatible file manifest for streaming support}
14
+ spec.homepage = ""
15
+ spec.license = "MIT"
16
+
17
+ spec.files = `git ls-files`.split($/)
18
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
19
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
20
+ spec.require_paths = ["lib"]
21
+
22
+ spec.add_development_dependency "bundler", "~> 1.3"
23
+ spec.add_development_dependency "rake"
24
+ end
@@ -0,0 +1 @@
1
+ Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
@@ -0,0 +1 @@
1
+ Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
Binary file
@@ -0,0 +1,3 @@
1
+ Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
2
+
3
+ Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
@@ -0,0 +1,5 @@
1
+ Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
2
+
3
+ Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
4
+
5
+ Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
@@ -0,0 +1,89 @@
1
+ require_relative "../../test_helper"
2
+
3
+ describe Ngzip do
4
+
5
+ it 'must support the static method :build' do
6
+ Ngzip.respond_to?(:build).must_equal true
7
+ end
8
+
9
+ end
10
+
11
+ describe Ngzip::Builder do
12
+
13
+ let(:builder) {Ngzip::Builder.new()}
14
+ let(:lorem) {File.expand_path('../../../data/a/lorem.txt', __FILE__)}
15
+ let(:ipsum) {File.expand_path('../../../data/a/ipsum.txt', __FILE__)}
16
+ let(:cargo) {File.expand_path('../../../data/b/Cargo.png', __FILE__)}
17
+ let(:sit) {File.expand_path('../../../data/sit.txt', __FILE__)}
18
+ let(:a) {File.expand_path('../../../data/a', __FILE__)}
19
+
20
+ it 'must be defined' do
21
+ Ngzip::Builder.wont_be_nil
22
+ end
23
+
24
+ it 'must be a class we can call :new on' do
25
+ Ngzip::Builder.new().wont_be_nil
26
+ end
27
+
28
+ it 'must respond to :build' do
29
+ builder.respond_to?(:build).must_equal true
30
+ end
31
+
32
+ describe "with CRC-32 checksums disabled" do
33
+ let(:options) { {:crc => false}}
34
+
35
+ it 'must return a correct list for one file' do
36
+ expected = "- 446 #{lorem} lorem.txt"
37
+ builder.build(lorem, options).must_equal expected
38
+ end
39
+ end
40
+
41
+ describe "with CRC-32 checksums enabled" do
42
+ let(:options) { {:crc => true}}
43
+
44
+ it 'must return a correct list for one file with a checksum' do
45
+ expected = "8f92322f 446 #{lorem} lorem.txt"
46
+ builder.build(lorem, options).must_equal expected
47
+ end
48
+
49
+ it 'must return a correct list for one binary file with a checksum' do
50
+ expected = "b2f4655b 11550 #{cargo} Cargo.png"
51
+ builder.build(cargo, options).must_equal expected
52
+ end
53
+
54
+ it 'must return a correct list for all files in a directory' do
55
+ expected = "8f92322f 446 #{ipsum} ipsum.txt\n8f92322f 446 #{lorem} lorem.txt"
56
+ builder.build(a,options).must_equal expected
57
+ end
58
+
59
+ it 'must allow to mix files and directories' do
60
+ expected = "8f92322f 446 #{ipsum} a/ipsum.txt"
61
+ expected << "\n8f92322f 446 #{lorem} a/lorem.txt"
62
+ expected << "\nf7c0867d 1342 #{sit} sit.txt"
63
+ builder.build([a,sit], options).must_equal expected
64
+ end
65
+
66
+ it 'must preserve directory names' do
67
+ expected = [
68
+ "8f92322f 446 #{lorem} a/lorem.txt",
69
+ "8f92322f 446 #{ipsum} a/ipsum.txt",
70
+ "b2f4655b 11550 #{cargo} b/Cargo.png"
71
+ ].join("\n")
72
+ builder.build([lorem,ipsum,cargo], options).must_equal expected
73
+ end
74
+
75
+ it 'must honor the CRC cache' do
76
+ invalid_but_cached = "781aaabcc124"
77
+ expected = "#{invalid_but_cached} 446 #{lorem} lorem.txt"
78
+ builder.build(lorem, options.merge(:crc_cache => {lorem => invalid_but_cached})).must_equal expected
79
+ end
80
+
81
+
82
+ end
83
+
84
+
85
+
86
+
87
+
88
+ end
89
+
@@ -0,0 +1,9 @@
1
+ require_relative "../../test_helper"
2
+
3
+ describe Ngzip do
4
+
5
+ it "must define a version" do
6
+ Ngzip::VERSION.wont_be_nil
7
+ end
8
+
9
+ end
@@ -0,0 +1,4 @@
1
+ require 'minitest/autorun'
2
+ require 'minitest/pride'
3
+ require File.expand_path('../../lib/ngzip.rb', __FILE__)
4
+
metadata ADDED
@@ -0,0 +1,112 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ngzip
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - dup2
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-07-14 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: bundler
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: '1.3'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ version: '1.3'
30
+ - !ruby/object:Gem::Dependency
31
+ name: rake
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :development
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ description: ! "Provides a nginx mod_zip compatible file manifest for streaming support.\n
47
+ \ See http://wiki.nginx.org/NginxNgxZip for the nginx module."
48
+ email:
49
+ - zarkov@ncode.ch
50
+ executables: []
51
+ extensions: []
52
+ extra_rdoc_files: []
53
+ files:
54
+ - .gitignore
55
+ - .rvmrc
56
+ - CHANGELOG
57
+ - Gemfile
58
+ - LICENSE.txt
59
+ - README.md
60
+ - Rakefile
61
+ - lib/ngzip.rb
62
+ - lib/ngzip/builder.rb
63
+ - lib/ngzip/version.rb
64
+ - ngzip.gemspec
65
+ - test/data/a/ipsum.txt
66
+ - test/data/a/lorem.txt
67
+ - test/data/b/Cargo.png
68
+ - test/data/b/dolor.txt
69
+ - test/data/sit.txt
70
+ - test/lib/ngzip/builder_test.rb
71
+ - test/lib/ngzip/version_test.rb
72
+ - test/test_helper.rb
73
+ homepage: ''
74
+ licenses:
75
+ - MIT
76
+ post_install_message:
77
+ rdoc_options: []
78
+ require_paths:
79
+ - lib
80
+ required_ruby_version: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ! '>='
84
+ - !ruby/object:Gem::Version
85
+ version: '0'
86
+ segments:
87
+ - 0
88
+ hash: -3265339193018102278
89
+ required_rubygems_version: !ruby/object:Gem::Requirement
90
+ none: false
91
+ requirements:
92
+ - - ! '>='
93
+ - !ruby/object:Gem::Version
94
+ version: '0'
95
+ segments:
96
+ - 0
97
+ hash: -3265339193018102278
98
+ requirements: []
99
+ rubyforge_project:
100
+ rubygems_version: 1.8.25
101
+ signing_key:
102
+ specification_version: 3
103
+ summary: Provides a nginx mod_zip compatible file manifest for streaming support
104
+ test_files:
105
+ - test/data/a/ipsum.txt
106
+ - test/data/a/lorem.txt
107
+ - test/data/b/Cargo.png
108
+ - test/data/b/dolor.txt
109
+ - test/data/sit.txt
110
+ - test/lib/ngzip/builder_test.rb
111
+ - test/lib/ngzip/version_test.rb
112
+ - test/test_helper.rb