| 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