heroku-deflater 0.4.2 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
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 gzipping images.
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.4.2
1
+ 0.5.0
@@ -5,7 +5,7 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = "heroku-deflater"
8
- s.version = "0.4.2"
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 "heroku_deflater.configure_rails_initialization" do |app|
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
@@ -0,0 +1,6 @@
1
+ // Fixture file
2
+ (function() {
3
+ console.log("Hello world");
4
+ console.log("Hello world");
5
+ console.log("Hello world");
6
+ })();
Binary file
@@ -0,0 +1,4 @@
1
+ // Fixture file
2
+ (function() {
3
+ console.log("Hello world");
4
+ })();
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.2
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: -1218227889335563131
103
+ hash: 262510115416976857
98
104
  required_rubygems_version: !ruby/object:Gem::Requirement
99
105
  none: false
100
106
  requirements: