rack-zippy 3.0.1 → 4.0.0

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: 69996e12bfb698114f7dfea5d26a0837de4041c1
4
+ data.tar.gz: 123aca242bc132651dba0ee53d666efe05a2e4a9
5
+ SHA512:
6
+ metadata.gz: 43c0d933b8b6129d9a18b733c05e309f6986b4d9251f98a658c19a9ff7925b80c817ee08c34b3cc0888e4640e3d96320bfb1d5371870610d01366301b491a8c6
7
+ data.tar.gz: a0a6d4e154724317cda6fe934babc845b6f51779a73fb22915abc01a1d14e7a76ff947303e4eadfcef5a59c5605758bfbe22523eb50f5bb97bba99dcc70126ce
@@ -1,8 +1,12 @@
1
+ ## 4.0.0 / 2015-10-20
2
+ - Rack Zippy continues to support non-Rails Rack apps, though Rails support has ended in rack-zippy 4.0+. Rails 4.2+ now supports serving gzipped files directly. Configure your Rails 4.2+ app to use the `ActionDispatch::Static` middleware. If you absolutely need rack-zippy for your Rails app or can't upgrade to Rails 4.2+, try using an earlier rack-zippy version: `~> 3.0.1`
3
+ - New dependency on actionpack gem. Rack Zippy decorates the `ActionDispatch::Static` middleware for non-Rails Rack apps to provide Rack Zippy's own choice of caching headers and whitelisting of permitted static file extensions.
4
+
1
5
  ## 3.0.1 / 2015-05-19
2
6
  - Allow paths with periods in the middle, but not if they immediately follow slash ([#46](https://github.com/eliotsykes/rack-zippy/pull/46)) @ssemakov
3
7
 
4
8
  ## 3.0.0 / 2015-04-18
5
- - POTENTIAL BREAKING CHANGE! `STATIC_EXTENSION_REGEX` has been removed and replaced with a `static_extensions` array. If your app monkey patched `STATIC_EXTENSTION_REGEX` to change the file extension whitelist, then you will need to update your app to use rack-zippy 3.x. Depending on how you patched, and your test coverage, your app could silently fail. Search your codebase for `STATIC_EXTENSION_REGEX` to ensure it is not used. If it is used, then migrate your patch to use the new `Rack::Zippy.config` method for configuring `static_extensions`: https://github.com/eliotsykes/rack-zippy#static_extensions
9
+ - POTENTIAL BREAKING CHANGE! `STATIC_EXTENSION_REGEX` has been removed and replaced with a `static_extensions` array. If your app monkey patched `STATIC_EXTENSTION_REGEX` to change the file extension whitelist, then you will need to update your app to use rack-zippy 3.x. Depending on how you patched, and your test coverage, your app could silently fail. Search your codebase for `STATIC_EXTENSION_REGEX` to ensure it is not used. If it is used, then migrate your patch to use the new `Rack::Zippy.config` method for configuring `static_extensions`: https://github.com/eliotsykes/rack-zippy#static_extensions
6
10
  - Make static extensions list configurable ([#45](https://github.com/eliotsykes/rack-zippy/pull/45)) Anton Petrunich
7
11
 
8
12
  ## 2.0.2 / 2014-12-15
data/Gemfile CHANGED
@@ -2,9 +2,3 @@ source 'https://rubygems.org'
2
2
 
3
3
  # Specify your gem's dependencies in rack-zippy.gemspec
4
4
  gemspec
5
-
6
- group :development do
7
- gem 'guard-test'
8
- gem 'rack-test'
9
- gem 'rake'
10
- end
data/README.md CHANGED
@@ -1,45 +1,21 @@
1
- # rack-zippy
1
+ # Hey fellow Rails developers, please read!
2
+
3
+ **Want to use rack-zippy with a Rails v4.2 or greater app?**
4
+ Its recommended you don't! Rails 4.2+ now supports serving gzipped files directly so there's no need for rack-zippy in Rails 4.2+ apps.
2
5
 
3
- rack-zippy is a Rack middleware for serving static gzipped assets precompiled by the Rails asset pipeline into the public/assets directory. Use it
4
- on Heroku if you want to serve the precompiled gzipped assets to gzip-capable clients with sensible caching headers.
6
+ **Want to use rack-zippy with a Rails v4.1 or less app?**
7
+ You'll need to use v3.0 of rack-zippy, see the README here: https://github.com/eliotsykes/rack-zippy/tree/v3.0.1
5
8
 
6
- By default, Rails + Heroku will not serve *.gz assets even though they are generated at deploy time.
9
+ # rack-zippy
7
10
 
8
- rack-zippy replaces the `ActionDispatch::Static` middleware used by Rails, which is not capable of serving the gzipped assets created by
9
- the `rake assets:precompile` task. rack-zippy will serve non-gzipped assets where they are not available or not supported by the
10
- requesting client.
11
+ rack-zippy v4+ is a Rack middleware for serving .gz files in Rack apps that are **not** Rails 4.2+ apps. (If you need to use rack-zippy in a Rails <= 4.1 app, then use v3.0 of rack-zippy, see README here: https://github.com/eliotsykes/rack-zippy/tree/v3.0.1)
11
12
 
12
- rack-zippy (since 2.0.0) has the same **convenient directory request handling** provided by `ActionDispatch::Static`, which means you can take advantage of this in any rack app:
13
+ rack-zippy has convenient directory request handling:
13
14
 
14
15
  - Requests for `/` and `/index` respond with `public/index.html` if present
15
16
  - Requests for `/foo/` and `/foo` respond with first file present out of `public/foo.html`, `public/foo/index.html` (Same behaviour for subdirectories)
16
17
 
17
- Watch the [Web Dev Break podcast on rack-zippy](http://www.webdevbreak.com/specials/rack-zippy "Faster, friendlier assets with rack-zippy") to see how you can check if your app
18
- is currently serving uncompressed assets and how quick it is to setup rack-zippy:
19
-
20
- [ ![Faster, friendlier assets with rack-zippy](/video-player.png "Faster, friendlier assets with rack-zippy") ](http://www.webdevbreak.com/specials/rack-zippy "Faster, friendlier assets with rack-zippy")
21
-
22
- ## Installation in Rails app
23
-
24
- Add this line to your application's Gemfile:
25
-
26
- gem 'rack-zippy'
27
-
28
- And then execute:
29
-
30
- $ bundle
31
-
32
- In `config/environments/production.rb`, set `config.serve_static_assets` to `true`:
33
-
34
- # Puts ActionDispatch::Static in middleware stack which we are going to replace with
35
- # Rack::Zippy::AssetServer
36
- config.serve_static_assets = true
37
-
38
- Create the file `config/initializers/rack_zippy.rb` and put this line in it:
39
-
40
- Rails.application.config.middleware.swap(ActionDispatch::Static, Rack::Zippy::AssetServer)
41
-
42
- Now run `rake middleware` at the command line and make sure that `Rack::Zippy::AssetServer` is near the top of the outputted list. ActionDispatch::Static should not be in the list. Nicely done, rack-zippy is now installed in your app.
18
+ rack-zippy decorates actionpack's `ActionDispatch::Static` middleware for non-Rails Rack apps to provide rack-zippy's own choice of caching headers and whitelisting of permitted static file extensions. (As an alternative to rack-zippy, you can use actionpack's `ActionDispatch::Static` directly without rack-zippy.)
43
19
 
44
20
  ## Installation in Rack app (that isn’t a Rails app)
45
21
 
@@ -72,24 +48,24 @@ application's public/ directory and will respond with sensible caching headers.
72
48
 
73
49
  `max_age_fallback`, is an integer value in seconds that should be used as the max_age fallback for files served by rack-zippy that live **outside** the `/assets` subdirectory *and* aren't `/favicon.ico`.
74
50
 
75
- A typical use for `max_age_fallback` is to define how long the cache lifetime for static HTML files served by rack-zippy should be. For one of my sites I have this set to 10 minutes:
51
+ A typical use for `max_age_fallback` is to define how long the cache lifetime for static HTML files served by rack-zippy should be. For one of my sites I have this set to 15 minutes:
76
52
 
77
53
  ```ruby
78
- max_age_in_secs = 10*60 # 10 mins = 600 secs
54
+ max_age_in_secs = 15*60 # 15 mins = 900 secs
79
55
  use Rack::Zippy::AssetServer, asset_root, max_age_fallback: max_age_in_secs
80
56
  ```
81
57
 
82
58
  Any files given the `max_age_fallback` would have the following `Cache-Control` header:
83
59
 
84
60
  ```
85
- Cache-Control: public, max-age=600
61
+ Cache-Control: public, max-age=900
86
62
  ```
87
63
 
88
64
  ### Configuration
89
65
 
90
66
  #### Supported Extensions Whitelist
91
67
 
92
- rack-zippy handles only files with whitelisted extensions. Default extensions are stored in the `static_extensions` array with an entry for each of these:
68
+ rack-zippy handles only files with whitelisted extensions. Default extensions are stored in the `static_extensions` array with an entry for each of these:
93
69
  `css js html htm txt ico png jpg jpeg gif pdf svg zip gz eps psd ai woff woff2 ttf eot otf swf`
94
70
 
95
71
  You can modify this list to support other extensions by appending the lowercased file extension to the `static_extensions` array:
@@ -97,23 +73,26 @@ You can modify this list to support other extensions by appending the lowercased
97
73
  ```ruby
98
74
  Rack::Zippy.configure do |config|
99
75
  # Add support for the given extensions:
100
- config.static_extensions.push('csv', 'xls', 'rtf', ...EXTENSIONS TO ADD...)
76
+ config.static_extensions.push('map', 'csv', 'xls', 'rtf', ...EXTENSIONS TO ADD...)
101
77
  end
102
78
  ```
103
79
 
104
- ## Troubleshooting
80
+ It is not recommended, however if you use rack-zippy 4.0+ with a Rails 4.2+ app, you can skip the rack-zippy rails version check and log output. Put the following in an initializer:
105
81
 
106
- ##### 'assert_index': No such middleware to insert before: ActionDispatch::Static (RuntimeError)
82
+ ```ruby
83
+ # config/initializers/zippy.rb
84
+ Rack::Zippy::Railtie.skip_version_check = true
85
+ ```
107
86
 
108
- Check your environment (in config/environments/) does not have `serve_static_assets` set to false:
109
87
 
110
- config.serve_static_assets = false # Oops! Should be set to true for rack-zippy
88
+ ## Troubleshooting
111
89
 
112
90
  ##### NameError: uninitialized constant Rack::Zippy
113
91
 
114
92
  - Check `Gemfile` doesn't limit rack-zippy to a subset of environment groups
115
93
  - Run `bundle install`
116
94
  - Check `Gemfile.lock` contains an entry for rack-zippy
95
+ - Ensure `require 'rack-zippy'` is present near the top of `config.ru`
117
96
 
118
97
 
119
98
  ## Contributing
@@ -148,7 +127,18 @@ Cleanup time! When you’re finished testing, delete the local override and set
148
127
  # In your-app/Gemfile change rack-zippy dependency to this (or similar):
149
128
  gem 'rack-zippy', '~> 9.8.7' # Replace 9.8.7 with the rack-zippy release version you want to use.
150
129
 
130
+ #### How to Run a Single Test
131
+
132
+ ```bash
133
+ # Single test file
134
+ ruby -Ilib:test test/assert_server_test.rb
151
135
 
136
+ # Single test method
137
+ ruby -Ilib:test test/assert_server_test.rb --name test_serves_static_file_as_directory
138
+
139
+ # Test methods matching a regex
140
+ ruby -Ilib:test test/assert_server_test.rb --name /serves_static/
141
+ ```
152
142
 
153
143
  ## Contributors
154
144
 
@@ -157,6 +147,7 @@ Cleanup time! When you’re finished testing, delete the local override and set
157
147
  - Luke Wendling https://github.com/lukewendling
158
148
  - Anton Petrunich https://github.com/solenko
159
149
  - ssemakov https://github.com/ssemakov
150
+ - Kai Schlichting https://github.com/lacco
160
151
 
161
152
  ## Releasing a new gem
162
153
 
@@ -169,4 +160,3 @@ Cleanup time! When you’re finished testing, delete the local override and set
169
160
  6. Update version to the next pre-release version in `lib/rack-zippy/version.rb`, e.g. `1.0.1` becomes `1.0.2.pre`.
170
161
  7. Add new heading to `CHANGELOG` for the next pre-release
171
162
  8. Commit and push the updated `lib/rack-zippy/version.rb` and `CHANGELOG` files.
172
-
@@ -1,7 +1,7 @@
1
1
  require 'rack-zippy/version'
2
- require 'rack-zippy/asset_compiler'
3
- require 'rack-zippy/serveable_file'
4
2
  require 'rack-zippy/configuration'
3
+ require 'rack-zippy/railtie' if defined?(Rails)
4
+ require 'action_controller'
5
5
 
6
6
  module Rack
7
7
  module Zippy
@@ -9,77 +9,122 @@ module Rack
9
9
 
10
10
  define_setting :static_extensions, %w(css js html htm txt ico png jpg jpeg gif pdf svg zip gz eps psd ai woff woff2 ttf eot otf swf)
11
11
 
12
- PRECOMPILED_ASSETS_SUBDIR_REGEX = /\A\/assets(?:\/|\z)/
12
+ ASSETS_SUBDIR_REGEX = /\A\/assets(?:\/|\z)/
13
13
 
14
14
  class AssetServer
15
15
 
16
- HTTP_STATUS_CODE_OK = 200
16
+ attr_reader :static_middleware
17
17
 
18
- def initialize(app, asset_root=nil, options={})
19
- if asset_root.nil?
20
- if RailsAssetCompiler.rails_env?
21
- asset_root = ::Rails.public_path
22
- else
23
- raise ArgumentError.new 'Please specify asset_root when initializing Rack::Zippy::AssetServer ' +
24
- '(asset_root is the path to your public directory, often the one with favicon.ico in it)'
25
- end
26
- end
27
- @app = app
18
+ # @param app [#call(env)] the Rack app
19
+ # @param path [String] the path to the public directory, usually where favicon.ico lives
20
+ # @param max_age_fallback [Fixnum] time for Cache-Control header. Defaults to 1 day (in seconds).
21
+ def initialize(app, path, max_age_fallback: :day)
22
+ assert_path_valid path
28
23
 
29
- @options = {
30
- :asset_compiler => resolve_asset_compiler,
31
- :asset_root => asset_root
32
- }.merge(options)
24
+ cache_control = cache_control(max_age_fallback)
25
+
26
+ @app = app
27
+ blank_app = ->(env) { }
28
+ @static_middleware = ::ActionDispatch::Static.new(blank_app, path, cache_control)
33
29
  end
34
30
 
35
31
  def call(env)
36
- path_info = env['PATH_INFO']
32
+ path_info = env[PATH_INFO]
33
+ return not_found_response if illegal_path?(path_info)
34
+
35
+ if try_static?(path_info)
36
+ static_response = static_middleware.call(env)
37
+ end
38
+
39
+ if static_response
40
+ after_static_responds(env, static_response)
41
+ else
42
+ @app.call(env)
43
+ end
44
+ end
37
45
 
38
- return not_found_response if path_info =~ ILLEGAL_PATH_REGEX
46
+ private
39
47
 
40
- serveable_file_options = {
41
- :path_info => path_info,
42
- :asset_root => asset_root,
43
- :asset_compiler => asset_compiler,
44
- :include_gzipped => client_accepts_gzip?(env),
45
- :max_age_fallback => @options[:max_age_fallback]
46
- }
48
+ ILLEGAL_PATH_REGEX = /(\/\.\.?)/
47
49
 
48
- serveable_file = ServeableFile.find_first(serveable_file_options)
50
+ BLANK_PATH_MESSAGE = 'Please specify non-blank path when initializing rack-zippy middleware ' +
51
+ '(path leads to your public directory, often the one with favicon.ico in it)'
49
52
 
53
+ SECONDS_IN = {
54
+ day: 24*60*60,
55
+ month: 31*(24*60*60),
56
+ year: 365*(24*60*60)
57
+ }.freeze
50
58
 
51
- if serveable_file
52
- return [HTTP_STATUS_CODE_OK, serveable_file.headers, serveable_file.response_body]
53
- end
59
+ # Old last-modified headers encourage caching via browser heuristics. Use it for year-long cached assets.
60
+ CACHE_FRIENDLY_LAST_MODIFIED = 'Mon, 10 Jan 2005 10:00:00 GMT'.freeze
61
+
62
+ FAVICON_PATH = '/favicon.ico'.freeze
63
+ PATH_INFO = 'PATH_INFO'.freeze
64
+ CACHE_CONTROL = 'Cache-Control'.freeze
65
+ LAST_MODIFIED = 'Last-Modified'.freeze
54
66
 
55
- @app.call(env)
67
+ def assert_path_valid(path)
68
+ raise ArgumentError, BLANK_PATH_MESSAGE if path.blank?
56
69
  end
57
70
 
58
- def asset_root
59
- @options[:asset_root]
71
+ def cache_control(max_age_fallback)
72
+ max_age_fallback = calc_max_age_fallback(max_age_fallback)
73
+ "public, max-age=#{max_age_fallback}"
60
74
  end
61
75
 
62
- private
76
+ def calc_max_age_fallback(max_age_fallback)
77
+ max_age_fallback.is_a?(Symbol) ? SECONDS_IN.fetch(max_age_fallback) : max_age_fallback
78
+ end
63
79
 
64
- ACCEPTS_GZIP_REGEX = /\bgzip\b/
80
+ def illegal_path?(path)
81
+ path =~ ILLEGAL_PATH_REGEX
82
+ end
65
83
 
66
- ILLEGAL_PATH_REGEX = /(\/\.\.?)/
84
+ def not_found_response
85
+ [404, {}, ['Not Found']]
86
+ end
67
87
 
68
- def client_accepts_gzip?(rack_env)
69
- rack_env['HTTP_ACCEPT_ENCODING'] =~ ACCEPTS_GZIP_REGEX
88
+ def try_static?(path)
89
+ extension = extension(path)
90
+ try_default_extension = extension.nil?
91
+ try_default_extension || static_extension?(extension)
70
92
  end
71
93
 
72
- def resolve_asset_compiler
73
- asset_compiler_class = RailsAssetCompiler.rails_env? ? RailsAssetCompiler : NullAssetCompiler
74
- return asset_compiler_class.new
94
+ def extension(path)
95
+ ext = ::File.extname(path).slice(1..-1)
96
+ ext.downcase! if ext
97
+ ext
75
98
  end
76
99
 
77
- def asset_compiler
78
- @options[:asset_compiler]
100
+ def static_extension?(extension)
101
+ Rack::Zippy.static_extensions.include? extension
79
102
  end
80
103
 
81
- def not_found_response
82
- [404, {}, ['Not Found']]
104
+ def after_static_responds(env, static_response)
105
+ path = ::Rack::Utils.unescape(env[PATH_INFO])
106
+ headers = static_response[1]
107
+ modify_headers(path, headers)
108
+ static_response
109
+ end
110
+
111
+ def modify_headers(path, headers)
112
+ case path
113
+ when ASSETS_SUBDIR_REGEX
114
+ lifetime_in_secs = SECONDS_IN[:year]
115
+ last_modified = CACHE_FRIENDLY_LAST_MODIFIED
116
+ when FAVICON_PATH
117
+ lifetime_in_secs = SECONDS_IN[:month]
118
+ last_modified = CACHE_FRIENDLY_LAST_MODIFIED
119
+ end
120
+
121
+ headers[CACHE_CONTROL] = "public, max-age=#{lifetime_in_secs}" if lifetime_in_secs
122
+
123
+ if last_modified
124
+ headers[LAST_MODIFIED] = last_modified
125
+ else
126
+ headers.delete(LAST_MODIFIED)
127
+ end
83
128
  end
84
129
 
85
130
  end
@@ -0,0 +1,26 @@
1
+ module Rack
2
+ module Zippy
3
+ class Railtie < ::Rails::Railtie
4
+
5
+ cattr_accessor :skip_version_check
6
+
7
+ def self.version_check
8
+ return if Rack::Zippy::Railtie.skip_version_check
9
+ if ::Rails.version.to_f >= minimum_rails_version_with_gzip_serving
10
+ puts "[rack-zippy] rack-zippy is not supported for this version of Rails. Rails now supports serving gzipped files using its own ActionDispatch::Static middleware. It is strongly recommended you remove rack-zippy from your app and use ActionDispatch::Static in its place."
11
+ else
12
+ puts "[rack-zippy] This version of rack-zippy does not support Rails. Your choices include: 1) [RECOMMENDED] Upgrade to Rails #{minimum_rails_version_with_gzip_serving} or above and use Rails' built-in ActionDispatch::Static middleware to serve gzipped files. or 2) Specify an earlier version of rack-zippy (~> '3.0.1') in your Gemfile that does support Rails"
13
+ end
14
+ end
15
+
16
+ def self.minimum_rails_version_with_gzip_serving
17
+ 4.2
18
+ end
19
+
20
+ config.after_initialize do
21
+ Rack::Zippy::Railtie.version_check
22
+ end
23
+
24
+ end
25
+ end
26
+ end
@@ -1,5 +1,5 @@
1
1
  module Rack
2
2
  module Zippy
3
- VERSION = '3.0.1'
3
+ VERSION = '4.0.0'
4
4
  end
5
5
  end
@@ -14,7 +14,14 @@ Gem::Specification.new do |gem|
14
14
  gem.license = 'MIT'
15
15
 
16
16
  gem.files = `git ls-files`.split($/)
17
- gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
17
+ gem.executables = []
18
18
  gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
19
19
  gem.require_paths = ["lib"]
20
+
21
+ gem.add_dependency 'actionpack', '~> 4.2.4'
22
+
23
+ gem.add_development_dependency 'minitest', '~> 5.8.1'
24
+ gem.add_development_dependency 'guard-test', '~> 2.0.6'
25
+ gem.add_development_dependency 'rack-test', '~> 0.6.3'
26
+ gem.add_development_dependency 'rake'
20
27
  end
@@ -7,14 +7,23 @@ module Rack
7
7
 
8
8
  def setup
9
9
  ensure_correct_working_directory
10
- enter_rails_env
11
- ::Rails.public_path = Pathname.new(asset_root)
12
- ::Rails.configuration.assets.compile = false
10
+ @original_extensions = Rack::Zippy.static_extensions.dup
13
11
  end
14
12
 
15
13
  def teardown
16
14
  revert_to_original_working_directory
17
15
  @app = nil
16
+ Rack::Zippy.static_extensions = @original_extensions
17
+ end
18
+
19
+ BLANK_PATHS = [nil, '', ' ']
20
+
21
+ BLANK_PATHS.each do |blank_path|
22
+ test "initializer prevents blank path: #{blank_path.inspect}" do
23
+ assert_raises ArgumentError do
24
+ AssetServer.new(create_rack_app, blank_path)
25
+ end
26
+ end
18
27
  end
19
28
 
20
29
  def test_serves_static_file_as_directory
@@ -39,15 +48,6 @@ module Rack
39
48
  assert_responds_with_html_file '', 'public/index.html'
40
49
  end
41
50
 
42
- def test_rails_asset_compiler_set_when_rails_environment_detected
43
- assert_equal RailsAssetCompiler, app.send(:asset_compiler).class
44
- end
45
-
46
- def test_null_asset_compiler_set_when_no_rails_environment_detected
47
- exit_rails_env
48
- assert_equal NullAssetCompiler, app.send(:asset_compiler).class
49
- end
50
-
51
51
  def test_request_for_non_asset_path_beginning_with_assets_dir_name_bypasses_middleware
52
52
  get '/assets-are-great-but-im-not-one'
53
53
  assert_underlying_app_responded
@@ -90,12 +90,6 @@ module Rack
90
90
  assert_cache_friendly_last_modified
91
91
  end
92
92
 
93
- def test_does_not_serve_assets_subdir_request_when_assets_compile_enabled
94
- ::Rails.configuration.assets.compile = true
95
- get '/assets/application.css'
96
- assert_underlying_app_responded
97
- end
98
-
99
93
  def test_responds_with_gzipped_css_to_gzip_capable_clients
100
94
  params = {}
101
95
  get '/assets/application.css', params, env_for_gzip_capable_client
@@ -173,6 +167,7 @@ module Rack
173
167
  get '/assets/rails.png'
174
168
  assert_response_ok
175
169
  assert_nil last_response.headers['vary']
170
+ assert_nil last_response.headers['content-encoding']
176
171
  end
177
172
 
178
173
  def test_responds_not_found_if_path_contains_hidden_dir
@@ -255,38 +250,53 @@ module Rack
255
250
  assert_underlying_app_responded
256
251
  end
257
252
 
258
- def test_asset_root_constructor_arg_accepts_string
259
- asset_server = AssetServer.new(create_rack_app, '/custom/asset/root')
260
- assert_equal '/custom/asset/root', asset_server.asset_root
261
- end
262
-
263
- def test_default_asset_root_is_rails_public_path
264
- Rails.public_path = '/unexpected/absolute/path/to/public'
265
- asset_server = AssetServer.new(create_rack_app)
266
- assert_equal '/unexpected/absolute/path/to/public', asset_server.asset_root
267
- end
268
-
269
- def test_asset_server_accepts_max_age_fallback_option
253
+ def test_uses_max_age_fallback_in_cache_control
270
254
  fallback_in_secs = 1234
271
255
  @app = AssetServer.new(
272
256
  create_rack_app, asset_root, max_age_fallback: fallback_in_secs
273
257
  )
274
-
258
+
275
259
  get '/thanks.html'
276
260
  assert_equal "public, max-age=1234", last_response.headers['cache-control']
261
+ assert_last_modified nil
262
+ end
263
+
264
+ def test_request_for_existing_file_with_unknown_extension_is_passed_onto_underlying_app
265
+ assert Rack::Zippy.static_extensions.delete("txt")
266
+ get '/robots.txt'
267
+ assert_underlying_app_responded
268
+ end
269
+
270
+ def test_request_for_file_with_configured_extension_successful
271
+ Rack::Zippy.static_extensions << 'csv'
272
+ get '/report.csv'
273
+ assert_response_ok
274
+ assert_content_type 'text/csv'
275
+ assert_content_length 'public/report.csv'
276
+ end
277
+
278
+ def test_default_extensions_includes_fonts
279
+ font_extensions = ['woff', 'woff2', 'ttf', 'eot', 'otf']
280
+ font_extensions.each do |ext|
281
+ assert_includes(Rack::Zippy.static_extensions, ext)
282
+ end
283
+ end
284
+
285
+ def test_default_extensions_includes_flash
286
+ assert_includes(Rack::Zippy.static_extensions, 'swf')
287
+ end
288
+
289
+ def test_responds_with_file_with_uppercase_chars_in_extension
290
+ get '/assets/loading.GiF'
291
+ assert_response_ok
292
+ assert_content_type 'image/gif'
293
+ assert_content_length 'public/assets/loading.GiF'
277
294
  end
278
295
 
279
296
  private
280
297
 
281
298
  def app
282
- return @app if @app
283
- if in_rails_env?
284
- @app = AssetServer.new(create_rack_app)
285
- else
286
- # In a pure rack app, non-Rails env
287
- @app = AssetServer.new(create_rack_app, asset_root)
288
- end
289
- return @app
299
+ @app ||= AssetServer.new(create_rack_app, asset_root)
290
300
  end
291
301
 
292
302
  def create_rack_app