Class | Mongrel::Rails::RailsHandler |
In: |
lib/mongrel/rails.rb
lib/mongrel/rails.rb |
Parent: | Mongrel::HttpHandler |
Implements a handler that can run Rails and serve files out of the Rails application‘s public directory. This lets you run your Rails application with Mongrel during development and testing, then use it also in production behind a server that‘s better at serving the static files.
The RailsHandler takes a mime_map parameter which is a simple suffix=mimetype mapping that it should add to the list of valid mime types.
It also supports page caching directly and will try to resolve a request in the following order:
This means that if you are using page caching it will actually work with Mongrel and you should see a decent speed boost (but not as fast as if you use a static server like Apache or Litespeed).
files | [R] | |
files | [R] | |
guard | [R] | |
guard | [R] |
# File lib/mongrel/rails.rb, line 37 37: def initialize(dir, mime_map = {}) 38: @files = Mongrel::DirHandler.new(dir,false) 39: @guard = Mutex.new 40: 41: # Register the requested MIME types 42: mime_map.each {|k,v| Mongrel::DirHandler::add_mime_type(k,v) } 43: end
# File lib/mongrel/rails.rb, line 37 37: def initialize(dir, mime_map = {}) 38: @files = Mongrel::DirHandler.new(dir,false) 39: @guard = Mutex.new 40: 41: # Register the requested MIME types 42: mime_map.each {|k,v| Mongrel::DirHandler::add_mime_type(k,v) } 43: end
Attempts to resolve the request as follows:
# File lib/mongrel/rails.rb, line 50 50: def process(request, response) 51: return if response.socket.closed? 52: 53: path_info = request.params[Mongrel::Const::PATH_INFO] 54: rest_operator = request.params[Mongrel::Const::REQUEST_URI][/^#{Regexp.escape path_info}(;[^\?]+)/, 1].to_s 55: path_info.chomp!("/") 56: 57: page_cached = path_info + rest_operator + ActionController::Base.page_cache_extension 58: get_or_head = @@file_only_methods.include? request.params[Mongrel::Const::REQUEST_METHOD] 59: 60: if get_or_head and @files.can_serve(path_info) 61: # File exists as-is so serve it up 62: @files.process(request,response) 63: elsif get_or_head and @files.can_serve(page_cached) 64: # Possible cached page, serve it up 65: request.params[Mongrel::Const::PATH_INFO] = page_cached 66: @files.process(request,response) 67: else 68: begin 69: cgi = Mongrel::CGIWrapper.new(request, response) 70: cgi.handler = self 71: # We don't want the output to be really final until we're out of the lock 72: cgi.default_really_final = false 73: 74: @guard.synchronize { 75: @active_request_path = request.params[Mongrel::Const::PATH_INFO] 76: Dispatcher.dispatch(cgi, ActionController::CgiRequest::DEFAULT_SESSION_OPTIONS, response.body) 77: @active_request_path = nil 78: } 79: 80: # This finalizes the output using the proper HttpResponse way 81: cgi.out("text/html",true) {""} 82: rescue Errno::EPIPE 83: response.socket.close 84: rescue Object => rails_error 85: STDERR.puts "#{Time.now}: Error calling Dispatcher.dispatch #{rails_error.inspect}" 86: STDERR.puts rails_error.backtrace.join("\n") 87: end 88: end 89: end
Attempts to resolve the request as follows:
# File lib/mongrel/rails.rb, line 50 50: def process(request, response) 51: return if response.socket.closed? 52: 53: path_info = request.params[Mongrel::Const::PATH_INFO] 54: rest_operator = request.params[Mongrel::Const::REQUEST_URI][/^#{Regexp.escape path_info}(;[^\?]+)/, 1].to_s 55: path_info.chomp!("/") 56: 57: page_cached = path_info + rest_operator + ActionController::Base.page_cache_extension 58: get_or_head = @@file_only_methods.include? request.params[Mongrel::Const::REQUEST_METHOD] 59: 60: if get_or_head and @files.can_serve(path_info) 61: # File exists as-is so serve it up 62: @files.process(request,response) 63: elsif get_or_head and @files.can_serve(page_cached) 64: # Possible cached page, serve it up 65: request.params[Mongrel::Const::PATH_INFO] = page_cached 66: @files.process(request,response) 67: else 68: begin 69: cgi = Mongrel::CGIWrapper.new(request, response) 70: cgi.handler = self 71: # We don't want the output to be really final until we're out of the lock 72: cgi.default_really_final = false 73: 74: @guard.synchronize { 75: @active_request_path = request.params[Mongrel::Const::PATH_INFO] 76: Dispatcher.dispatch(cgi, ActionController::CgiRequest::DEFAULT_SESSION_OPTIONS, response.body) 77: @active_request_path = nil 78: } 79: 80: # This finalizes the output using the proper HttpResponse way 81: cgi.out("text/html",true) {""} 82: rescue Errno::EPIPE 83: response.socket.close 84: rescue Object => rails_error 85: STDERR.puts "#{Time.now}: Error calling Dispatcher.dispatch #{rails_error.inspect}" 86: STDERR.puts rails_error.backtrace.join("\n") 87: end 88: end 89: end
Does the internal reload for Rails. It might work for most cases, but sometimes you get exceptions. In that case just do a real restart.
# File lib/mongrel/rails.rb, line 93 93: def reload! 94: begin 95: @guard.synchronize { 96: $".replace $orig_dollar_quote 97: GC.start 98: Dispatcher.reset_application! 99: ActionController::Routing::Routes.reload 100: } 101: end 102: end
Does the internal reload for Rails. It might work for most cases, but sometimes you get exceptions. In that case just do a real restart.
# File lib/mongrel/rails.rb, line 93 93: def reload! 94: begin 95: @guard.synchronize { 96: $".replace $orig_dollar_quote 97: GC.start 98: Dispatcher.reset_application! 99: ActionController::Routing::Routes.reload 100: } 101: end 102: end