Class: ActionController::Dispatcher

Inherits:
Object
  • Object
show all
Defined in:
lib/action_controller/dispatcher.rb

Overview

Dispatches requests to the appropriate controller and takes care of reloading the app after each request when Dependencies.load? is true.

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(output, request = nil, response = nil) ⇒ Dispatcher

Returns a new instance of Dispatcher.



109
110
111
# File 'lib/action_controller/dispatcher.rb', line 109

def initialize(output, request = nil, response = nil)
  @output, @request, @response = output, request, response
end

Class Method Details

.after_dispatch(*method_names, &block) ⇒ Object

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



21
22
23
24
# File '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

.before_dispatch(*method_names, &block) ⇒ Object

Declare a block to be called before each dispatch. Run in the order declared.



14
15
16
17
# File '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

.dispatch(cgi = nil, session_options = CgiRequest::DEFAULT_SESSION_OPTIONS, output = $stdout) ⇒ Object

Backward-compatible class method takes CGI-specific args. Deprecated in favor of Dispatcher.new(output, request, response).dispatch!



8
9
10
# File '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

.failsafe_response(fallback_output, status, originating_exception = nil) ⇒ Object

If the block raises, send status code as a last-ditch response.



48
49
50
51
52
53
54
55
56
57
58
59
60
# File '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

.to_prepare(identifier = nil, &block) ⇒ Object

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.



34
35
36
37
38
39
40
41
42
43
44
45
# File '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

Instance Method Details

#cleanup_application(force = false) ⇒ Object

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



156
157
158
159
160
161
162
# File 'lib/action_controller/dispatcher.rb', line 156

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

#dispatchObject



113
114
115
116
117
118
119
120
# File 'lib/action_controller/dispatcher.rb', line 113

def dispatch
  run_callbacks :before
  handle_request
rescue Exception => exception
  failsafe_rescue exception
ensure
  run_callbacks :after, :reverse_each
end

#dispatch_cgi(cgi, session_options) ⇒ Object



122
123
124
125
126
127
128
129
130
# File 'lib/action_controller/dispatcher.rb', line 122

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

#flush_loggerObject



164
165
166
# File 'lib/action_controller/dispatcher.rb', line 164

def flush_logger
  RAILS_DEFAULT_LOGGER.flush if defined?(RAILS_DEFAULT_LOGGER) && RAILS_DEFAULT_LOGGER.respond_to?(:flush)
end

#prepare_application(force = false) ⇒ Object



139
140
141
142
143
144
145
146
147
148
149
150
151
152
# File 'lib/action_controller/dispatcher.rb', line 139

def prepare_application(force = false)
  begin
    require_dependency 'application' unless defined?(::ApplicationController)
  rescue LoadError => error
    raise unless error.message =~ /application\.rb/
  end

  ActiveRecord::Base.verify_active_connections! if defined?(ActiveRecord)

  if unprepared || force
    run_callbacks :prepare
    self.unprepared = false
  end
end

#reload_applicationObject



132
133
134
135
136
137
# File 'lib/action_controller/dispatcher.rb', line 132

def reload_application
  if Dependencies.load?
    Routing::Routes.reload
    self.unprepared = true
  end
end