rack-zippy 3.0.1 → 4.0.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.
@@ -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