rack-gzip-file 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 4daaaab6c65f1ffdf55d1da33916e1050469a6c9
4
+ data.tar.gz: 813746448715814f30db50db8104120882778833
5
+ SHA512:
6
+ metadata.gz: b63d8090b6e9c22ddd67113a1e6339b3335204b20037965ac17d895215ee2cdfa80e851adebe96b656c25d9f8f98515ec02ed8dfe4f45650c1e6a6d9cdc76193
7
+ data.tar.gz: 41f80cc1fedbc3360f7d07bcdf28c8d22beb5dfdc66a3c98cab62220484cbedab2f83eff72d4943c9a61d748f541961656dc04fc12fc4ed934b28f884019e9e1
@@ -0,0 +1,22 @@
1
+ Copyright (C) 2014 Yuji Miyane
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,37 @@
1
+ # Rack::GzipFile, Rack::GzipStatic
2
+
3
+ [English](README.md) | 日本語
4
+
5
+ Rack::GzipFileは[Rack::File](http://rack.rubyforge.org/doc/Rack/File.html)と同機能で、次に示す2つの拡張機能を持ちます。
6
+
7
+ * gzipで事前圧縮されたファイルに対する最適化機能をサポートします(Nginxのgzip\_staticモジュールと同機能)。クライアントがgzip圧縮に対応している場合は`.gz`ファイルを先に検索してそれをそのままgzip圧縮されたbodyとして返します。
8
+ * さらに`.gz`ファイルがあり、クライアントがgzipに対応していない場合はファイルを解凍してbodyとして返します。これで元の非圧縮ファイルを残しておく必要がなくなり、サーバリソースを削減できます。
9
+
10
+ Rack::GzipStaticも[Rack::Static](http://rack.rubyforge.org/doc/Rack/Static.html)と同じで、上記2点の機能拡張を加えたものです。
11
+
12
+ # インストール
13
+
14
+ ```
15
+ gem install rack-gzip-file
16
+ ```
17
+
18
+ # 使用法
19
+
20
+ Rack::File及びRack::Staticの上位互換で、機能は全く同じです。
21
+
22
+ ```
23
+ require 'rack/gzip_file'
24
+ run Rack::GzipFile.new('public')
25
+ ```
26
+
27
+ ```
28
+ require 'rack/gzip_static
29
+ use Rack::Static, :urls => {"/" => 'index.html'}, :root => 'public'
30
+ run lambda {|env|}
31
+ ```
32
+
33
+ ## ライセンス
34
+
35
+ MIT (See [LICENCE.txt](LICENCE.txt))
36
+
37
+
@@ -0,0 +1,36 @@
1
+ # Rack::GzipFile, Rack::GzipStatic
2
+
3
+ English | [日本語](README.ja.md)
4
+
5
+ Rack::GzipFile is the identical as [Rack::File](http://rack.rubyforge.org/doc/Rack/File.html) with the following two extensions.
6
+
7
+ * Supports gzip pre-compressed file optimization (same function as Nginx gzip\_static module). If a client support gzip-encoding, it searchs `.gz` file from the same directory first and returns a gzipped body.
8
+ * Furthermore, if `.gz` file exists and a client does not support gzip, it inflates `.gz` file and returns as a body (you do not have to keep an non-gzipped original file).
9
+
10
+ Rack::GzipStatic is also identical to [Rack::Static](http://rack.rubyforge.org/doc/Rack/Static.html) with the extensions shown above.
11
+
12
+ ## Install
13
+
14
+ ```
15
+ gem install rack-gzip-file
16
+ ```
17
+
18
+ ## Usage
19
+
20
+ Upper-compatible to Rack::File and Rack::Static.
21
+
22
+ ```
23
+ require 'rack/gzip_file'
24
+ run Rack::GzipFile.new('public')
25
+ ```
26
+
27
+ ```
28
+ require 'rack/gzip_static
29
+ use Rack::Static, :urls => {"/" => 'index.html'}, :root => 'public'
30
+ run lambda {|env|}
31
+ ```
32
+
33
+ ## Licence
34
+
35
+ MIT (See [LICENCE.txt](LICENCE.txt))
36
+
@@ -0,0 +1,7 @@
1
+ require 'rspec/core/rake_task'
2
+
3
+ RSpec::Core::RakeTask.new(:spec) do |t|
4
+ t.rspec_opts = '--format doc --color'
5
+ end
6
+
7
+ task default: :spec
@@ -0,0 +1,48 @@
1
+ require 'zlib'
2
+ require 'rack/file'
3
+
4
+ module Rack
5
+ # Rack::File with gzip pre-compressed files support and
6
+ # extraction for a client whitch does not support gzip.
7
+ class GzipFile
8
+ PATH_INFO = 'PATH_INFO'
9
+ DOT_GZ = '.gz'
10
+ TEXT_PLAIN = 'text/plain'
11
+ CONTENT_TYPE = 'Content-Type'
12
+ HTTP_ACCEPT_ENCODING = 'HTTP_ACCEPT_ENCODING'
13
+ GZIP = 'gzip'
14
+ CONTENT_ENCODING = 'Content-Encoding'
15
+ CONTENT_LENGTH = 'Content-Length'
16
+
17
+ def initialize(*args)
18
+ @file_server = Rack::File.new(*args)
19
+ @default_mime = args[2] || TEXT_PLAIN
20
+ end
21
+
22
+ def call(env)
23
+ path = env[PATH_INFO]
24
+ env[PATH_INFO] = path + DOT_GZ
25
+ status, headers, body = result = @file_server.call(env)
26
+ case status
27
+ when 200 # OK
28
+ mime = Rack::Mime.mime_type(::File.extname(path), @default_mime)
29
+ headers[CONTENT_TYPE] = mime if mime
30
+ enc = env[HTTP_ACCEPT_ENCODING]
31
+ if enc && enc.include?(GZIP)
32
+ headers[CONTENT_ENCODING] = GZIP
33
+ else
34
+ # inflate body for a client which does not support gzip
35
+ body = [Zlib::GzipReader.open(body.to_path) {|f| f.read }]
36
+ headers[CONTENT_LENGTH] = body[0].bytesize.to_s
37
+ headers.delete CONTENT_ENCODING
38
+ end
39
+ [status, headers, body]
40
+ when 304 # not modified
41
+ result
42
+ else # retry with the original path
43
+ env[PATH_INFO] = path
44
+ @file_server.call(env)
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,12 @@
1
+ require 'rack/static'
2
+ require 'rack/gzip_file'
3
+
4
+ module Rack
5
+ # Rack::Static with gzip pre-compressed files support.
6
+ class GzipStatic < Static
7
+ def initialize(app, options = {})
8
+ super
9
+ @file_server = Rack::GzipFile.new(options[:root] || Dir.pwd, @headers)
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,66 @@
1
+ require 'rack/gzip_file'
2
+ require 'rack/mock'
3
+
4
+ describe Rack::GzipFile do
5
+ before do
6
+ @root = 'spec/site'
7
+ @server = Rack::MockRequest.new(
8
+ Rack::GzipFile.new @root
9
+ )
10
+ @plain_content = "plain text\n"
11
+ @gzip_inflated_content = "gzipped text\n"
12
+ end
13
+
14
+ describe '#call' do
15
+ describe 'when gzip-precompressed file does not exist' do
16
+ it 'should serve non-gzipped file if exist' do
17
+ res = @server.get '/plain.txt'
18
+ res.status.should be 200
19
+ res.headers['Content-Encoding'].should be_nil
20
+ res.body.should eql @plain_content
21
+ end
22
+
23
+ it 'should respond 304 if If-Modified-Since matches' do
24
+ date = File.mtime("#{@root}/plain.txt").httpdate
25
+ res = @server.get '/plain.txt', 'HTTP_IF_MODIFIED_SINCE' => date
26
+ res.status.should be 304
27
+ res.headers.empty?.should be_true
28
+ res.body.empty?.should be_true
29
+ end
30
+
31
+ it 'should respond 404 if not exist' do
32
+ @server.get('/not-exist.txt').status.should be 404
33
+ end
34
+ end
35
+
36
+ describe 'when gzip-precompressed file exists' do
37
+ it 'should respond 304 if If-Modified-Since matches' do
38
+ date = File.mtime("#{@root}/gzipped.txt.gz").httpdate
39
+ res = @server.get '/gzipped.txt', 'HTTP_IF_MODIFIED_SINCE' => date
40
+ res.status.should be 304
41
+ res.headers.empty?.should be_true
42
+ res.body.empty?.should be_true
43
+ end
44
+
45
+ describe 'when request supports gzip encoding' do
46
+ it 'should serve gzipped body' do
47
+ res = @server.get '/gzipped.txt', 'HTTP_ACCEPT_ENCODING' => 'gzip'
48
+ res.status.should be 200
49
+ res.headers['Content-Encoding'].should eql 'gzip'
50
+ Zlib::GzipReader.new StringIO.new(res.body) do |f|
51
+ f.read.should eql @gzip_inflated_content
52
+ end
53
+ end
54
+ end
55
+
56
+ describe 'when request does not support gzip encoding' do
57
+ it 'should inflate gzipped file and serve it as body' do
58
+ res = @server.get '/gzipped.txt'
59
+ res.status.should be 200
60
+ res.headers['Content-Encoding'].should be_nil
61
+ res.body.should eql @gzip_inflated_content
62
+ end
63
+ end
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,66 @@
1
+ require 'rack/gzip_static'
2
+ require 'rack/mock'
3
+
4
+ describe Rack::GzipStatic do
5
+ before do
6
+ @root = 'spec/site'
7
+ @server = Rack::MockRequest.new(
8
+ Rack::GzipStatic.new lambda {|env|}, urls: [''], root: @root
9
+ )
10
+ @plain_content = "plain text\n"
11
+ @gzip_inflated_content = "gzipped text\n"
12
+ end
13
+
14
+ describe '#call' do
15
+ describe 'when gzip-precompressed file does not exist' do
16
+ it 'should serve non-gzipped file if exist' do
17
+ res = @server.get '/plain.txt'
18
+ res.status.should be 200
19
+ res.headers['Content-Encoding'].should be_nil
20
+ res.body.should eql @plain_content
21
+ end
22
+
23
+ it 'should respond 304 if If-Modified-Since matches' do
24
+ date = File.mtime("#{@root}/plain.txt").httpdate
25
+ res = @server.get '/plain.txt', 'HTTP_IF_MODIFIED_SINCE' => date
26
+ res.status.should be 304
27
+ res.headers.empty?.should be_true
28
+ res.body.empty?.should be_true
29
+ end
30
+
31
+ it 'should respond 404 if not exist' do
32
+ @server.get('/not-exist.txt').status.should be 404
33
+ end
34
+ end
35
+
36
+ describe 'when gzip-precompressed file exists' do
37
+ it 'should respond 304 if If-Modified-Since matches' do
38
+ date = File.mtime("#{@root}/gzipped.txt.gz").httpdate
39
+ res = @server.get '/gzipped.txt', 'HTTP_IF_MODIFIED_SINCE' => date
40
+ res.status.should be 304
41
+ res.headers.empty?.should be_true
42
+ res.body.empty?.should be_true
43
+ end
44
+
45
+ describe 'when request supports gzip encoding' do
46
+ it 'should serve gzipped body' do
47
+ res = @server.get '/gzipped.txt', 'HTTP_ACCEPT_ENCODING' => 'gzip'
48
+ res.status.should be 200
49
+ res.headers['Content-Encoding'].should eql 'gzip'
50
+ Zlib::GzipReader.new StringIO.new(res.body) do |f|
51
+ f.read.should eql @gzip_inflated_content
52
+ end
53
+ end
54
+ end
55
+
56
+ describe 'when request does not support gzip encoding' do
57
+ it 'should inflate gzipped file and serve it as body' do
58
+ res = @server.get '/gzipped.txt'
59
+ res.status.should be 200
60
+ res.headers['Content-Encoding'].should be_nil
61
+ res.body.should eql @gzip_inflated_content
62
+ end
63
+ end
64
+ end
65
+ end
66
+ end
Binary file
@@ -0,0 +1 @@
1
+ plain text
metadata ADDED
@@ -0,0 +1,86 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rack-gzip-file
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Yuji Miyane
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-04-26 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rack
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '>='
18
+ - !ruby/object:Gem::Version
19
+ version: 1.5.0
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '>='
25
+ - !ruby/object:Gem::Version
26
+ version: 1.5.0
27
+ - !ruby/object:Gem::Dependency
28
+ name: rspec
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ description: |
42
+ Extends Rack::File and Rack::Static with gzip pre-compression optimization support. Also supports gzipped file extraction for clients which do not support gzip encoding.'
43
+ email: myuj1964@gmail.com
44
+ executables: []
45
+ extensions: []
46
+ extra_rdoc_files: []
47
+ files:
48
+ - lib/rack/gzip_file.rb
49
+ - lib/rack/gzip_static.rb
50
+ - spec/site/plain.txt
51
+ - spec/site/gzipped.txt.gz
52
+ - spec/gzip_file_spec.rb
53
+ - spec/gzip_static_spec.rb
54
+ - README.md
55
+ - README.ja.md
56
+ - Rakefile
57
+ - LICENSE.txt
58
+ homepage: https://github.com/higuma/rack-gzip-file
59
+ licenses:
60
+ - MIT
61
+ metadata: {}
62
+ post_install_message:
63
+ rdoc_options: []
64
+ require_paths:
65
+ - lib
66
+ required_ruby_version: !ruby/object:Gem::Requirement
67
+ requirements:
68
+ - - '>='
69
+ - !ruby/object:Gem::Version
70
+ version: '0'
71
+ required_rubygems_version: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - '>='
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ requirements: []
77
+ rubyforge_project:
78
+ rubygems_version: 2.0.3
79
+ signing_key:
80
+ specification_version: 4
81
+ summary: Rack::GzipFile, Rack::GzipStatic
82
+ test_files:
83
+ - spec/site/plain.txt
84
+ - spec/site/gzipped.txt.gz
85
+ - spec/gzip_file_spec.rb
86
+ - spec/gzip_static_spec.rb