| 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 6
6: def define_dispatcher_callbacks(cache_classes)
7: unless cache_classes
8: # Development mode callbacks
9: before_dispatch :reload_application
10: after_dispatch :cleanup_application
11: end
12:
13: # Common callbacks
14: to_prepare :load_application_controller do
15: begin
16: require_dependency 'application' unless defined?(::ApplicationController)
17: rescue LoadError => error
18: raise unless error.message =~ /application\.rb/
19: end
20: end
21:
22: if defined?(ActiveRecord)
23: before_dispatch { ActiveRecord::Base.verify_active_connections! }
24: to_prepare(:activerecord_instantiate_observers) { ActiveRecord::Base.instantiate_observers }
25: end
26:
27: after_dispatch :flush_logger if Base.logger && Base.logger.respond_to?(:flush)
28: 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 32
32: def dispatch(cgi = nil, session_options = CgiRequest::DEFAULT_SESSION_OPTIONS, output = $stdout)
33: new(output).dispatch_cgi(cgi, session_options)
34: end
If the block raises, send status code as a last-ditch response.
# File vendor/rails/actionpack/lib/action_controller/dispatcher.rb, line 51
51: def failsafe_response(fallback_output, status, originating_exception = nil)
52: yield
53: rescue Exception => exception
54: begin
55: log_failsafe_exception(status, originating_exception || exception)
56: body = failsafe_response_body(status)
57: fallback_output.write "Status: #{status}\r\nContent-Type: text/html\r\n\r\n#{body}"
58: nil
59: rescue Exception => failsafe_error # Logger or IO errors
60: $stderr.puts "Error during failsafe response: #{failsafe_error}"
61: $stderr.puts "(originally #{originating_exception})" if originating_exception
62: end
63: end
# File vendor/rails/actionpack/lib/action_controller/dispatcher.rb, line 97
97: def initialize(output = $stdout, request = nil, response = nil)
98: @output, @request, @response = output, request, response
99: 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 44
44: def to_prepare(identifier = nil, &block)
45: @prepare_dispatch_callbacks ||= ActiveSupport::Callbacks::CallbackChain.new
46: callback = ActiveSupport::Callbacks::Callback.new(:prepare_dispatch, block, :identifier => identifier)
47: @prepare_dispatch_callbacks.replace_or_append!(callback)
48: end
# File vendor/rails/actionpack/lib/action_controller/dispatcher.rb, line 122
122: def call(env)
123: @request = RackRequest.new(env)
124: @response = RackResponse.new(@request)
125: dispatch
126: 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 138
138: def cleanup_application
139: ActiveRecord::Base.reset_subclasses if defined?(ActiveRecord)
140: ActiveSupport::Dependencies.clear
141: ActiveRecord::Base.clear_reloadable_connections! if defined?(ActiveRecord)
142: end
# File vendor/rails/actionpack/lib/action_controller/dispatcher.rb, line 101
101: def dispatch
102: begin
103: run_callbacks :before_dispatch
104: handle_request
105: rescue Exception => exception
106: failsafe_rescue exception
107: ensure
108: run_callbacks :after_dispatch, :enumerator => :reverse_each
109: end
110: end
# File vendor/rails/actionpack/lib/action_controller/dispatcher.rb, line 112
112: def dispatch_cgi(cgi, session_options)
113: if cgi ||= self.class.failsafe_response(@output, '400 Bad Request') { CGI.new }
114: @request = CgiRequest.new(cgi, session_options)
115: @response = CgiResponse.new(cgi)
116: dispatch
117: end
118: rescue Exception => exception
119: failsafe_rescue exception
120: end
# File vendor/rails/actionpack/lib/action_controller/dispatcher.rb, line 144
144: def flush_logger
145: Base.logger.flush
146: end
# File vendor/rails/actionpack/lib/action_controller/dispatcher.rb, line 128
128: def reload_application
129: # Run prepare callbacks before every request in development mode
130: run_callbacks :prepare_dispatch
131:
132: Routing::Routes.reload
133: ActionController::Base.view_paths.reload!
134: end
# File vendor/rails/actionpack/lib/action_controller/dispatcher.rb, line 154
154: def failsafe_rescue(exception)
155: self.class.failsafe_response(@output, '500 Internal Server Error', exception) do
156: if @controller ||= defined?(::ApplicationController) ? ::ApplicationController : Base
157: @controller.process_with_exception(@request, @response, exception).out(@output)
158: else
159: raise exception
160: end
161: end
162: end