Skip to content

Instantly share code, notes, and snippets.

@eliotsykes
Last active December 20, 2015 01:29
Show Gist options
  • Star 8 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save eliotsykes/6049536 to your computer and use it in GitHub Desktop.
Save eliotsykes/6049536 to your computer and use it in GitHub Desktop.
***** Checkout the rack-zippy gem, I recommend it over this gist, find it at https://github.com/eliotsykes/rack-zippy ***** An asset server for Rails 3.2.x that serves asset pipeline precompiled assets to clients, including those elusive gzipped (.gz) assets. Sadly Rails' own ActionDispatch::Static middleware does not take care of serving gzippe…
# 1. Add rack-rewrite to your Gemfile and run 'bundle install':
# gem 'rack-rewrite'
#
# 2. Create a file with the contents below in config/initializers/asset_server_middleware.rb
#
# 3. Rename 'YourApp' below
#
# 4. In config/environments/production.rb and config/environments/test.rb, set:
# config.serve_static_assets = true
# config.assets.compile = false
# config.assets.digest = true
# config.assets.compress = true
#
# 5. Write some tests to be sure your assets are being served as expected. Your test will
# probably want to clean and precompile the assets for an accurate test, e.g.:
# system('bundle exec rake assets:clean assets:precompile')
#
# 6. config/application.rb can be altered so the assets bundler group is only used in development:
# Bundler.require(*Rails.groups(:assets => %w(development))) # test environment removed
#
# 7. .gitignore the public/assets directory:
# echo "public/assets" >> .gitignore
YourApp::Application.configure do
# You probably only want config.assets.compile = true in development,
# and set to false in test+production. When config.assets.compile is
# true the app uses Sprockets for asset serving at runtime instead
# of the send_file rules below. This is useful in development when
# assets can change often.
serve_precompiled_assets_only = !config.assets.compile
next unless serve_precompiled_assets_only
config.middleware.swap(ActionDispatch::Static, Rack::Rewrite) do
local_file_path = ->(match, rack_env) {
path = rack_env['PATH_INFO']
raise 'Illegal request' if path.include?('..')
"public#{path}"
}
local_gz_file_path = ->(match, rack_env) {
"#{local_file_path.call(nil, rack_env)}.gz"
}
is_gzippable_request = ->(rack_env) {
client_accepts_gzip = !!(rack_env['HTTP_ACCEPT_ENCODING'] =~ /\bgzip\b/)
return client_accepts_gzip && File.exists?(local_gz_file_path.call(nil, rack_env))
}
is_static_request = ->(rack_env) {
return File.exists?(local_file_path.call(nil, rack_env))
}
seconds_in_day = 24*60*60
seconds_in_month = 31*seconds_in_day
seconds_in_year = 365*seconds_in_day
send_file %r{\A\/favicon\.ico},
local_file_path,
:headers => {
'Cache-Control' => "public, max-age=#{seconds_in_month}",
'Last-Modified' => 'Mon, 10 Jan 2005 10:00:00 GMT'
},
:if => is_static_request
send_file %r{\A\/robots\.txt},
local_file_path,
:headers => {
'Cache-Control' => "public, max-age=#{seconds_in_day}"
},
:if => is_static_request
# Gzipped css
send_file %r{\A\/assets\/.+\.css},
local_gz_file_path,
:headers => {
'Vary' => 'Accept-Encoding',
'Content-Encoding' => 'gzip',
'Content-Type' => 'text/css',
'Cache-Control' => "public, max-age=#{seconds_in_year}",
'Last-Modified' => 'Mon, 10 Jan 2005 10:00:00 GMT'
},
:if => is_gzippable_request
# Gzipped js
send_file %r{\A\/assets\/.+\.js},
local_gz_file_path,
:headers => {
'Vary' => 'Accept-Encoding',
'Content-Encoding' => 'gzip',
'Content-Type' => 'application/javascript',
'Cache-Control' => "public, max-age=#{seconds_in_year}",
'Last-Modified' => 'Mon, 10 Jan 2005 10:00:00 GMT'
},
:if => is_gzippable_request
# js+css for gzip-unsupported clients
send_file %r{\A\/assets\/.+\.(?:css|js)},
local_file_path,
:headers => {
'Vary' => 'Accept-Encoding',
'Cache-Control' => "public, max-age=#{seconds_in_year}",
'Last-Modified' => 'Mon, 10 Jan 2005 10:00:00 GMT'
},
:if => is_static_request
# Non-css, non-js assets
send_file %r{\A\/assets\/.+},
local_file_path,
:headers => {
'Cache-Control' => "public, max-age=#{seconds_in_year}",
'Last-Modified' => 'Mon, 10 Jan 2005 10:00:00 GMT'
},
:if => is_static_request
end
end
@michrome
Copy link

Looks good! WIll give it a whirl soon.

@eliotsykes
Copy link
Author

Thanks, would love to hear how it goes for you

@eliotsykes
Copy link
Author

I've written the rack-zippy gem to supersede this gist: https://github.com/eliotsykes/rack-zippy

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment