diff options
Diffstat (limited to 'actionpack/lib/action_controller/base')
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 |