lib/rack/static.rb in rack-1.6.13 vs lib/rack/static.rb in rack-2.0.0.alpha
- old
+ new
@@ -1,5 +1,8 @@
+require "rack/file"
+require "rack/utils"
+
module Rack
# The Rack::Static middleware intercepts requests for static files
# (javascript files, images, stylesheets, etc) based on the url prefixes or
# route mappings passed in the options, and serves them using a Rack::File
@@ -82,22 +85,27 @@
def initialize(app, options={})
@app = app
@urls = options[:urls] || ["/favicon.ico"]
@index = options[:index]
+ @gzip = options[:gzip]
root = options[:root] || Dir.pwd
# HTTP Headers
@header_rules = options[:header_rules] || []
# Allow for legacy :cache_control option while prioritizing global header_rules setting
- @header_rules.insert(0, [:all, {'Cache-Control' => options[:cache_control]}]) if options[:cache_control]
+ @header_rules.insert(0, [:all, {CACHE_CONTROL => options[:cache_control]}]) if options[:cache_control]
@file_server = Rack::File.new(root)
end
+ def add_index_root?(path)
+ @index && path =~ /\/$/
+ end
+
def overwrite_file_path(path)
- @urls.kind_of?(Hash) && @urls.key?(path) || @index && path =~ /\/$/
+ @urls.kind_of?(Hash) && @urls.key?(path) || add_index_root?(path)
end
def route_file(path)
@urls.kind_of?(Array) && @urls.any? { |url| path.index(url) == 0 }
end
@@ -108,12 +116,29 @@
def call(env)
path = env[PATH_INFO]
if can_serve(path)
- env["PATH_INFO"] = (path =~ /\/$/ ? path + @index : @urls[path]) if overwrite_file_path(path)
- path = env["PATH_INFO"]
- response = @file_server.call(env)
+ if overwrite_file_path(path)
+ env[PATH_INFO] = (add_index_root?(path) ? path + @index : @urls[path])
+ elsif @gzip && env['HTTP_ACCEPT_ENCODING'] =~ /\bgzip\b/
+ path = env[PATH_INFO]
+ env[PATH_INFO] += '.gz'
+ response = @file_server.call(env)
+ env[PATH_INFO] = path
+
+ if response[0] == 404
+ response = nil
+ else
+ if mime_type = Mime.mime_type(::File.extname(path), 'text/plain')
+ response[1][CONTENT_TYPE] = mime_type
+ end
+ response[1]['Content-Encoding'] = 'gzip'
+ end
+ end
+
+ path = env[PATH_INFO]
+ response ||= @file_server.call(env)
headers = response[1]
applicable_rules(path).each do |rule, new_headers|
new_headers.each { |field, content| headers[field] = content }
end