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.

Methods

Public Class methods

Declare a block to be called after each dispatch. Run in reverse of the order declared.

[Source]

# 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.

[Source]

# 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!

[Source]

# 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.

[Source]

# 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

[Source]

# 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.

[Source]

# 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

Private Class methods

[Source]

# 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

[Source]

# 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

[Source]

# 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

Public Instance methods

Cleanup the application by clearing out loaded classes so they can be reloaded on the next request without restarting the server.

[Source]

# 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

[Source]

# 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

[Source]

# 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

[Source]

# 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

[Source]

# 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

[Source]

# File actionpack/lib/action_controller/dispatcher.rb, line 131
    def reload_application
      if Dependencies.load?
        Routing::Routes.reload
        self.unprepared = true
      end
    end

Protected Instance methods

[Source]

# 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

[Source]

# File actionpack/lib/action_controller/dispatcher.rb, line 163
      def handle_request
        @controller = Routing::Routes.recognize(@request)
        @controller.process(@request, @response).out(@output)
      end

[Source]

# 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

[Validate]