| Class | ActionController::Dispatcher |
| In: |
actionpack/lib/action_controller/dispatcher.rb
|
| Parent: | Object |
Dispatches requests to the appropriate controller and takes care of reloading the app after each request when Dependencies.load? is true.
Declare a block to be called after each dispatch. Run in reverse of the order declared.
# File actionpack/lib/action_controller/dispatcher.rb, line 21 def after_dispatch(*method_names, &block) callbacks[:after].concat method_names callbacks[:after] << block if block_given? end
Declare a block to be called before each dispatch. Run in the order declared.
# File actionpack/lib/action_controller/dispatcher.rb, line 14 def before_dispatch(*method_names, &block) callbacks[:before].concat method_names callbacks[:before] << block if block_given? end
Backward-compatible class method takes CGI-specific args. Deprecated in favor of Dispatcher.new(output, request, response).dispatch!
# File actionpack/lib/action_controller/dispatcher.rb, line 8 def dispatch(cgi = nil, session_options = CgiRequest::DEFAULT_SESSION_OPTIONS, output = $stdout) new(output).dispatch_cgi(cgi, session_options) end
If the block raises, send status code as a last-ditch response.
# File actionpack/lib/action_controller/dispatcher.rb, line 48 def failsafe_response(fallback_output, status, originating_exception = nil) yield rescue Exception => exception begin log_failsafe_exception(status, originating_exception || exception) body = failsafe_response_body(status) fallback_output.write "Status: #{status}\r\nContent-Type: text/html\r\n\r\n#{body}" nil rescue Exception => failsafe_error # Logger or IO errors $stderr.puts "Error during failsafe response: #{failsafe_error}" $stderr.puts "(originally #{originating_exception})" if originating_exception end end
# File actionpack/lib/action_controller/dispatcher.rb, line 108 def initialize(output, request = nil, response = nil) @output, @request, @response = output, request, response end
Add a preparation callback. Preparation callbacks are run before every request in development mode, and before the first request in production mode.
An optional identifier may be supplied for the callback. If provided, to_prepare may be called again with the same identifier to replace the existing callback. Passing an identifier is a suggested practice if the code adding a preparation block may be reloaded.
# File actionpack/lib/action_controller/dispatcher.rb, line 34 def to_prepare(identifier = nil, &block) # Already registered: update the existing callback if identifier if callback = callbacks[:prepare].assoc(identifier) callback[1] = block else callbacks[:prepare] << [identifier, block] end else callbacks[:prepare] << block end end
# File actionpack/lib/action_controller/dispatcher.rb, line 79 def failsafe_logger if defined?(::RAILS_DEFAULT_LOGGER) && !::RAILS_DEFAULT_LOGGER.nil? ::RAILS_DEFAULT_LOGGER else Logger.new($stderr) end end
# File actionpack/lib/action_controller/dispatcher.rb, line 63 def failsafe_response_body(status) error_path = "#{error_file_path}/#{status.to_s[0..3]}.html" if File.exist?(error_path) File.read(error_path) else "<html><body><h1>#{status}</h1></body></html>" end end
# File actionpack/lib/action_controller/dispatcher.rb, line 73 def log_failsafe_exception(status, exception) message = "/!\ FAILSAFE /!\ #{Time.now}\n Status: #{status}\n" message << " #{exception}\n #{exception.backtrace.join("\n ")}" if exception failsafe_logger.fatal message end
Cleanup the application by clearing out loaded classes so they can be reloaded on the next request without restarting the server.
# File actionpack/lib/action_controller/dispatcher.rb, line 150 def cleanup_application(force = false) if Dependencies.load? || force ActiveRecord::Base.reset_subclasses if defined?(ActiveRecord) Dependencies.clear ActiveRecord::Base.clear_reloadable_connections! if defined?(ActiveRecord) end end
# File actionpack/lib/action_controller/dispatcher.rb, line 112 def dispatch run_callbacks :before handle_request rescue Exception => exception failsafe_rescue exception ensure run_callbacks :after, :reverse_each end
# File actionpack/lib/action_controller/dispatcher.rb, line 121 def dispatch_cgi(cgi, session_options) if cgi ||= self.class.failsafe_response(@output, '400 Bad Request') { CGI.new } @request = CgiRequest.new(cgi, session_options) @response = CgiResponse.new(cgi) dispatch end rescue Exception => exception failsafe_rescue exception end
# File actionpack/lib/action_controller/dispatcher.rb, line 158 def flush_logger RAILS_DEFAULT_LOGGER.flush if defined?(RAILS_DEFAULT_LOGGER) && RAILS_DEFAULT_LOGGER.respond_to?(:flush) end
# File actionpack/lib/action_controller/dispatcher.rb, line 138 def prepare_application(force = false) require_dependency 'application' unless defined?(::ApplicationController) ActiveRecord::Base.verify_active_connections! if defined?(ActiveRecord) if unprepared || force run_callbacks :prepare self.unprepared = false end end
# File actionpack/lib/action_controller/dispatcher.rb, line 131 def reload_application if Dependencies.load? Routing::Routes.reload self.unprepared = true end end
# File actionpack/lib/action_controller/dispatcher.rb, line 179 def failsafe_rescue(exception) self.class.failsafe_response(@output, '500 Internal Server Error', exception) do if @controller ||= defined?(::ApplicationController) ? ::ApplicationController : Base @controller.process_with_exception(@request, @response, exception).out(@output) else raise exception end end end
# File actionpack/lib/action_controller/dispatcher.rb, line 163 def handle_request @controller = Routing::Routes.recognize(@request) @controller.process(@request, @response).out(@output) end
# File actionpack/lib/action_controller/dispatcher.rb, line 168 def run_callbacks(kind, enumerator = :each) callbacks[kind].send(enumerator) do |callback| case callback when Proc; callback.call(self) when String, Symbol; send(callback) when Array; callback[1].call(self) else raise ArgumentError, "Unrecognized callback #{callback.inspect}" end end end