diff options
Diffstat (limited to 'actionpack/lib/action_controller/dispatcher.rb')
-rw-r--r-- | actionpack/lib/action_controller/dispatcher.rb | 97 |
1 files changed, 19 insertions, 78 deletions
diff --git a/actionpack/lib/action_controller/dispatcher.rb b/actionpack/lib/action_controller/dispatcher.rb index 2d5e80f0bb..203f6b1683 100644 --- a/actionpack/lib/action_controller/dispatcher.rb +++ b/actionpack/lib/action_controller/dispatcher.rb @@ -12,15 +12,6 @@ module ActionController after_dispatch :cleanup_application end - # Common callbacks - to_prepare :load_application_controller do - begin - require_dependency 'application' unless defined?(::ApplicationController) - rescue LoadError => error - raise unless error.message =~ /application\.rb/ - end - end - if defined?(ActiveRecord) after_dispatch :checkin_connections to_prepare(:activerecord_instantiate_observers) { ActiveRecord::Base.instantiate_observers } @@ -33,8 +24,7 @@ module ActionController end end - # Backward-compatible class method takes CGI-specific args. Deprecated - # in favor of Dispatcher.new(output, request, response).dispatch. + # DEPRECATE: Remove CGI support def dispatch(cgi = nil, session_options = CgiRequest::DEFAULT_SESSION_OPTIONS, output = $stdout) new(output).dispatch_cgi(cgi, session_options) end @@ -52,56 +42,19 @@ module ActionController callback = ActiveSupport::Callbacks::Callback.new(:prepare_dispatch, block, :identifier => identifier) @prepare_dispatch_callbacks.replace_or_append!(callback) end - - # If the block raises, send status code as a last-ditch response. - 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 - - private - 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 - - 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 - - def failsafe_logger - if defined?(::RAILS_DEFAULT_LOGGER) && !::RAILS_DEFAULT_LOGGER.nil? - ::RAILS_DEFAULT_LOGGER - else - Logger.new($stderr) - end - end end - cattr_accessor :error_file_path - self.error_file_path = Rails.public_path if defined?(Rails.public_path) + cattr_accessor :middleware + self.middleware = MiddlewareStack.new + self.middleware.use "ActionController::Failsafe" include ActiveSupport::Callbacks define_callbacks :prepare_dispatch, :before_dispatch, :after_dispatch + # DEPRECATE: Remove arguments def initialize(output = $stdout, request = nil, response = nil) @output, @request, @response = output, request, response + @app = @@middleware.build(lambda { |env| self.dup._call(env) }) end def dispatch_unlocked @@ -125,17 +78,16 @@ module ActionController end end + # DEPRECATE: Remove CGI support 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 + CGIHandler.dispatch_cgi(self, cgi, @output) end def call(env) + @app.call(env) + end + + def _call(env) @request = RackRequest.new(env) @response = RackResponse.new(@request) dispatch @@ -146,7 +98,6 @@ module ActionController run_callbacks :prepare_dispatch Routing::Routes.reload - ActionController::Base.view_paths.reload! ActionView::Helpers::AssetTagHelper::AssetTag::Cache.clear end @@ -162,34 +113,24 @@ module ActionController Base.logger.flush end - def mark_as_test_request! - @test_request = true - self - end - - def test_request? - @test_request - end - def checkin_connections # Don't return connection (and peform implicit rollback) if this request is a part of integration test - return if test_request? + # TODO: This callback should have direct access to env + return if @request.key?("action_controller.test") ActiveRecord::Base.clear_active_connections! end protected def handle_request @controller = Routing::Routes.recognize(@request) - @controller.process(@request, @response).out(@output) + @controller.process(@request, @response).out end 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 + if @controller ||= (::ApplicationController rescue Base) + @controller.process_with_exception(@request, @response, exception).out + else + raise exception end end end |