aboutsummaryrefslogtreecommitdiffstats
path: root/actionpack/lib
diff options
context:
space:
mode:
authorXavier Noria <fxn@hashref.com>2010-04-28 13:41:21 -0700
committerXavier Noria <fxn@hashref.com>2010-04-28 13:41:21 -0700
commitb9ab4c780af82c1c60d63c50f040a55da5bfa8db (patch)
tree4df8981047957fce17c10ea5c6aac7955aef2a4d /actionpack/lib
parent8f1a5bfee1305f193bb659c010ca7e2272c12051 (diff)
parent22184930ea323872c73542767d447bbbd7878c96 (diff)
downloadrails-b9ab4c780af82c1c60d63c50f040a55da5bfa8db.tar.gz
rails-b9ab4c780af82c1c60d63c50f040a55da5bfa8db.tar.bz2
rails-b9ab4c780af82c1c60d63c50f040a55da5bfa8db.zip
Merge commit 'rails/master'
Diffstat (limited to 'actionpack/lib')
-rw-r--r--actionpack/lib/abstract_controller.rb1
-rw-r--r--actionpack/lib/abstract_controller/assigns.rb21
-rw-r--r--actionpack/lib/abstract_controller/base.rb17
-rw-r--r--actionpack/lib/abstract_controller/helpers.rb1
-rw-r--r--actionpack/lib/abstract_controller/logger.rb2
-rw-r--r--actionpack/lib/action_controller/base.rb5
-rw-r--r--actionpack/lib/action_controller/caching.rb6
-rw-r--r--actionpack/lib/action_controller/caching/pages.rb8
-rw-r--r--actionpack/lib/action_controller/deprecated/base.rb48
-rw-r--r--actionpack/lib/action_controller/metal/compatibility.rb4
-rw-r--r--actionpack/lib/action_controller/metal/helpers.rb4
-rw-r--r--actionpack/lib/action_controller/metal/renderers.rb6
-rw-r--r--actionpack/lib/action_controller/metal/request_forgery_protection.rb118
-rw-r--r--actionpack/lib/action_controller/railtie.rb65
-rw-r--r--actionpack/lib/action_controller/test_case.rb260
-rw-r--r--actionpack/lib/action_dispatch/http/parameters.rb3
-rw-r--r--actionpack/lib/action_dispatch/middleware/params_parser.rb3
-rw-r--r--actionpack/lib/action_dispatch/routing/mapper.rb9
-rw-r--r--actionpack/lib/action_dispatch/routing/url_for.rb2
-rw-r--r--actionpack/lib/action_dispatch/testing/assertions/routing.rb1
-rw-r--r--actionpack/lib/action_dispatch/testing/test_process.rb1
-rw-r--r--actionpack/lib/action_view/base.rb4
-rw-r--r--actionpack/lib/action_view/helpers/active_model_helper.rb2
-rw-r--r--actionpack/lib/action_view/helpers/prototype_helper.rb2
-rw-r--r--actionpack/lib/action_view/test_case.rb2
25 files changed, 252 insertions, 343 deletions
diff --git a/actionpack/lib/abstract_controller.rb b/actionpack/lib/abstract_controller.rb
index de95f935c2..2da4dc052c 100644
--- a/actionpack/lib/abstract_controller.rb
+++ b/actionpack/lib/abstract_controller.rb
@@ -12,7 +12,6 @@ require 'active_support/i18n'
module AbstractController
extend ActiveSupport::Autoload
- autoload :Assigns
autoload :Base
autoload :Callbacks
autoload :Collector
diff --git a/actionpack/lib/abstract_controller/assigns.rb b/actionpack/lib/abstract_controller/assigns.rb
deleted file mode 100644
index 21459c6d51..0000000000
--- a/actionpack/lib/abstract_controller/assigns.rb
+++ /dev/null
@@ -1,21 +0,0 @@
-module AbstractController
- module Assigns
- # This method should return a hash with assigns.
- # You can overwrite this configuration per controller.
- # :api: public
- def view_assigns
- hash = {}
- variables = instance_variable_names
- variables -= protected_instance_variables if respond_to?(:protected_instance_variables)
- variables.each { |name| hash[name] = instance_variable_get(name) }
- hash
- end
-
- # This method assigns the hash specified in _assigns_hash to the given object.
- # :api: private
- # TODO Ideally, this should be done on AV::Base.new initialization.
- def _evaluate_assigns(object)
- view_assigns.each { |k,v| object.instance_variable_set(k, v) }
- end
- end
-end \ No newline at end of file
diff --git a/actionpack/lib/abstract_controller/base.rb b/actionpack/lib/abstract_controller/base.rb
index c12b584144..8500cbd7f2 100644
--- a/actionpack/lib/abstract_controller/base.rb
+++ b/actionpack/lib/abstract_controller/base.rb
@@ -1,4 +1,4 @@
-require 'active_support/ordered_options'
+require 'active_support/configurable'
module AbstractController
class Error < StandardError; end
@@ -8,6 +8,8 @@ module AbstractController
attr_internal :response_body
attr_internal :action_name
+ include ActiveSupport::Configurable
+
class << self
attr_reader :abstract
alias_method :abstract?, :abstract
@@ -29,14 +31,6 @@ module AbstractController
@descendants ||= []
end
- def config
- @config ||= ActiveSupport::InheritableOptions.new(superclass < Base ? superclass.config : {})
- end
-
- def configure
- yield config
- end
-
# A list of all internal methods for a controller. This finds the first
# abstract superclass of a controller, and gets a list of all public
# instance methods on that abstract class. Public instance methods of
@@ -99,10 +93,6 @@ module AbstractController
abstract!
- def config
- @config ||= ActiveSupport::InheritableOptions.new(self.class.config)
- end
-
# Calls the action going through the entire action dispatch stack.
#
# The actual method that is called is determined by calling
@@ -133,6 +123,7 @@ module AbstractController
end
private
+
# Returns true if the name can be considered an action. This can
# be overridden in subclasses to modify the semantics of what
# can be considered an action.
diff --git a/actionpack/lib/abstract_controller/helpers.rb b/actionpack/lib/abstract_controller/helpers.rb
index 53cf6b3931..4374b439d0 100644
--- a/actionpack/lib/abstract_controller/helpers.rb
+++ b/actionpack/lib/abstract_controller/helpers.rb
@@ -8,7 +8,6 @@ module AbstractController
included do
class_attribute :_helpers
- delegate :_helpers, :to => :'self.class'
self._helpers = Module.new
end
diff --git a/actionpack/lib/abstract_controller/logger.rb b/actionpack/lib/abstract_controller/logger.rb
index 9318f5e369..0b196119f4 100644
--- a/actionpack/lib/abstract_controller/logger.rb
+++ b/actionpack/lib/abstract_controller/logger.rb
@@ -6,7 +6,7 @@ module AbstractController
extend ActiveSupport::Concern
included do
- cattr_accessor :logger
+ config_accessor :logger
extend ActiveSupport::Benchmarkable
end
end
diff --git a/actionpack/lib/action_controller/base.rb b/actionpack/lib/action_controller/base.rb
index 2e94a20d9d..092fe98588 100644
--- a/actionpack/lib/action_controller/base.rb
+++ b/actionpack/lib/action_controller/base.rb
@@ -65,8 +65,11 @@ module ActionController
@subclasses ||= []
end
+ # TODO Move this to the appropriate module
+ config_accessor :assets_dir, :asset_path, :javascripts_dir, :stylesheets_dir
+
ActiveSupport.run_load_hooks(:action_controller, self)
end
end
-require "action_controller/deprecated/base"
+require "action_controller/deprecated/base" \ No newline at end of file
diff --git a/actionpack/lib/action_controller/caching.rb b/actionpack/lib/action_controller/caching.rb
index 0da0ca1893..4105f9e14f 100644
--- a/actionpack/lib/action_controller/caching.rb
+++ b/actionpack/lib/action_controller/caching.rb
@@ -63,12 +63,10 @@ module ActionController #:nodoc:
included do
extend ConfigMethods
- delegate :perform_caching, :perform_caching=, :to => :config
- singleton_class.delegate :perform_caching, :perform_caching=, :to => :config
- self.perform_caching = true
+ config_accessor :perform_caching
+ self.perform_caching = true if perform_caching.nil?
end
-
def caching_allowed?
request.get? && response.status == 200
end
diff --git a/actionpack/lib/action_controller/caching/pages.rb b/actionpack/lib/action_controller/caching/pages.rb
index 20df3a1a69..cefd1f48c0 100644
--- a/actionpack/lib/action_controller/caching/pages.rb
+++ b/actionpack/lib/action_controller/caching/pages.rb
@@ -44,8 +44,8 @@ module ActionController #:nodoc:
# For Rails, this directory has already been set to Rails.public_path (which is usually set to <tt>Rails.root + "/public"</tt>). Changing
# this setting can be useful to avoid naming conflicts with files in <tt>public/</tt>, but doing so will likely require configuring your
# web server to look in the new location for cached files.
- singleton_class.delegate :page_cache_directory, :page_cache_directory=, :to => :config
- self.page_cache_directory = ''
+ config_accessor :page_cache_directory
+ self.page_cache_directory ||= ''
##
# :singleton-method:
@@ -53,8 +53,8 @@ module ActionController #:nodoc:
# order to make it easy for the cached files to be picked up properly by the web server. By default, this cache extension is <tt>.html</tt>.
# If you want something else, like <tt>.php</tt> or <tt>.shtml</tt>, just set Base.page_cache_extension. In cases where a request already has an
# extension, such as <tt>.xml</tt> or <tt>.rss</tt>, page caching will not add an extension. This allows it to work well with RESTful apps.
- singleton_class.delegate :page_cache_extension, :page_cache_extension=, :to => :config
- self.page_cache_extension = '.html'
+ config_accessor :page_cache_extension
+ self.page_cache_extension ||= '.html'
end
module ClassMethods
diff --git a/actionpack/lib/action_controller/deprecated/base.rb b/actionpack/lib/action_controller/deprecated/base.rb
index 57203ce95f..3975afcaf0 100644
--- a/actionpack/lib/action_controller/deprecated/base.rb
+++ b/actionpack/lib/action_controller/deprecated/base.rb
@@ -1,33 +1,16 @@
module ActionController
class Base
- class << self
- def deprecated_config_accessor(option, message = nil)
- deprecated_config_reader(option, message)
- deprecated_config_writer(option, message)
+ # Deprecated methods. Wrap them in a module so they can be overwritten by plugins
+ # (like the verify method.)
+ module DeprecatedBehavior #:nodoc:
+ def relative_url_root
+ ActiveSupport::Deprecation.warn "ActionController::Base.relative_url_root is ineffective. " <<
+ "Please stop using it.", caller
end
- def deprecated_config_reader(option, message = nil)
- message ||= "Reading #{option} directly from ActionController::Base is deprecated. " \
- "Please read it from config.#{option}"
-
- self.class_eval <<-RUBY, __FILE__, __LINE__ + 1
- def #{option}
- ActiveSupport::Deprecation.warn #{message.inspect}, caller
- config.#{option}
- end
- RUBY
- end
-
- def deprecated_config_writer(option, message = nil)
- message ||= "Setting #{option} directly on ActionController::Base is deprecated. " \
- "Please set it on config.action_controller.#{option}"
-
- self.class_eval <<-RUBY, __FILE__, __LINE__ + 1
- def #{option}=(val)
- ActiveSupport::Deprecation.warn #{message.inspect}, caller
- config.#{option} = val
- end
- RUBY
+ def relative_url_root=
+ ActiveSupport::Deprecation.warn "ActionController::Base.relative_url_root= is ineffective. " <<
+ "Please stop using it.", caller
end
def consider_all_requests_local
@@ -125,9 +108,7 @@ module ActionController
def use_accept_header=(val)
use_accept_header
end
- end
- module DeprecatedBehavior
# This method has been moved to ActionDispatch::Request.filter_parameters
def filter_parameter_logging(*args, &block)
ActiveSupport::Deprecation.warn("Setting filter_parameter_logging in ActionController is deprecated and has no longer effect, please set 'config.filter_parameters' in config/application.rb instead", caller)
@@ -146,17 +127,6 @@ module ActionController
extend DeprecatedBehavior
- deprecated_config_writer :session_options
- deprecated_config_writer :session_store
-
- deprecated_config_accessor :assets_dir
- deprecated_config_accessor :asset_path
- deprecated_config_accessor :helpers_path
- deprecated_config_accessor :javascripts_dir
- deprecated_config_accessor :page_cache_directory
- deprecated_config_accessor :relative_url_root, "relative_url_root is ineffective. Please stop using it"
- deprecated_config_accessor :stylesheets_dir
-
delegate :consider_all_requests_local, :consider_all_requests_local=,
:allow_concurrency, :allow_concurrency=, :to => :"self.class"
end
diff --git a/actionpack/lib/action_controller/metal/compatibility.rb b/actionpack/lib/action_controller/metal/compatibility.rb
index 02722360f1..d49465fa0b 100644
--- a/actionpack/lib/action_controller/metal/compatibility.rb
+++ b/actionpack/lib/action_controller/metal/compatibility.rb
@@ -21,8 +21,8 @@ module ActionController
delegate :default_charset=, :to => "ActionDispatch::Response"
end
- # cattr_reader :protected_instance_variables
- cattr_accessor :protected_instance_variables
+ # TODO: Update protected instance variables list
+ config_accessor :protected_instance_variables
self.protected_instance_variables = %w(@assigns @performed_redirect @performed_render
@variables_added @request_origin @url
@parent_controller @action_name
diff --git a/actionpack/lib/action_controller/metal/helpers.rb b/actionpack/lib/action_controller/metal/helpers.rb
index 82bedc3fad..1110d7c117 100644
--- a/actionpack/lib/action_controller/metal/helpers.rb
+++ b/actionpack/lib/action_controller/metal/helpers.rb
@@ -52,8 +52,8 @@ module ActionController
include AbstractController::Helpers
included do
- class_attribute :helpers_path
- self.helpers_path = []
+ config_accessor :helpers_path
+ self.helpers_path ||= []
end
module ClassMethods
diff --git a/actionpack/lib/action_controller/metal/renderers.rb b/actionpack/lib/action_controller/metal/renderers.rb
index aebd71e867..0be07cd1fc 100644
--- a/actionpack/lib/action_controller/metal/renderers.rb
+++ b/actionpack/lib/action_controller/metal/renderers.rb
@@ -71,7 +71,7 @@ module ActionController
end
add :json do |json, options|
- json = ActiveSupport::JSON.encode(json) unless json.respond_to?(:to_str)
+ json = ActiveSupport::JSON.encode(json, options) unless json.respond_to?(:to_str)
json = "#{options[:callback]}(#{json})" unless options[:callback].blank?
self.content_type ||= Mime::JSON
self.response_body = json
@@ -79,12 +79,12 @@ module ActionController
add :js do |js, options|
self.content_type ||= Mime::JS
- self.response_body = js.respond_to?(:to_js) ? js.to_js : js
+ self.response_body = js.respond_to?(:to_js) ? js.to_js(options) : js
end
add :xml do |xml, options|
self.content_type ||= Mime::XML
- self.response_body = xml.respond_to?(:to_xml) ? xml.to_xml : xml
+ self.response_body = xml.respond_to?(:to_xml) ? xml.to_xml(options) : xml
end
add :update do |proc, options|
diff --git a/actionpack/lib/action_controller/metal/request_forgery_protection.rb b/actionpack/lib/action_controller/metal/request_forgery_protection.rb
index 39a809657b..2ba0d6e5cd 100644
--- a/actionpack/lib/action_controller/metal/request_forgery_protection.rb
+++ b/actionpack/lib/action_controller/metal/request_forgery_protection.rb
@@ -4,6 +4,45 @@ module ActionController #:nodoc:
class InvalidAuthenticityToken < ActionControllerError #:nodoc:
end
+ # Protecting controller actions from CSRF attacks by ensuring that all forms are coming from the current
+ # web application, not a forged link from another site, is done by embedding a token based on a random
+ # string stored in the session (which an attacker wouldn't know) in all forms and Ajax requests generated
+ # by Rails and then verifying the authenticity of that token in the controller. Only HTML/JavaScript
+ # requests are checked, so this will not protect your XML API (presumably you'll have a different
+ # authentication scheme there anyway). Also, GET requests are not protected as these should be
+ # idempotent anyway.
+ #
+ # This is turned on with the <tt>protect_from_forgery</tt> method, which will check the token and raise an
+ # ActionController::InvalidAuthenticityToken if it doesn't match what was expected. You can customize the
+ # error message in production by editing public/422.html. A call to this method in ApplicationController is
+ # generated by default in post-Rails 2.0 applications.
+ #
+ # The token parameter is named <tt>authenticity_token</tt> by default. If you are generating an HTML form
+ # manually (without the use of Rails' <tt>form_for</tt>, <tt>form_tag</tt> or other helpers), you have to
+ # include a hidden field named like that and set its value to what is returned by
+ # <tt>form_authenticity_token</tt>.
+ #
+ # Request forgery protection is disabled by default in test environment. If you are upgrading from Rails
+ # 1.x, add this to config/environments/test.rb:
+ #
+ # # Disable request forgery protection in test environment
+ # config.action_controller.allow_forgery_protection = false
+ #
+ # == Learn more about CSRF (Cross-Site Request Forgery) attacks
+ #
+ # Here are some resources:
+ # * http://isc.sans.org/diary.html?storyid=1750
+ # * http://en.wikipedia.org/wiki/Cross-site_request_forgery
+ #
+ # Keep in mind, this is NOT a silver-bullet, plug 'n' play, warm security blanket for your rails application.
+ # There are a few guidelines you should follow:
+ #
+ # * Keep your GET requests safe and idempotent. More reading material:
+ # * http://www.xml.com/pub/a/2002/04/24/deviant.html
+ # * http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.1.1
+ # * Make sure the session cookies that Rails creates are non-persistent. Check in Firefox and look
+ # for "Expires: at end of session"
+ #
module RequestForgeryProtection
extend ActiveSupport::Concern
@@ -12,54 +51,17 @@ module ActionController #:nodoc:
included do
# Sets the token parameter name for RequestForgery. Calling +protect_from_forgery+
# sets it to <tt>:authenticity_token</tt> by default.
- config.request_forgery_protection_token ||= :authenticity_token
+ config_accessor :request_forgery_protection_token
+ self.request_forgery_protection_token ||= :authenticity_token
# Controls whether request forgergy protection is turned on or not. Turned off by default only in test mode.
- config.allow_forgery_protection ||= true
+ config_accessor :allow_forgery_protection
+ self.allow_forgery_protection = true if allow_forgery_protection.nil?
helper_method :form_authenticity_token
helper_method :protect_against_forgery?
end
- # Protecting controller actions from CSRF attacks by ensuring that all forms are coming from the current
- # web application, not a forged link from another site, is done by embedding a token based on a random
- # string stored in the session (which an attacker wouldn't know) in all forms and Ajax requests generated
- # by Rails and then verifying the authenticity of that token in the controller. Only HTML/JavaScript
- # requests are checked, so this will not protect your XML API (presumably you'll have a different
- # authentication scheme there anyway). Also, GET requests are not protected as these should be
- # idempotent anyway.
- #
- # This is turned on with the <tt>protect_from_forgery</tt> method, which will check the token and raise an
- # ActionController::InvalidAuthenticityToken if it doesn't match what was expected. You can customize the
- # error message in production by editing public/422.html. A call to this method in ApplicationController is
- # generated by default in post-Rails 2.0 applications.
- #
- # The token parameter is named <tt>authenticity_token</tt> by default. If you are generating an HTML form
- # manually (without the use of Rails' <tt>form_for</tt>, <tt>form_tag</tt> or other helpers), you have to
- # include a hidden field named like that and set its value to what is returned by
- # <tt>form_authenticity_token</tt>.
- #
- # Request forgery protection is disabled by default in test environment. If you are upgrading from Rails
- # 1.x, add this to config/environments/test.rb:
- #
- # # Disable request forgery protection in test environment
- # config.action_controller.allow_forgery_protection = false
- #
- # == Learn more about CSRF (Cross-Site Request Forgery) attacks
- #
- # Here are some resources:
- # * http://isc.sans.org/diary.html?storyid=1750
- # * http://en.wikipedia.org/wiki/Cross-site_request_forgery
- #
- # Keep in mind, this is NOT a silver-bullet, plug 'n' play, warm security blanket for your rails application.
- # There are a few guidelines you should follow:
- #
- # * Keep your GET requests safe and idempotent. More reading material:
- # * http://www.xml.com/pub/a/2002/04/24/deviant.html
- # * http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.1.1
- # * Make sure the session cookies that Rails creates are non-persistent. Check in Firefox and look
- # for "Expires: at end of session"
- #
module ClassMethods
# Turn on request forgery protection. Bear in mind that only non-GET, HTML/JavaScript requests are checked.
#
@@ -79,22 +81,6 @@ module ActionController #:nodoc:
self.request_forgery_protection_token ||= :authenticity_token
before_filter :verify_authenticity_token, options
end
-
- def request_forgery_protection_token
- config.request_forgery_protection_token
- end
-
- def request_forgery_protection_token=(val)
- config.request_forgery_protection_token = val
- end
-
- def allow_forgery_protection
- config.allow_forgery_protection
- end
-
- def allow_forgery_protection=(val)
- config.allow_forgery_protection = val
- end
end
protected
@@ -104,22 +90,6 @@ module ActionController #:nodoc:
before_filter :verify_authenticity_token, options
end
- def request_forgery_protection_token
- config.request_forgery_protection_token
- end
-
- def request_forgery_protection_token=(val)
- config.request_forgery_protection_token = val
- end
-
- def allow_forgery_protection
- config.allow_forgery_protection
- end
-
- def allow_forgery_protection=(val)
- config.allow_forgery_protection = val
- end
-
# The actual before_filter that is used. Modify this to change how you handle unverified requests.
def verify_authenticity_token
verified_request? || raise(ActionController::InvalidAuthenticityToken)
@@ -146,7 +116,7 @@ module ActionController #:nodoc:
end
def protect_against_forgery?
- config.allow_forgery_protection
+ allow_forgery_protection
end
end
end
diff --git a/actionpack/lib/action_controller/railtie.rb b/actionpack/lib/action_controller/railtie.rb
index b029434004..0e3cdffadc 100644
--- a/actionpack/lib/action_controller/railtie.rb
+++ b/actionpack/lib/action_controller/railtie.rb
@@ -13,64 +13,51 @@ module ActionController
class Railtie < Rails::Railtie
config.action_controller = ActiveSupport::OrderedOptions.new
- ad = config.action_dispatch
- config.action_controller.singleton_class.send(:define_method, :session) do
- ActiveSupport::Deprecation.warn "config.action_controller.session has been " \
- "renamed to config.action_dispatch.session.", caller
- ad.session
- end
+ config.action_controller.singleton_class.tap do |d|
+ d.send(:define_method, :session) do
+ ActiveSupport::Deprecation.warn "config.action_controller.session has been deprecated. " <<
+ "Please use Rails.application.config.session_store instead.", caller
+ end
- config.action_controller.singleton_class.send(:define_method, :session=) do |val|
- ActiveSupport::Deprecation.warn "config.action_controller.session has been " \
- "renamed to config.action_dispatch.session.", caller
- ad.session = val
- end
+ d.send(:define_method, :session=) do |val|
+ ActiveSupport::Deprecation.warn "config.action_controller.session= has been deprecated. " <<
+ "Please use config.session_store(name, options) instead.", caller
+ end
- config.action_controller.singleton_class.send(:define_method, :session_store) do
- ActiveSupport::Deprecation.warn "config.action_controller.session_store has been " \
- "renamed to config.action_dispatch.session_store.", caller
- ad.session_store
- end
+ d.send(:define_method, :session_store) do
+ ActiveSupport::Deprecation.warn "config.action_controller.session_store has been deprecated. " <<
+ "Please use Rails.application.config.session_store instead.", caller
+ end
- config.action_controller.singleton_class.send(:define_method, :session_store=) do |val|
- ActiveSupport::Deprecation.warn "config.action_controller.session_store has been " \
- "renamed to config.action_dispatch.session_store.", caller
- ad.session_store = val
+ d.send(:define_method, :session_store=) do |val|
+ ActiveSupport::Deprecation.warn "config.action_controller.session_store= has been deprecated. " <<
+ "Please use config.session_store(name, options) instead.", caller
+ end
end
log_subscriber :action_controller, ActionController::Railties::LogSubscriber.new
- initializer "action_controller.logger" do
- ActiveSupport.on_load(:action_controller) { self.logger ||= Rails.logger }
- end
-
- initializer "action_controller.page_cache_directory" do
- ActiveSupport.on_load(:action_controller) do
- self.page_cache_directory = Rails.public_path
- end
- end
-
initializer "action_controller.set_configs" do |app|
paths = app.config.paths
ac = app.config.action_controller
- ac.assets_dir = paths.public.to_a.first
- ac.javascripts_dir = paths.public.javascripts.to_a.first
- ac.stylesheets_dir = paths.public.stylesheets.to_a.first
+ ac.assets_dir ||= paths.public.to_a.first
+ ac.javascripts_dir ||= paths.public.javascripts.to_a.first
+ ac.stylesheets_dir ||= paths.public.stylesheets.to_a.first
+ ac.page_cache_directory ||= paths.public.to_a.first
+ ac.helpers_path ||= paths.app.helpers.to_a
ActiveSupport.on_load(:action_controller) do
self.config.merge!(ac)
end
end
- initializer "action_controller.initialize_framework_caches" do
- ActiveSupport.on_load(:action_controller) { self.cache_store ||= RAILS_CACHE }
+ initializer "action_controller.logger" do
+ ActiveSupport.on_load(:action_controller) { self.logger ||= Rails.logger }
end
- initializer "action_controller.set_helpers_path" do |app|
- ActiveSupport.on_load(:action_controller) do
- self.helpers_path = app.config.paths.app.helpers.to_a
- end
+ initializer "action_controller.initialize_framework_caches" do
+ ActiveSupport.on_load(:action_controller) { self.cache_store ||= RAILS_CACHE }
end
initializer "action_controller.url_helpers" do |app|
diff --git a/actionpack/lib/action_controller/test_case.rb b/actionpack/lib/action_controller/test_case.rb
index b3758218a2..2b9b34961e 100644
--- a/actionpack/lib/action_controller/test_case.rb
+++ b/actionpack/lib/action_controller/test_case.rb
@@ -36,6 +36,7 @@ module ActionController
end
def teardown_subscriptions
+ ActiveSupport::Notifications.unsubscribe("action_view.render_template")
ActiveSupport::Notifications.unsubscribe("action_view.render_template!")
end
@@ -282,165 +283,143 @@ module ActionController
#
# assert_redirected_to page_url(:title => 'foo')
class TestCase < ActiveSupport::TestCase
- include ActionDispatch::TestProcess
- include ActionController::TemplateAssertions
+ module Behavior
+ extend ActiveSupport::Concern
+ include ActionDispatch::TestProcess
- attr_reader :response, :request
+ attr_reader :response, :request
- # Executes a request simulating GET HTTP method and set/volley the response
- def get(action, parameters = nil, session = nil, flash = nil)
- process(action, parameters, session, flash, "GET")
- end
+ module ClassMethods
- # Executes a request simulating POST HTTP method and set/volley the response
- def post(action, parameters = nil, session = nil, flash = nil)
- process(action, parameters, session, flash, "POST")
- end
+ # Sets the controller class name. Useful if the name can't be inferred from test class.
+ # Expects +controller_class+ as a constant. Example: <tt>tests WidgetController</tt>.
+ def tests(controller_class)
+ self.controller_class = controller_class
+ end
+
+ def controller_class=(new_class)
+ prepare_controller_class(new_class) if new_class
+ write_inheritable_attribute(:controller_class, new_class)
+ end
- # Executes a request simulating PUT HTTP method and set/volley the response
- def put(action, parameters = nil, session = nil, flash = nil)
- process(action, parameters, session, flash, "PUT")
- end
+ def controller_class
+ if current_controller_class = read_inheritable_attribute(:controller_class)
+ current_controller_class
+ else
+ self.controller_class = determine_default_controller_class(name)
+ end
+ end
- # Executes a request simulating DELETE HTTP method and set/volley the response
- def delete(action, parameters = nil, session = nil, flash = nil)
- process(action, parameters, session, flash, "DELETE")
- end
+ def determine_default_controller_class(name)
+ name.sub(/Test$/, '').constantize
+ rescue NameError
+ nil
+ end
- # Executes a request simulating HEAD HTTP method and set/volley the response
- def head(action, parameters = nil, session = nil, flash = nil)
- process(action, parameters, session, flash, "HEAD")
- end
+ def prepare_controller_class(new_class)
+ new_class.send :include, ActionController::TestCase::RaiseActionExceptions
+ end
- def xml_http_request(request_method, action, parameters = nil, session = nil, flash = nil)
- @request.env['HTTP_X_REQUESTED_WITH'] = 'XMLHttpRequest'
- @request.env['HTTP_ACCEPT'] ||= [Mime::JS, Mime::HTML, Mime::XML, 'text/xml', Mime::ALL].join(', ')
- returning __send__(request_method, action, parameters, session, flash) do
- @request.env.delete 'HTTP_X_REQUESTED_WITH'
- @request.env.delete 'HTTP_ACCEPT'
end
- end
- alias xhr :xml_http_request
-
- def process(action, parameters = nil, session = nil, flash = nil, http_method = 'GET')
- # Sanity check for required instance variables so we can give an
- # understandable error message.
- %w(@routes @controller @request @response).each do |iv_name|
- if !(instance_variable_names.include?(iv_name) || instance_variable_names.include?(iv_name.to_sym)) || instance_variable_get(iv_name).nil?
- raise "#{iv_name} is nil: make sure you set it in your test's setup method."
- end
+
+ # Executes a request simulating GET HTTP method and set/volley the response
+ def get(action, parameters = nil, session = nil, flash = nil)
+ process(action, parameters, session, flash, "GET")
end
- @request.recycle!
- @response.recycle!
- @controller.response_body = nil
- @controller.formats = nil
- @controller.params = nil
-
- @html_document = nil
- @request.env['REQUEST_METHOD'] = http_method
-
- parameters ||= {}
- @request.assign_parameters(@routes, @controller.class.name.underscore.sub(/_controller$/, ''), action.to_s, parameters)
-
- @request.session = ActionController::TestSession.new(session) unless session.nil?
- @request.session["flash"] = @request.flash.update(flash || {})
- @request.session["flash"].sweep
-
- @controller.request = @request
- @controller.params.merge!(parameters)
- build_request_uri(action, parameters)
- Base.class_eval { include Testing }
- @controller.process_with_new_base_test(@request, @response)
- @request.session.delete('flash') if @request.session['flash'].blank?
- @response
- end
+ # Executes a request simulating POST HTTP method and set/volley the response
+ def post(action, parameters = nil, session = nil, flash = nil)
+ process(action, parameters, session, flash, "POST")
+ end
- include ActionDispatch::Assertions
+ # Executes a request simulating PUT HTTP method and set/volley the response
+ def put(action, parameters = nil, session = nil, flash = nil)
+ process(action, parameters, session, flash, "PUT")
+ end
- # When the request.remote_addr remains the default for testing, which is 0.0.0.0, the exception is simply raised inline
- # (bystepping the regular exception handling from rescue_action). If the request.remote_addr is anything else, the regular
- # rescue_action process takes place. This means you can test your rescue_action code by setting remote_addr to something else
- # than 0.0.0.0.
- #
- # The exception is stored in the exception accessor for further inspection.
- module RaiseActionExceptions
- def self.included(base)
- base.class_eval do
- attr_accessor :exception
- protected :exception, :exception=
- end
+ # Executes a request simulating DELETE HTTP method and set/volley the response
+ def delete(action, parameters = nil, session = nil, flash = nil)
+ process(action, parameters, session, flash, "DELETE")
end
- protected
- def rescue_action_without_handler(e)
- self.exception = e
+ # Executes a request simulating HEAD HTTP method and set/volley the response
+ def head(action, parameters = nil, session = nil, flash = nil)
+ process(action, parameters, session, flash, "HEAD")
+ end
- if request.remote_addr == "0.0.0.0"
- raise(e)
- else
- super(e)
+ def xml_http_request(request_method, action, parameters = nil, session = nil, flash = nil)
+ @request.env['HTTP_X_REQUESTED_WITH'] = 'XMLHttpRequest'
+ @request.env['HTTP_ACCEPT'] ||= [Mime::JS, Mime::HTML, Mime::XML, 'text/xml', Mime::ALL].join(', ')
+ returning __send__(request_method, action, parameters, session, flash) do
+ @request.env.delete 'HTTP_X_REQUESTED_WITH'
+ @request.env.delete 'HTTP_ACCEPT'
+ end
+ end
+ alias xhr :xml_http_request
+
+ def process(action, parameters = nil, session = nil, flash = nil, http_method = 'GET')
+ # Sanity check for required instance variables so we can give an
+ # understandable error message.
+ %w(@routes @controller @request @response).each do |iv_name|
+ if !(instance_variable_names.include?(iv_name) || instance_variable_names.include?(iv_name.to_sym)) || instance_variable_get(iv_name).nil?
+ raise "#{iv_name} is nil: make sure you set it in your test's setup method."
end
end
- end
- setup :setup_controller_request_and_response
+ @request.recycle!
+ @response.recycle!
+ @controller.response_body = nil
+ @controller.formats = nil
+ @controller.params = nil
- @@controller_class = nil
+ @html_document = nil
+ @request.env['REQUEST_METHOD'] = http_method
- class << self
- # Sets the controller class name. Useful if the name can't be inferred from test class.
- # Expects +controller_class+ as a constant. Example: <tt>tests WidgetController</tt>.
- def tests(controller_class)
- self.controller_class = controller_class
- end
+ parameters ||= {}
+ @request.assign_parameters(@routes, @controller.class.name.underscore.sub(/_controller$/, ''), action.to_s, parameters)
- def controller_class=(new_class)
- prepare_controller_class(new_class) if new_class
- write_inheritable_attribute(:controller_class, new_class)
- end
+ @request.session = ActionController::TestSession.new(session) unless session.nil?
+ @request.session["flash"] = @request.flash.update(flash || {})
+ @request.session["flash"].sweep
- def controller_class
- if current_controller_class = read_inheritable_attribute(:controller_class)
- current_controller_class
- else
- self.controller_class = determine_default_controller_class(name)
- end
+ @controller.request = @request
+ @controller.params.merge!(parameters)
+ build_request_uri(action, parameters)
+ Base.class_eval { include Testing }
+ @controller.process_with_new_base_test(@request, @response)
+ @request.session.delete('flash') if @request.session['flash'].blank?
+ @response
end
- def determine_default_controller_class(name)
- name.sub(/Test$/, '').constantize
- rescue NameError
- nil
- end
+ def setup_controller_request_and_response
+ @request = TestRequest.new
+ @response = TestResponse.new
- def prepare_controller_class(new_class)
- new_class.send :include, RaiseActionExceptions
- end
- end
+ if klass = self.class.controller_class
+ @controller ||= klass.new rescue nil
+ end
- def setup_controller_request_and_response
- @request = TestRequest.new
- @response = TestResponse.new
+ @request.env.delete('PATH_INFO')
- if klass = self.class.controller_class
- @controller ||= klass.new rescue nil
+ if @controller
+ @controller.request = @request
+ @controller.params = {}
+ end
end
- @request.env.delete('PATH_INFO')
-
- if @controller
- @controller.request = @request
- @controller.params = {}
+ # Cause the action to be rescued according to the regular rules for rescue_action when the visitor is not local
+ def rescue_action_in_public!
+ @request.remote_addr = '208.77.188.166' # example.com
end
- end
- # Cause the action to be rescued according to the regular rules for rescue_action when the visitor is not local
- def rescue_action_in_public!
- @request.remote_addr = '208.77.188.166' # example.com
- end
+ included do
+ include ActionController::TemplateAssertions
+ include ActionDispatch::Assertions
+ setup :setup_controller_request_and_response
+ end
private
+
def build_request_uri(action, parameters)
unless @request.env["PATH_INFO"]
options = @controller.__send__(:url_options).merge(parameters)
@@ -458,4 +437,33 @@ module ActionController
end
end
end
+
+ # When the request.remote_addr remains the default for testing, which is 0.0.0.0, the exception is simply raised inline
+ # (bystepping the regular exception handling from rescue_action). If the request.remote_addr is anything else, the regular
+ # rescue_action process takes place. This means you can test your rescue_action code by setting remote_addr to something else
+ # than 0.0.0.0.
+ #
+ # The exception is stored in the exception accessor for further inspection.
+ module RaiseActionExceptions
+ def self.included(base)
+ base.class_eval do
+ attr_accessor :exception
+ protected :exception, :exception=
+ end
+ end
+
+ protected
+ def rescue_action_without_handler(e)
+ self.exception = e
+
+ if request.remote_addr == "0.0.0.0"
+ raise(e)
+ else
+ super(e)
+ end
+ end
+ end
+
+ include Behavior
+ end
end
diff --git a/actionpack/lib/action_dispatch/http/parameters.rb b/actionpack/lib/action_dispatch/http/parameters.rb
index 40b40ea94e..bc43414e75 100644
--- a/actionpack/lib/action_dispatch/http/parameters.rb
+++ b/actionpack/lib/action_dispatch/http/parameters.rb
@@ -1,4 +1,5 @@
require 'active_support/core_ext/hash/keys'
+require 'active_support/core_ext/hash/indifferent_access'
module ActionDispatch
module Http
@@ -46,4 +47,4 @@ module ActionDispatch
end
end
end
-end \ No newline at end of file
+end
diff --git a/actionpack/lib/action_dispatch/middleware/params_parser.rb b/actionpack/lib/action_dispatch/middleware/params_parser.rb
index 09fb1f998a..a25089176c 100644
--- a/actionpack/lib/action_dispatch/middleware/params_parser.rb
+++ b/actionpack/lib/action_dispatch/middleware/params_parser.rb
@@ -1,5 +1,6 @@
-require 'active_support/core_ext/hash/conversions.rb'
+require 'active_support/core_ext/hash/conversions'
require 'action_dispatch/http/request'
+require 'active_support/core_ext/hash/indifferent_access'
module ActionDispatch
class ParamsParser
diff --git a/actionpack/lib/action_dispatch/routing/mapper.rb b/actionpack/lib/action_dispatch/routing/mapper.rb
index ef2826a4e8..4b02c2deb3 100644
--- a/actionpack/lib/action_dispatch/routing/mapper.rb
+++ b/actionpack/lib/action_dispatch/routing/mapper.rb
@@ -64,10 +64,11 @@ module ActionDispatch
end
path = normalize_path(path)
+ path_without_format = path.sub(/\(\.:format\)$/, '')
- if using_match_shorthand?(path, options)
- options[:to] ||= path[1..-1].sub(%r{/([^/]*)$}, '#\1').sub(%r{\(.*\)}, '')
- options[:as] ||= path[1..-1].gsub("/", "_").sub(%r{\(.*\)}, '')
+ if using_match_shorthand?(path_without_format, options)
+ options[:to] ||= path_without_format[1..-1].sub(%r{/([^/]*)$}, '#\1')
+ options[:as] ||= path_without_format[1..-1].gsub("/", "_")
end
[ path, options ]
@@ -80,7 +81,7 @@ module ActionDispatch
# match "account/overview"
def using_match_shorthand?(path, options)
- path && options.except(:via, :anchor, :to, :as).empty? && path =~ %r{^/[\w+/?]+(\(.*\))*$}
+ path && options.except(:via, :anchor, :to, :as).empty? && path =~ %r{^/[\w\/]+$}
end
def normalize_path(path)
diff --git a/actionpack/lib/action_dispatch/routing/url_for.rb b/actionpack/lib/action_dispatch/routing/url_for.rb
index fb236dce53..db17615d92 100644
--- a/actionpack/lib/action_dispatch/routing/url_for.rb
+++ b/actionpack/lib/action_dispatch/routing/url_for.rb
@@ -128,7 +128,7 @@ module ActionDispatch
when String
options
when nil, Hash
- _router.url_for(url_options.merge(options || {}))
+ _router.url_for(url_options.merge((options || {}).symbolize_keys))
else
polymorphic_url(options)
end
diff --git a/actionpack/lib/action_dispatch/testing/assertions/routing.rb b/actionpack/lib/action_dispatch/testing/assertions/routing.rb
index b7e9b0c95a..1499c03bdf 100644
--- a/actionpack/lib/action_dispatch/testing/assertions/routing.rb
+++ b/actionpack/lib/action_dispatch/testing/assertions/routing.rb
@@ -1,4 +1,5 @@
require 'active_support/core_ext/hash/diff'
+require 'active_support/core_ext/hash/indifferent_access'
module ActionDispatch
module Assertions
diff --git a/actionpack/lib/action_dispatch/testing/test_process.rb b/actionpack/lib/action_dispatch/testing/test_process.rb
index 79f309cae7..c56ebc6438 100644
--- a/actionpack/lib/action_dispatch/testing/test_process.rb
+++ b/actionpack/lib/action_dispatch/testing/test_process.rb
@@ -1,4 +1,5 @@
require 'action_dispatch/middleware/flash'
+require 'active_support/core_ext/hash/indifferent_access'
module ActionDispatch
module TestProcess
diff --git a/actionpack/lib/action_view/base.rb b/actionpack/lib/action_view/base.rb
index be9791505e..4ac2ee52d6 100644
--- a/actionpack/lib/action_view/base.rb
+++ b/actionpack/lib/action_view/base.rb
@@ -176,8 +176,6 @@ module ActionView #:nodoc:
delegate :logger, :to => 'ActionController::Base', :allow_nil => true
end
- ActiveSupport.run_load_hooks(:action_view, self)
-
attr_accessor :base_path, :assigns, :template_extension, :lookup_context
attr_internal :captures, :request, :controller, :template, :config
@@ -229,5 +227,7 @@ module ActionView #:nodoc:
response.body_parts << part
nil
end
+
+ ActiveSupport.run_load_hooks(:action_view, self)
end
end
diff --git a/actionpack/lib/action_view/helpers/active_model_helper.rb b/actionpack/lib/action_view/helpers/active_model_helper.rb
index a7650c0050..d9f09b5dc5 100644
--- a/actionpack/lib/action_view/helpers/active_model_helper.rb
+++ b/actionpack/lib/action_view/helpers/active_model_helper.rb
@@ -6,7 +6,7 @@ require 'active_support/core_ext/object/blank'
module ActionView
ActiveSupport.on_load(:action_view) do
class ActionView::Base
- @@field_error_proc = Proc.new{ |html_tag, instance| "<div class=\"fieldWithErrors\">#{html_tag}</div>".html_safe }
+ @@field_error_proc = Proc.new{ |html_tag, instance| "<div class=\"field_with_errors\">#{html_tag}</div>".html_safe }
cattr_accessor :field_error_proc
end
end
diff --git a/actionpack/lib/action_view/helpers/prototype_helper.rb b/actionpack/lib/action_view/helpers/prototype_helper.rb
index ebe0b4e876..a798c3eaef 100644
--- a/actionpack/lib/action_view/helpers/prototype_helper.rb
+++ b/actionpack/lib/action_view/helpers/prototype_helper.rb
@@ -767,7 +767,7 @@ module ActionView
end
def grep(variable, pattern, &block)
- enumerate :grep, :variable => variable, :return => true, :method_args => [pattern], :yield_args => %w(value index), &block
+ enumerate :grep, :variable => variable, :return => true, :method_args => [::ActiveSupport::JSON::Variable.new(pattern.inspect)], :yield_args => %w(value index), &block
end
def in_groups_of(variable, number, fill_with = nil)
diff --git a/actionpack/lib/action_view/test_case.rb b/actionpack/lib/action_view/test_case.rb
index beda7743bf..f6417d5c2c 100644
--- a/actionpack/lib/action_view/test_case.rb
+++ b/actionpack/lib/action_view/test_case.rb
@@ -31,8 +31,8 @@ module ActionView
include ActionController::PolymorphicRoutes
include ActionController::RecordIdentifier
+ include AbstractController::Helpers
include ActionView::Helpers
- include ActionController::Helpers
class_inheritable_accessor :helper_class
attr_accessor :controller, :output_buffer, :rendered