heroku-deflater 0.4.2 → 0.5.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.
- data/README.md +9 -2
- data/VERSION +1 -1
- data/heroku-deflater.gemspec +7 -1
- data/lib/heroku-deflater/railtie.rb +4 -1
- data/lib/heroku-deflater/serve_zipped_assets.rb +52 -0
- data/spec/fixtures/assets/spec.js +6 -0
- data/spec/fixtures/assets/spec.js.gz +0 -0
- data/spec/fixtures/assets/spec2.js +4 -0
- data/spec/fixtures/non-assets/spec.js.gz +0 -0
- data/spec/serve_zipped_assets_spec.rb +60 -0
- metadata +8 -2
data/README.md
CHANGED
@@ -1,7 +1,14 @@
|
|
1
1
|
# heroku-deflater
|
2
2
|
|
3
3
|
A simple rack middleware that enables compressing of your assets and application
|
4
|
-
responses on Heroku, while not wasting CPU cycles on pointlessly
|
4
|
+
responses on Heroku, while not wasting CPU cycles on pointlessly compressing images
|
5
|
+
and other binary responses.
|
6
|
+
|
7
|
+
It also includes code from https://github.com/mattolson/heroku_rails_deflate
|
8
|
+
|
9
|
+
Before serving a file from disk to a gzip-enabled client, it will look for
|
10
|
+
a precompressed file in the same location that ends in ".gz".
|
11
|
+
The purpose is to avoid compressing the same file each time it is requested.
|
5
12
|
|
6
13
|
## Installing
|
7
14
|
|
@@ -11,7 +18,7 @@ Add to your Gemfile:
|
|
11
18
|
|
12
19
|
|
13
20
|
## Contributing to heroku-deflater
|
14
|
-
|
21
|
+
|
15
22
|
* Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet.
|
16
23
|
* Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it.
|
17
24
|
* Fork the project.
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.5.0
|
data/heroku-deflater.gemspec
CHANGED
@@ -5,7 +5,7 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = "heroku-deflater"
|
8
|
-
s.version = "0.
|
8
|
+
s.version = "0.5.0"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Roman Shterenzon"]
|
@@ -27,7 +27,13 @@ Gem::Specification.new do |s|
|
|
27
27
|
"heroku-deflater.gemspec",
|
28
28
|
"lib/heroku-deflater.rb",
|
29
29
|
"lib/heroku-deflater/railtie.rb",
|
30
|
+
"lib/heroku-deflater/serve_zipped_assets.rb",
|
30
31
|
"lib/heroku-deflater/skip_binary.rb",
|
32
|
+
"spec/fixtures/assets/spec.js",
|
33
|
+
"spec/fixtures/assets/spec.js.gz",
|
34
|
+
"spec/fixtures/assets/spec2.js",
|
35
|
+
"spec/fixtures/non-assets/spec.js.gz",
|
36
|
+
"spec/serve_zipped_assets_spec.rb",
|
31
37
|
"spec/skip_binary_spec.rb"
|
32
38
|
]
|
33
39
|
s.homepage = "http://github.com/romanbsd/heroku-deflater"
|
@@ -1,11 +1,14 @@
|
|
1
1
|
require 'rack/deflater'
|
2
2
|
require 'heroku-deflater/skip_binary'
|
3
|
+
require 'heroku-deflater/serve_zipped_assets'
|
3
4
|
|
4
5
|
module HerokuDeflater
|
5
6
|
class Railtie < Rails::Railtie
|
6
|
-
initializer
|
7
|
+
initializer 'heroku_deflater.configure_rails_initialization' do |app|
|
7
8
|
app.middleware.insert_before ActionDispatch::Static, Rack::Deflater
|
8
9
|
app.middleware.insert_before ActionDispatch::Static, HerokuDeflater::SkipBinary
|
10
|
+
app.middleware.insert_before Rack::Deflater, HerokuDeflater::ServeZippedAssets,
|
11
|
+
app.paths['public'].first, app.config.assets.prefix, {'Cache-Control' => app.config.static_cache_control}
|
9
12
|
end
|
10
13
|
|
11
14
|
# Set default Cache-Control headers to one week.
|
@@ -0,0 +1,52 @@
|
|
1
|
+
require 'action_controller'
|
2
|
+
require 'active_support/core_ext/uri'
|
3
|
+
require 'action_dispatch/middleware/static'
|
4
|
+
|
5
|
+
# Adapted from https://gist.github.com/guyboltonking/2152663
|
6
|
+
#
|
7
|
+
# Taken from: https://github.com/mattolson/heroku_rails_deflate
|
8
|
+
#
|
9
|
+
|
10
|
+
module HerokuDeflater
|
11
|
+
class ServeZippedAssets
|
12
|
+
def initialize(app, root, assets_path, headers=nil)
|
13
|
+
@app = app
|
14
|
+
@assets_path = assets_path.chomp('/') + '/'
|
15
|
+
@file_handler = ActionDispatch::FileHandler.new(root, headers)
|
16
|
+
end
|
17
|
+
|
18
|
+
def call(env)
|
19
|
+
if env['REQUEST_METHOD'] == 'GET'
|
20
|
+
request = Rack::Request.new(env)
|
21
|
+
encoding = Rack::Utils.select_best_encoding(%w(gzip identity), request.accept_encoding)
|
22
|
+
|
23
|
+
if encoding == 'gzip'
|
24
|
+
# See if gzipped version exists in assets directory
|
25
|
+
compressed_path = env['PATH_INFO'] + '.gz'
|
26
|
+
|
27
|
+
if compressed_path.start_with?(@assets_path) && (match = @file_handler.match?(compressed_path))
|
28
|
+
# Get the FileHandler to serve up the gzipped file, then strip the .gz suffix
|
29
|
+
env['PATH_INFO'] = match
|
30
|
+
status, headers, body = @file_handler.call(env)
|
31
|
+
env['PATH_INFO'].chomp!('.gz')
|
32
|
+
|
33
|
+
# Set the Vary HTTP header.
|
34
|
+
vary = headers['Vary'].to_s.split(',').map(&:strip)
|
35
|
+
|
36
|
+
unless vary.include?('*') || vary.include?('Accept-Encoding')
|
37
|
+
headers['Vary'] = vary.push('Accept-Encoding').join(',')
|
38
|
+
end
|
39
|
+
|
40
|
+
# Add encoding and type
|
41
|
+
headers['Content-Encoding'] = 'gzip'
|
42
|
+
headers['Content-Type'] = Rack::Mime.mime_type(File.extname(env['PATH_INFO']), 'text/plain')
|
43
|
+
|
44
|
+
return [status, headers, body]
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
@app.call(env)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
Binary file
|
Binary file
|
@@ -0,0 +1,60 @@
|
|
1
|
+
require 'rack/mock'
|
2
|
+
require 'rack/static'
|
3
|
+
require 'heroku-deflater/serve_zipped_assets'
|
4
|
+
|
5
|
+
describe HerokuDeflater::ServeZippedAssets do
|
6
|
+
def process(path, accept_encoding = 'compress, gzip, deflate')
|
7
|
+
env = Rack::MockRequest.env_for(path)
|
8
|
+
env['HTTP_ACCEPT_ENCODING'] = accept_encoding
|
9
|
+
app.call(env)
|
10
|
+
end
|
11
|
+
|
12
|
+
def app
|
13
|
+
@app ||= begin
|
14
|
+
root_path = File.expand_path('../fixtures', __FILE__)
|
15
|
+
headers = {'Cache-Control'=>'public, max-age=86400'}
|
16
|
+
mock = lambda { |env| [404, {'X-Cascade' => 'pass'}, []] }
|
17
|
+
described_class.new(mock, root_path, '/assets', headers)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'does nothing for clients which do not want gzip' do
|
22
|
+
status, headers, body = process('/assets/spec.js', nil)
|
23
|
+
status.should eq(404)
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'handles the pre-gzipped assets' do
|
27
|
+
status, headers, body = process('/assets/spec.js')
|
28
|
+
status.should eq(200)
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'has correct content type' do
|
32
|
+
status, headers, body = process('/assets/spec.js')
|
33
|
+
headers['Content-Type'].should eq('application/javascript')
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'has correct content encoding' do
|
37
|
+
status, headers, body = process('/assets/spec.js')
|
38
|
+
headers['Content-Encoding'].should eq('gzip')
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'has correct content length' do
|
42
|
+
status, headers, body = process('/assets/spec.js')
|
43
|
+
headers['Content-Length'].should eq('86')
|
44
|
+
end
|
45
|
+
|
46
|
+
it 'has correct cache control' do
|
47
|
+
status, headers, body = process('/assets/spec.js')
|
48
|
+
headers['Cache-Control'].should eq('public, max-age=86400')
|
49
|
+
end
|
50
|
+
|
51
|
+
it 'does not serve non-gzipped assets' do
|
52
|
+
status, headers, body = process('/assets/spec2.js')
|
53
|
+
status.should eq(404)
|
54
|
+
end
|
55
|
+
|
56
|
+
it 'does not serve anything from non-asset directories' do
|
57
|
+
status, headers, body = process('/non-assets/spec.js')
|
58
|
+
status.should eq(404)
|
59
|
+
end
|
60
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: heroku-deflater
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -77,7 +77,13 @@ files:
|
|
77
77
|
- heroku-deflater.gemspec
|
78
78
|
- lib/heroku-deflater.rb
|
79
79
|
- lib/heroku-deflater/railtie.rb
|
80
|
+
- lib/heroku-deflater/serve_zipped_assets.rb
|
80
81
|
- lib/heroku-deflater/skip_binary.rb
|
82
|
+
- spec/fixtures/assets/spec.js
|
83
|
+
- spec/fixtures/assets/spec.js.gz
|
84
|
+
- spec/fixtures/assets/spec2.js
|
85
|
+
- spec/fixtures/non-assets/spec.js.gz
|
86
|
+
- spec/serve_zipped_assets_spec.rb
|
81
87
|
- spec/skip_binary_spec.rb
|
82
88
|
homepage: http://github.com/romanbsd/heroku-deflater
|
83
89
|
licenses:
|
@@ -94,7 +100,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
94
100
|
version: '0'
|
95
101
|
segments:
|
96
102
|
- 0
|
97
|
-
hash:
|
103
|
+
hash: 262510115416976857
|
98
104
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
99
105
|
none: false
|
100
106
|
requirements:
|