Class: Mongrel::Rails::RailsHandler

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:

- If the requested exact PATH_INFO exists as a file then serve it.
- If it exists at PATH_INFO+".html" exists then serve that.
- Finally, construct a Mongrel::CGIWrapper and run Dispatcher.dispatch to have Rails go.

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).

### Methods

new new process process reload! reload!

### Attributes

files | [R] |
files | [R] |
guard | [R] |
guard | [R] |

### Public Class methods

new(dir, mime_map = {})

[Source]

        # 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

new(dir, mime_map = {})

[Source]

        # 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

### Public Instance methods

process(request, response)

Attempts to resolve the request as follows:

- If the requested exact PATH_INFO exists as a file then serve it.
- If it exists at PATH_INFO+".html" exists then serve that.
- Finally, construct a Mongrel::CGIWrapper and run Dispatcher.dispatch to have Rails go.

[Source]

        # 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

process(request, response)

Attempts to resolve the request as follows:

- If the requested exact PATH_INFO exists as a file then serve it.
- If it exists at PATH_INFO+".html" exists then serve that.
- Finally, construct a Mongrel::CGIWrapper and run Dispatcher.dispatch to have Rails go.

[Source]

        # 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

reload!()

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.

[Source]

         # 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

reload!()

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.

[Source]

         # 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

[Validate]