1 # This code is based on the original Rails handler in Mongrel
2 # Copyright (c) 2005 Zed A. Shaw
3 # Copyright (c) 2009 Eric Wong
4 # You can redistribute it and/or modify it under the same terms as Ruby.
8 # Static file handler for Rails < 2.3. This handler is only provided
9 # as a convenience for developers. Performance-minded deployments should
10 # use nginx (or similar) for serving static files.
12 # This supports page caching directly and will try to resolve a
13 # request in the following order:
15 # * If the requested exact PATH_INFO exists as a file then serve it.
16 # * If it exists at PATH_INFO+rest_operator+".html" exists
19 # This means that if you are using page caching it will actually work
20 # with Unicorn and you should see a decent speed boost (but not as
21 # fast as if you use a static server like nginx).
22 class Unicorn::App::OldRails::Static
23 FILE_METHODS = { 'GET' => true, 'HEAD' => true }.freeze
24 REQUEST_METHOD = 'REQUEST_METHOD'.freeze
25 REQUEST_URI = 'REQUEST_URI'.freeze
26 PATH_INFO = 'PATH_INFO'.freeze
30 @root = "#{::RAILS_ROOT}/public"
31 @file_server = ::Rack::File.new(@root)
35 # short circuit this ASAP if serving non-file methods
36 FILE_METHODS.include?(env[REQUEST_METHOD]) or return @app.call(env)
38 # first try the path as-is
39 path_info = env[PATH_INFO].chomp("/")
40 if File.file?("#@root/#{::Rack::Utils.unescape(path_info)}")
41 # File exists as-is so serve it up
42 env[PATH_INFO] = path_info
43 return @file_server.call(env)
46 # then try the cached version:
48 # grab the semi-colon REST operator used by old versions of Rails
49 # this is the reason we didn't just copy the new Rails::Rack::Static
50 env[REQUEST_URI] =~ /^#{Regexp.escape(path_info)}(;[^\?]+)/
51 path_info << "#$1#{ActionController::Base.page_cache_extension}"
53 if File.file?("#@root/#{::Rack::Utils.unescape(path_info)}")
54 env[PATH_INFO] = path_info
55 return @file_server.call(env)
58 @app.call(env) # call OldRails
60 end if defined?(Unicorn::App::OldRails)