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 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: