aboutsummaryrefslogtreecommitdiffstats
path: root/actionpack/lib/action_controller/base
diff options
context:
space:
mode:
Diffstat (limited to 'actionpack/lib/action_controller/base')
-rw-r--r--actionpack/lib/action_controller/base/base.rb47
-rw-r--r--actionpack/lib/action_controller/base/chained/benchmarking.rb2
-rw-r--r--actionpack/lib/action_controller/base/http_authentication.rb6
-rw-r--r--actionpack/lib/action_controller/base/layout.rb4
-rw-r--r--actionpack/lib/action_controller/base/redirect.rb8
-rw-r--r--actionpack/lib/action_controller/base/render.rb3
-rw-r--r--actionpack/lib/action_controller/base/rescue.rb50
7 files changed, 89 insertions, 31 deletions
diff --git a/actionpack/lib/action_controller/base/base.rb b/actionpack/lib/action_controller/base/base.rb
index 4429b8f0b7..0993b311cd 100644
--- a/actionpack/lib/action_controller/base/base.rb
+++ b/actionpack/lib/action_controller/base/base.rb
@@ -1,5 +1,7 @@
require 'action_controller/deprecated'
require 'set'
+require 'active_support/core_ext/class/inheritable_attributes'
+require 'active_support/core_ext/module/attr_internal'
module ActionController #:nodoc:
class ActionControllerError < StandardError #:nodoc:
@@ -30,10 +32,6 @@ module ActionController #:nodoc:
def allowed_methods_header
allowed_methods.map { |method_symbol| method_symbol.to_s.upcase } * ', '
end
-
- def handle_response!(response)
- response.headers['Allow'] ||= allowed_methods_header
- end
end
class NotImplemented < MethodNotAllowed #:nodoc:
@@ -369,19 +367,23 @@ module ActionController #:nodoc:
attr_reader :template
- class << self
- def call(env)
- # HACK: For global rescue to have access to the original request and response
- request = env["action_controller.rescue.request"] ||= ActionDispatch::Request.new(env)
- response = env["action_controller.rescue.response"] ||= ActionDispatch::Response.new
- process(request, response)
- end
+ def action(name, env)
+ # HACK: For global rescue to have access to the original request and response
+ request = env["action_controller.rescue.request"] ||= ActionDispatch::Request.new(env)
+ response = env["action_controller.rescue.response"] ||= ActionDispatch::Response.new
+ self.action_name = name && name.to_s
+ process(request, response).to_a
+ end
- # Factory for the standard create, process loop where the controller is discarded after processing.
- def process(request, response) #:nodoc:
- new.process(request, response)
- end
+ class << self
+ def action(name = nil)
+ @actions ||= {}
+ @actions[name] ||= proc do |env|
+ new.action(name, env)
+ end
+ end
+
# Converts the class name from something like "OneModule::TwoModule::NeatController" to "NeatController".
def controller_class_name
@controller_class_name ||= name.demodulize
@@ -511,6 +513,12 @@ module ActionController #:nodoc:
end
public
+ def call(env)
+ request = ActionDispatch::Request.new(env)
+ response = ActionDispatch::Response.new
+ process(request, response).to_a
+ end
+
# Extracts the action_name from the request parameters and performs that action.
def process(request, response, method = :perform_action, *arguments) #:nodoc:
response.request = request
@@ -518,7 +526,6 @@ module ActionController #:nodoc:
assign_shortcuts(request, response)
initialize_template_class(response)
initialize_current_url
- assign_names
log_processing
send(method, *arguments)
@@ -817,9 +824,9 @@ module ActionController #:nodoc:
end
def initialize_template_class(response)
- @template = response.template = ActionView::Base.new(self.class.view_paths, {}, self, formats)
+ @template = ActionView::Base.new(self.class.view_paths, {}, self, formats)
+ response.template = @template if response.respond_to?(:template=)
@template.helpers.send :include, self.class.master_helper_module
- response.redirected_to = nil
@performed_render = @performed_redirect = false
end
@@ -882,10 +889,6 @@ module ActionController #:nodoc:
@performed_render || @performed_redirect
end
- def assign_names
- @action_name = (params['action'] || 'index')
- end
-
def reset_variables_added_to_assigns
@template.instance_variable_set("@assigns_added", nil)
end
diff --git a/actionpack/lib/action_controller/base/chained/benchmarking.rb b/actionpack/lib/action_controller/base/chained/benchmarking.rb
index 066150f58a..66e9e9c31d 100644
--- a/actionpack/lib/action_controller/base/chained/benchmarking.rb
+++ b/actionpack/lib/action_controller/base/chained/benchmarking.rb
@@ -1,4 +1,4 @@
-require 'benchmark'
+require 'active_support/core_ext/benchmark'
module ActionController #:nodoc:
# The benchmarking module times the performance of actions and reports to the logger. If the Active Record
diff --git a/actionpack/lib/action_controller/base/http_authentication.rb b/actionpack/lib/action_controller/base/http_authentication.rb
index 9219847cd0..0be53cb02d 100644
--- a/actionpack/lib/action_controller/base/http_authentication.rb
+++ b/actionpack/lib/action_controller/base/http_authentication.rb
@@ -1,3 +1,5 @@
+require 'active_support/base64'
+
module ActionController
module HttpAuthentication
# Makes it dead easy to do HTTP Basic authentication.
@@ -276,7 +278,7 @@ module ActionController
t = time.to_i
hashed = [t, secret_key]
digest = ::Digest::MD5.hexdigest(hashed.join(":"))
- Base64.encode64("#{t}:#{digest}").gsub("\n", '')
+ ActiveSupport::Base64.encode64("#{t}:#{digest}").gsub("\n", '')
end
# Might want a shorter timeout depending on whether the request
@@ -285,7 +287,7 @@ module ActionController
# allow a user to use new nonce without prompting user again for their
# username and password.
def validate_nonce(request, value, seconds_to_timeout=5*60)
- t = Base64.decode64(value).split(":").first.to_i
+ t = ActiveSupport::Base64.decode64(value).split(":").first.to_i
nonce(t) == value && (t - Time.now.to_i).abs <= seconds_to_timeout
end
diff --git a/actionpack/lib/action_controller/base/layout.rb b/actionpack/lib/action_controller/base/layout.rb
index 1ad5191c73..cf5f46a32b 100644
--- a/actionpack/lib/action_controller/base/layout.rb
+++ b/actionpack/lib/action_controller/base/layout.rb
@@ -1,3 +1,7 @@
+require 'active_support/core_ext/enumerable'
+require 'active_support/core_ext/class/delegating_attributes'
+require 'active_support/core_ext/class/inheritable_attributes'
+
module ActionController #:nodoc:
module Layout #:nodoc:
def self.included(base)
diff --git a/actionpack/lib/action_controller/base/redirect.rb b/actionpack/lib/action_controller/base/redirect.rb
index 2e92117e7c..7e10f614e2 100644
--- a/actionpack/lib/action_controller/base/redirect.rb
+++ b/actionpack/lib/action_controller/base/redirect.rb
@@ -48,8 +48,6 @@ module ActionController
status = 302
end
- response.redirected_to = options
-
case options
# The scheme name consist of a letter followed by any combination of
# letters, digits, and the plus ("+"), period ("."), or hyphen ("-")
@@ -72,7 +70,9 @@ module ActionController
def redirect_to_full_url(url, status)
raise DoubleRenderError if performed?
logger.info("Redirected to #{url}") if logger && logger.info?
- response.redirect(url, interpret_status(status))
+ response.status = interpret_status(status)
+ response.location = url.gsub(/[\r\n]/, '')
+ response.body = "<html><body>You are being <a href=\"#{CGI.escapeHTML(url)}\">redirected</a>.</body></html>"
@performed_redirect = true
end
@@ -82,8 +82,6 @@ module ActionController
# The response body is not reset here, see +erase_render_results+
def erase_redirect_results #:nodoc:
@performed_redirect = false
- response.redirected_to = nil
- response.redirected_to_method_params = nil
response.status = DEFAULT_RENDER_STATUS_CODE
response.headers.delete('Location')
end
diff --git a/actionpack/lib/action_controller/base/render.rb b/actionpack/lib/action_controller/base/render.rb
index 4286577ec5..cc0d878e01 100644
--- a/actionpack/lib/action_controller/base/render.rb
+++ b/actionpack/lib/action_controller/base/render.rb
@@ -253,7 +253,8 @@ module ActionController
response.content_type ||= Mime::JS
render_for_text(js)
- elsif json = options[:json]
+ elsif options.include?(:json)
+ json = options[:json]
json = ActiveSupport::JSON.encode(json) unless json.respond_to?(:to_str)
json = "#{options[:callback]}(#{json})" unless options[:callback].blank?
response.content_type ||= Mime::JSON
diff --git a/actionpack/lib/action_controller/base/rescue.rb b/actionpack/lib/action_controller/base/rescue.rb
new file mode 100644
index 0000000000..2717a06a37
--- /dev/null
+++ b/actionpack/lib/action_controller/base/rescue.rb
@@ -0,0 +1,50 @@
+module ActionController #:nodoc:
+ # Actions that fail to perform as expected throw exceptions. These
+ # exceptions can either be rescued for the public view (with a nice
+ # user-friendly explanation) or for the developers view (with tons of
+ # debugging information). The developers view is already implemented by
+ # the Action Controller, but the public view should be tailored to your
+ # specific application.
+ #
+ # The default behavior for public exceptions is to render a static html
+ # file with the name of the error code thrown. If no such file exists, an
+ # empty response is sent with the correct status code.
+ #
+ # You can override what constitutes a local request by overriding the
+ # <tt>local_request?</tt> method in your own controller. Custom rescue
+ # behavior is achieved by overriding the <tt>rescue_action_in_public</tt>
+ # and <tt>rescue_action_locally</tt> methods.
+ module Rescue
+ def self.included(base) #:nodoc:
+ base.send :include, ActiveSupport::Rescuable
+ base.extend(ClassMethods)
+
+ base.class_eval do
+ alias_method_chain :perform_action, :rescue
+ end
+ end
+
+ module ClassMethods
+ def rescue_action(env)
+ exception = env.delete('action_dispatch.rescue.exception')
+ request = ActionDispatch::Request.new(env)
+ response = ActionDispatch::Response.new
+ new.process(request, response, :rescue_action, exception).to_a
+ end
+ end
+
+ protected
+ # Exception handler called when the performance of an action raises
+ # an exception.
+ def rescue_action(exception)
+ rescue_with_handler(exception) || raise(exception)
+ end
+
+ private
+ def perform_action_with_rescue
+ perform_action_without_rescue
+ rescue Exception => exception
+ rescue_action(exception)
+ end
+ end
+end