Class: Mongrel::Rails::RailsHandler
- Inherits:
-
HttpHandler
- Object
- HttpHandler
- Mongrel::Rails::RailsHandler
- Defined in:
- lib/mongrel/rails.rb
Overview
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).
Constant Summary collapse
- @@file_only_methods =
["GET","HEAD"]
Instance Attribute Summary collapse
-
#files ⇒ Object
readonly
Returns the value of attribute files.
-
#guard ⇒ Object
readonly
Returns the value of attribute guard.
Attributes inherited from HttpHandler
Instance Method Summary collapse
-
#initialize(dir, mime_map = {}) ⇒ RailsHandler
constructor
A new instance of RailsHandler.
-
#process(request, response) ⇒ Object
Attempts to resolve the request as follows:.
-
#reload! ⇒ Object
Does the internal reload for Rails.
Methods inherited from HttpHandler
#request_begins, #request_progress
Constructor Details
#initialize(dir, mime_map = {}) ⇒ RailsHandler
Returns a new instance of RailsHandler.
37 38 39 40 41 42 43 |
# File 'lib/mongrel/rails.rb', line 37 def initialize(dir, mime_map = {}) @files = Mongrel::DirHandler.new(dir,false) @guard = Mutex.new # Register the requested MIME types mime_map.each {|k,v| Mongrel::DirHandler::add_mime_type(k,v) } end |
Instance Attribute Details
#files ⇒ Object (readonly)
Returns the value of attribute files.
33 34 35 |
# File 'lib/mongrel/rails.rb', line 33 def files @files end |
#guard ⇒ Object (readonly)
Returns the value of attribute guard.
34 35 36 |
# File 'lib/mongrel/rails.rb', line 34 def guard @guard end |
Instance Method Details
#process(request, response) ⇒ Object
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.
50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 |
# File 'lib/mongrel/rails.rb', line 50 def process(request, response) return if response.socket.closed? path_info = request.params[Mongrel::Const::PATH_INFO] rest_operator = request.params[Mongrel::Const::REQUEST_URI][/^#{Regexp.escape path_info}(;[^\?]+)/, 1].to_s path_info.chomp!("/") path_info = "/index" if path_info.empty? do_caching = ActionController::Base.perform_caching cache_dir = ActionController::Base.page_cache_directory cache_dir.chomp!("/") html_page_cached = cache_dir + path_info + rest_operator + ActionController::Base.page_cache_extension file_cached = cache_dir + path_info get_or_head = @@file_only_methods.include? request.params[Mongrel::Const::REQUEST_METHOD] STDERR.puts "file_cached = #{file_cached}" if get_or_head and @files.can_serve(path_info) # File exists as-is so serve it up @files.process(request,response) elsif do_caching and get_or_head and @files.can_serve(file_cached); # Possible cached page, serve it up request.params[Mongrel::Const::PATH_INFO] = file_cached @files.process(request,response) elsif do_caching and get_or_head and @files.can_serve(html_page_cached); # Possible cached page, serve it up request.params[Mongrel::Const::PATH_INFO] = html_page_cached @files.process(request,response) else begin cgi = Mongrel::CGIWrapper.new(request, response) cgi.handler = self # We don't want the output to be really final until we're out of the lock cgi.default_really_final = false @guard.synchronize { @active_request_path = request.params[Mongrel::Const::PATH_INFO] Dispatcher.dispatch(cgi, ActionController::CgiRequest::DEFAULT_SESSION_OPTIONS, response.body) @active_request_path = nil } # This finalizes the output using the proper HttpResponse way cgi.out("text/html",true) {""} rescue Errno::EPIPE response.socket.close rescue Object => rails_error STDERR.puts "#{Time.now}: Error calling Dispatcher.dispatch #{rails_error.inspect}" STDERR.puts rails_error.backtrace.join("\n") end end end |
#reload! ⇒ Object
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.
103 104 105 106 107 108 109 110 111 112 |
# File 'lib/mongrel/rails.rb', line 103 def reload! begin @guard.synchronize { $".replace $orig_dollar_quote GC.start Dispatcher.reset_application! ActionController::Routing::Routes.reload } end end |