Class | ActionController::Dispatcher |
In: |
vendor/rails/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.
# File vendor/rails/actionpack/lib/action_controller/dispatcher.rb, line 8 8: def define_dispatcher_callbacks(cache_classes) 9: unless cache_classes 10: # Development mode callbacks 11: before_dispatch :reload_application 12: after_dispatch :cleanup_application 13: end 14: 15: # Common callbacks 16: to_prepare :load_application_controller do 17: begin 18: require_dependency 'application' unless defined?(::ApplicationController) 19: rescue LoadError => error 20: raise unless error.message =~ /application\.rb/ 21: end 22: end 23: 24: if defined?(ActiveRecord) 25: before_dispatch { ActiveRecord::Base.verify_active_connections! } 26: to_prepare(:activerecord_instantiate_observers) { ActiveRecord::Base.instantiate_observers } 27: end 28: 29: after_dispatch :flush_logger if defined?(RAILS_DEFAULT_LOGGER) && RAILS_DEFAULT_LOGGER.respond_to?(:flush) 30: end
Backward-compatible class method takes CGI-specific args. Deprecated in favor of Dispatcher.new(output, request, response).dispatch.
# File vendor/rails/actionpack/lib/action_controller/dispatcher.rb, line 34 34: def dispatch(cgi = nil, session_options = CgiRequest::DEFAULT_SESSION_OPTIONS, output = $stdout) 35: new(output).dispatch_cgi(cgi, session_options) 36: end
If the block raises, send status code as a last-ditch response.
# File vendor/rails/actionpack/lib/action_controller/dispatcher.rb, line 53 53: def failsafe_response(fallback_output, status, originating_exception = nil) 54: yield 55: rescue Exception => exception 56: begin 57: log_failsafe_exception(status, originating_exception || exception) 58: body = failsafe_response_body(status) 59: fallback_output.write "Status: #{status}\r\nContent-Type: text/html\r\n\r\n#{body}" 60: nil 61: rescue Exception => failsafe_error # Logger or IO errors 62: $stderr.puts "Error during failsafe response: #{failsafe_error}" 63: $stderr.puts "(originally #{originating_exception})" if originating_exception 64: end 65: end
# File vendor/rails/actionpack/lib/action_controller/dispatcher.rb, line 99 99: def initialize(output, request = nil, response = nil) 100: @output, @request, @response = output, request, response 101: 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 vendor/rails/actionpack/lib/action_controller/dispatcher.rb, line 46 46: def to_prepare(identifier = nil, &block) 47: @prepare_dispatch_callbacks ||= ActiveSupport::Callbacks::CallbackChain.new 48: callback = ActiveSupport::Callbacks::Callback.new(:prepare_dispatch, block, :identifier => identifier) 49: @prepare_dispatch_callbacks | callback 50: end
Cleanup the application by clearing out loaded classes so they can be reloaded on the next request without restarting the server.
# File vendor/rails/actionpack/lib/action_controller/dispatcher.rb, line 136 136: def cleanup_application 137: ActiveRecord::Base.reset_subclasses if defined?(ActiveRecord) 138: Dependencies.clear 139: ActiveRecord::Base.clear_reloadable_connections! if defined?(ActiveRecord) 140: end
# File vendor/rails/actionpack/lib/action_controller/dispatcher.rb, line 103 103: def dispatch 104: @@guard.synchronize do 105: begin 106: run_callbacks :before_dispatch 107: handle_request 108: rescue Exception => exception 109: failsafe_rescue exception 110: ensure 111: run_callbacks :after_dispatch, :enumerator => :reverse_each 112: end 113: end 114: end
# File vendor/rails/actionpack/lib/action_controller/dispatcher.rb, line 116 116: def dispatch_cgi(cgi, session_options) 117: if cgi ||= self.class.failsafe_response(@output, '400 Bad Request') { CGI.new } 118: @request = CgiRequest.new(cgi, session_options) 119: @response = CgiResponse.new(cgi) 120: dispatch 121: end 122: rescue Exception => exception 123: failsafe_rescue exception 124: end
# File vendor/rails/actionpack/lib/action_controller/dispatcher.rb, line 142 142: def flush_logger 143: RAILS_DEFAULT_LOGGER.flush 144: end
# File vendor/rails/actionpack/lib/action_controller/dispatcher.rb, line 126 126: def reload_application 127: # Run prepare callbacks before every request in development mode 128: run_callbacks :prepare_dispatch 129: 130: Routing::Routes.reload 131: ActionView::TemplateFinder.reload! unless ActionView::Base.cache_template_loading 132: end
# File vendor/rails/actionpack/lib/action_controller/dispatcher.rb, line 152 152: def failsafe_rescue(exception) 153: self.class.failsafe_response(@output, '500 Internal Server Error', exception) do 154: if @controller ||= defined?(::ApplicationController) ? ::ApplicationController : Base 155: @controller.process_with_exception(@request, @response, exception).out(@output) 156: else 157: raise exception 158: end 159: end 160: end