From 0b095ea72fb849682a1185a626eef247b5afc1cd Mon Sep 17 00:00:00 2001 From: Eric Wong Date: Mon, 23 Mar 2009 02:03:31 -0700 Subject: unicorn_rails: support non-Rack versions of Rails This resurrects old code from Mongrel to wrap the Rails Dispatcher for older versions of Rails. It seems that Rails >= 2.2.0 support Rack, but only >=2.3 requires it. I'd like to support Rails 1.2.x for a while, too. --- lib/unicorn/app/old_rails/static.rb | 58 +++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 lib/unicorn/app/old_rails/static.rb (limited to 'lib/unicorn/app/old_rails/static.rb') diff --git a/lib/unicorn/app/old_rails/static.rb b/lib/unicorn/app/old_rails/static.rb new file mode 100644 index 0000000..c9366d2 --- /dev/null +++ b/lib/unicorn/app/old_rails/static.rb @@ -0,0 +1,58 @@ +# This code is based on the original Rails handler in Mongrel +# Copyright (c) 2005 Zed A. Shaw +# Copyright (c) 2009 Eric Wong +# You can redistribute it and/or modify it under the same terms as Ruby. + +require 'rack/file' + +# Static file handler for Rails < 2.3. This handler is only provided +# as a convenience for developers. Performance-minded deployments should +# use nginx (or similar) for serving static files. +# +# This supports page caching directly and will try to resolve a +# request in the following order: +# +# * If the requested exact PATH_INFO exists as a file then serve it. +# * If it exists at PATH_INFO+rest_operator+".html" exists +# then serve that. +# +# This means that if you are using page caching it will actually work +# with Unicorn and you should see a decent speed boost (but not as +# fast as if you use a static server like nginx). +class Unicorn::App::OldRails::Static + FILE_METHODS = { 'GET' => true, 'HEAD' => true }.freeze + + def initialize(app) + @app = app + @root = "#{::RAILS_ROOT}/public" + @file_server = ::Rack::File.new(@root) + end + + def call(env) + # short circuit this ASAP if serving non-file methods + FILE_METHODS.include?(env[Unicorn::Const::REQUEST_METHOD]) or + return @app.call(env) + + # first try the path as-is + path_info = env[Unicorn::Const::PATH_INFO].chomp("/") + if File.file?("#@root/#{::Rack::Utils.unescape(path_info)}") + # File exists as-is so serve it up + env[Unicorn::Const::PATH_INFO] = path_info + return @file_server.call(env) + end + + # then try the cached version: + + # grab the semi-colon REST operator used by old versions of Rails + # this is the reason we didn't just copy the new Rails::Rack::Static + env[Unicorn::Const::REQUEST_URI] =~ /^#{Regexp.escape(path_info)}(;[^\?]+)/ + path_info << "#$1#{ActionController::Base.page_cache_extension}" + + if File.file?("#@root/#{::Rack::Utils.unescape(path_info)}") + env[Unicorn::Const::PATH_INFO] = path_info + return @file_server.call(env) + end + + @app.call(env) # call OldRails + end +end if defined?(Unicorn::App::OldRails) -- cgit v1.2.3-24-ge0c7