Skip to content

Instantly share code, notes, and snippets.

@guyboltonking
Created March 21, 2012 20:37
Show Gist options
  • Star 43 You must be signed in to star a gist
  • Fork 4 You must be signed in to fork a gist
  • Save guyboltonking/2152663 to your computer and use it in GitHub Desktop.
Save guyboltonking/2152663 to your computer and use it in GitHub Desktop.
Slightly hacky rails middleware for serving up precompiled gzipped assets
require 'action_dispatch/middleware/static'
module Middleware
class FileHandler < ActionDispatch::FileHandler
def initialize(root, assets_path, cache_control)
@assets_path = assets_path.chomp('/') + '/'
super(root, cache_control)
end
def match?(path)
path.start_with?(@assets_path) && super(path)
end
end
class CompressedStaticAssets
def initialize(app, path, assets_path, cache_control=nil)
@app = app
@file_handler = FileHandler.new(path, assets_path, cache_control)
end
def call(env)
if env['REQUEST_METHOD'] == 'GET'
request = Rack::Request.new(env)
encoding = Rack::Utils.select_best_encoding(
%w(gzip identity), request.accept_encoding)
if encoding == 'gzip'
pathgz = env['PATH_INFO'] + '.gz'
if match = @file_handler.match?(pathgz)
# Get the filehandler to serve up the gzipped file,
# then strip the .gz suffix
env["PATH_INFO"] = match
status, headers, body = @file_handler.call(env)
path = env["PATH_INFO"] = env["PATH_INFO"].chomp('.gz')
# Set the Vary HTTP header.
vary = headers["Vary"].to_s.split(",").map { |v| v.strip }
unless vary.include?("*") || vary.include?("Accept-Encoding")
headers["Vary"] = vary.push("Accept-Encoding").join(",")
end
headers['Content-Encoding'] = 'gzip'
headers['Content-Type'] =
Rack::Mime.mime_type(File.extname(path), 'text/plain')
headers.delete('Content-Length')
return [status, headers, body]
end
end
end
@app.call(env)
end
end
end
# Serve pre-gzipped static assets
middleware.insert_after(
'Rack::Cache', Middleware::CompressedStaticAssets,
paths["public"].first, config.assets.prefix, config.static_cache_control)
@mattolson
Copy link

@guyboltonking @neersighted @bensheldon @marcgg @runeroniek I have taken the liberty of gemifying this code (with changes to make it play nice with Rack::Deflate). It is available here. It's been working well for me. Let me know if you have any questions.

@eliotsykes
Copy link

Another option for serving gzipped assets using Rack::Rewrite https://gist.github.com/eliotsykes/6049536

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