aboutsummaryrefslogtreecommitdiffstats
path: root/actionpack/lib/action_controller
diff options
context:
space:
mode:
Diffstat (limited to 'actionpack/lib/action_controller')
-rw-r--r--actionpack/lib/action_controller/assertions/response_assertions.rb2
-rwxr-xr-xactionpack/lib/action_controller/base.rb35
-rw-r--r--actionpack/lib/action_controller/caching/actions.rb61
-rw-r--r--actionpack/lib/action_controller/caching/fragments.rb18
-rw-r--r--actionpack/lib/action_controller/dispatcher.rb6
-rw-r--r--actionpack/lib/action_controller/integration.rb9
-rw-r--r--actionpack/lib/action_controller/layout.rb2
-rw-r--r--actionpack/lib/action_controller/performance_test.rb16
-rw-r--r--actionpack/lib/action_controller/polymorphic_routes.rb37
-rw-r--r--actionpack/lib/action_controller/rack_process.rb54
-rw-r--r--actionpack/lib/action_controller/record_identifier.rb33
-rwxr-xr-xactionpack/lib/action_controller/request.rb9
-rw-r--r--actionpack/lib/action_controller/resources.rb6
-rw-r--r--actionpack/lib/action_controller/routing.rb2
-rw-r--r--actionpack/lib/action_controller/routing/segments.rb2
-rw-r--r--actionpack/lib/action_controller/templates/rescues/layout.erb2
-rw-r--r--actionpack/lib/action_controller/vendor/html-scanner/html/document.rb2
-rw-r--r--actionpack/lib/action_controller/verification.rb2
18 files changed, 165 insertions, 133 deletions
diff --git a/actionpack/lib/action_controller/assertions/response_assertions.rb b/actionpack/lib/action_controller/assertions/response_assertions.rb
index c5fc6c7966..3deda0b45a 100644
--- a/actionpack/lib/action_controller/assertions/response_assertions.rb
+++ b/actionpack/lib/action_controller/assertions/response_assertions.rb
@@ -97,7 +97,7 @@ module ActionController
value['controller'] = value['controller'].to_s
if key == :actual && value['controller'].first != '/' && !value['controller'].include?('/')
new_controller_path = ActionController::Routing.controller_relative_to(value['controller'], @controller.class.controller_path)
- value['controller'] = new_controller_path if value['controller'] != new_controller_path && ActionController::Routing.possible_controllers.include?(new_controller_path)
+ value['controller'] = new_controller_path if value['controller'] != new_controller_path && ActionController::Routing.possible_controllers.include?(new_controller_path) && @response.redirected_to.is_a?(Hash)
end
value['controller'] = value['controller'][1..-1] if value['controller'].first == '/' # strip leading hash
end
diff --git a/actionpack/lib/action_controller/base.rb b/actionpack/lib/action_controller/base.rb
index 6222c3205d..817b270feb 100755
--- a/actionpack/lib/action_controller/base.rb
+++ b/actionpack/lib/action_controller/base.rb
@@ -283,13 +283,6 @@ module ActionController #:nodoc:
@@debug_routes = true
cattr_accessor :debug_routes
- # Indicates to Mongrel or Webrick whether to allow concurrent action
- # processing. Your controller actions and any other code they call must
- # also behave well when called from concurrent threads. Turned off by
- # default.
- @@allow_concurrency = false
- cattr_accessor :allow_concurrency
-
# Modern REST web services often need to submit complex data to the web application.
# The <tt>@@param_parsers</tt> hash lets you register handlers which will process the HTTP body and add parameters to the
# <tt>params</tt> hash. These handlers are invoked for POST and PUT requests.
@@ -428,8 +421,7 @@ module ActionController #:nodoc:
end
def view_paths=(value)
- @view_paths = value
- ActionView::TemplateFinder.process_view_paths(value)
+ @view_paths = ActionView::ViewLoadPaths.new(Array(value)) if value
end
# Adds a view_path to the front of the view_paths array.
@@ -441,8 +433,7 @@ module ActionController #:nodoc:
#
def prepend_view_path(path)
@view_paths = superclass.view_paths.dup if @view_paths.nil?
- view_paths.unshift(*path)
- ActionView::TemplateFinder.process_view_paths(path)
+ @view_paths.unshift(*path)
end
# Adds a view_path to the end of the view_paths array.
@@ -454,8 +445,7 @@ module ActionController #:nodoc:
#
def append_view_path(path)
@view_paths = superclass.view_paths.dup if @view_paths.nil?
- view_paths.push(*path)
- ActionView::TemplateFinder.process_view_paths(path)
+ @view_paths.push(*path)
end
# Replace sensitive parameter data from the request log.
@@ -613,8 +603,8 @@ module ActionController #:nodoc:
#
# This takes the current URL as is and only exchanges the action. In contrast, <tt>url_for :action => 'print'</tt>
# would have slashed-off the path components after the changed action.
- def url_for(options = nil) #:doc:
- case options || {}
+ def url_for(options = {}) #:doc:
+ case options
when String
options
when Hash
@@ -647,11 +637,11 @@ module ActionController #:nodoc:
# View load paths for controller.
def view_paths
- @template.finder.view_paths
+ @template.view_paths
end
def view_paths=(value)
- @template.finder.view_paths = value # Mutex needed
+ @template.view_paths = ViewLoadPaths.new(value)
end
# Adds a view_path to the front of the view_paths array.
@@ -661,7 +651,7 @@ module ActionController #:nodoc:
# self.prepend_view_path(["views/default", "views/custom"])
#
def prepend_view_path(path)
- @template.finder.prepend_view_path(path) # Mutex needed
+ @template.view_paths.unshift(*path)
end
# Adds a view_path to the end of the view_paths array.
@@ -671,7 +661,7 @@ module ActionController #:nodoc:
# self.append_view_path(["views/default", "views/custom"])
#
def append_view_path(path)
- @template.finder.append_view_path(path) # Mutex needed
+ @template.view_paths.push(*path)
end
protected
@@ -1232,7 +1222,7 @@ module ActionController #:nodoc:
end
def template_exists?(template_name = default_template_name)
- @template.finder.file_exists?(template_name)
+ @template.file_exists?(template_name)
end
def template_public?(template_name = default_template_name)
@@ -1240,9 +1230,8 @@ module ActionController #:nodoc:
end
def template_exempt_from_layout?(template_name = default_template_name)
- extension = @template && @template.finder.pick_template_extension(template_name)
- name_with_extension = !template_name.include?('.') && extension ? "#{template_name}.#{extension}" : template_name
- @@exempt_from_layout.any? { |ext| name_with_extension =~ ext }
+ template_name = @template.send(:template_file_from_name, template_name) if @template
+ @@exempt_from_layout.any? { |ext| template_name.to_s =~ ext }
end
def default_template_name(action_name = self.action_name)
diff --git a/actionpack/lib/action_controller/caching/actions.rb b/actionpack/lib/action_controller/caching/actions.rb
index 1ef9e60a21..65a36f7f98 100644
--- a/actionpack/lib/action_controller/caching/actions.rb
+++ b/actionpack/lib/action_controller/caching/actions.rb
@@ -40,6 +40,8 @@ module ActionController #:nodoc:
# controller.send(:list_url, c.params[:id]) }
# end
#
+ # If you pass :layout => false, it will only cache your action content. It is useful when your layout has dynamic information.
+ #
module Actions
def self.included(base) #:nodoc:
base.extend(ClassMethods)
@@ -54,7 +56,8 @@ module ActionController #:nodoc:
def caches_action(*actions)
return unless cache_configured?
options = actions.extract_options!
- around_filter(ActionCacheFilter.new(:cache_path => options.delete(:cache_path)), {:only => actions}.merge(options))
+ cache_filter = ActionCacheFilter.new(:layout => options.delete(:layout), :cache_path => options.delete(:cache_path))
+ around_filter(cache_filter, {:only => actions}.merge(options))
end
end
@@ -64,10 +67,10 @@ module ActionController #:nodoc:
if options[:action].is_a?(Array)
options[:action].dup.each do |action|
- expire_fragment(ActionCachePath.path_for(self, options.merge({ :action => action })))
+ expire_fragment(ActionCachePath.path_for(self, options.merge({ :action => action }), false))
end
else
- expire_fragment(ActionCachePath.path_for(self, options))
+ expire_fragment(ActionCachePath.path_for(self, options, false))
end
end
@@ -81,7 +84,9 @@ module ActionController #:nodoc:
if cache = controller.read_fragment(cache_path.path)
controller.rendered_action_cache = true
set_content_type!(controller, cache_path.extension)
- controller.send!(:render_for_text, cache)
+ options = { :text => cache }
+ options.merge!(:layout => true) if cache_layout?
+ controller.send!(:render, options)
false
else
controller.action_cache_path = cache_path
@@ -90,7 +95,8 @@ module ActionController #:nodoc:
def after(controller)
return if controller.rendered_action_cache || !caching_allowed(controller)
- controller.write_fragment(controller.action_cache_path.path, controller.response.body)
+ action_content = cache_layout? ? content_for_layout(controller) : controller.response.body
+ controller.write_fragment(controller.action_cache_path.path, action_content)
end
private
@@ -105,22 +111,38 @@ module ActionController #:nodoc:
def caching_allowed(controller)
controller.request.get? && controller.response.headers['Status'].to_i == 200
end
+
+ def cache_layout?
+ @options[:layout] == false
+ end
+
+ def content_for_layout(controller)
+ controller.response.layout && controller.response.template.instance_variable_get('@content_for_layout')
+ end
end
class ActionCachePath
attr_reader :path, :extension
class << self
- def path_for(controller, options)
- new(controller, options).path
+ def path_for(controller, options, infer_extension=true)
+ new(controller, options, infer_extension).path
end
end
-
- def initialize(controller, options = {})
- @extension = extract_extension(controller.request.path)
+
+ # When true, infer_extension will look up the cache path extension from the request's path & format.
+ # This is desirable when reading and writing the cache, but not when expiring the cache - expire_action should expire the same files regardless of the request format.
+ def initialize(controller, options = {}, infer_extension=true)
+ if infer_extension and options.is_a? Hash
+ request_extension = extract_extension(controller.request)
+ options = options.reverse_merge(:format => request_extension)
+ end
path = controller.url_for(options).split('://').last
normalize!(path)
- add_extension!(path, @extension)
+ if infer_extension
+ @extension = request_extension
+ add_extension!(path, @extension)
+ end
@path = URI.unescape(path)
end
@@ -130,13 +152,22 @@ module ActionController #:nodoc:
end
def add_extension!(path, extension)
- path << ".#{extension}" if extension
+ path << ".#{extension}" if extension and !path.ends_with?(extension)
end
-
- def extract_extension(file_path)
+
+ def extract_extension(request)
# Don't want just what comes after the last '.' to accommodate multi part extensions
# such as tar.gz.
- file_path[/^[^.]+\.(.+)$/, 1]
+ extension = request.path[/^[^.]+\.(.+)$/, 1]
+
+ # If there's no extension in the path, check request.format
+ if extension.nil?
+ extension = request.format.to_sym.to_s
+ if extension=='all'
+ extension = nil
+ end
+ end
+ extension
end
end
end
diff --git a/actionpack/lib/action_controller/caching/fragments.rb b/actionpack/lib/action_controller/caching/fragments.rb
index 578e031a17..45946421fc 100644
--- a/actionpack/lib/action_controller/caching/fragments.rb
+++ b/actionpack/lib/action_controller/caching/fragments.rb
@@ -61,16 +61,18 @@ module ActionController #:nodoc:
end
def fragment_for(block, name = {}, options = nil) #:nodoc:
- unless perform_caching then block.call; return end
-
- buffer = yield
-
- if cache = read_fragment(name, options)
- buffer.concat(cache)
+ if perform_caching
+ buffer = yield
+
+ if cache = read_fragment(name, options)
+ buffer.concat(cache)
+ else
+ pos = buffer.length
+ block.call
+ write_fragment(name, buffer[pos..-1], options)
+ end
else
- pos = buffer.length
block.call
- write_fragment(name, buffer[pos..-1], options)
end
end
diff --git a/actionpack/lib/action_controller/dispatcher.rb b/actionpack/lib/action_controller/dispatcher.rb
index b40f1ba9be..7df987d525 100644
--- a/actionpack/lib/action_controller/dispatcher.rb
+++ b/actionpack/lib/action_controller/dispatcher.rb
@@ -125,7 +125,7 @@ module ActionController
def call(env)
@request = RackRequest.new(env)
- @response = RackResponse.new
+ @response = RackResponse.new(@request)
dispatch
end
@@ -134,14 +134,14 @@ module ActionController
run_callbacks :prepare_dispatch
Routing::Routes.reload
- ActionView::TemplateFinder.reload! unless ActionView::Base.cache_template_loading
+ ActionController::Base.view_paths.reload!
end
# Cleanup the application by clearing out loaded classes so they can
# be reloaded on the next request without restarting the server.
def cleanup_application
ActiveRecord::Base.reset_subclasses if defined?(ActiveRecord)
- Dependencies.clear
+ ActiveSupport::Dependencies.clear
ActiveRecord::Base.clear_reloadable_connections! if defined?(ActiveRecord)
end
diff --git a/actionpack/lib/action_controller/integration.rb b/actionpack/lib/action_controller/integration.rb
index 12e1b4d493..2a732448f2 100644
--- a/actionpack/lib/action_controller/integration.rb
+++ b/actionpack/lib/action_controller/integration.rb
@@ -1,9 +1,10 @@
-require 'stringio'
-require 'uri'
-
+require 'active_support/test_case'
require 'action_controller/dispatcher'
require 'action_controller/test_process'
+require 'stringio'
+require 'uri'
+
module ActionController
module Integration #:nodoc:
# An integration Session instance represents a set of requests and responses
@@ -580,7 +581,7 @@ EOF
# end
# end
# end
- class IntegrationTest < Test::Unit::TestCase
+ class IntegrationTest < ActiveSupport::TestCase
include Integration::Runner
# Work around a bug in test/unit caused by the default test being named
diff --git a/actionpack/lib/action_controller/layout.rb b/actionpack/lib/action_controller/layout.rb
index b5b59f2d7c..0721f71498 100644
--- a/actionpack/lib/action_controller/layout.rb
+++ b/actionpack/lib/action_controller/layout.rb
@@ -304,7 +304,7 @@ module ActionController #:nodoc:
end
def layout_directory?(layout_name)
- @template.finder.find_template_extension_from_handler(File.join('layouts', layout_name))
+ @template.view_paths.find_template_file_for_path("#{File.join('layouts', layout_name)}.#{@template.template_format}.erb") ? true : false
end
end
end
diff --git a/actionpack/lib/action_controller/performance_test.rb b/actionpack/lib/action_controller/performance_test.rb
new file mode 100644
index 0000000000..85543fffae
--- /dev/null
+++ b/actionpack/lib/action_controller/performance_test.rb
@@ -0,0 +1,16 @@
+require 'action_controller/integration'
+require 'active_support/testing/performance'
+require 'active_support/testing/default'
+
+module ActionController
+ # An integration test that runs a code profiler on your test methods.
+ # Profiling output for combinations of each test method, measurement, and
+ # output format are written to your tmp/performance directory.
+ #
+ # By default, process_time is measured and both flat and graph_html output
+ # formats are written, so you'll have two output files per test method.
+ class PerformanceTest < ActionController::IntegrationTest
+ include ActiveSupport::Testing::Performance
+ include ActiveSupport::Testing::Default
+ end
+end
diff --git a/actionpack/lib/action_controller/polymorphic_routes.rb b/actionpack/lib/action_controller/polymorphic_routes.rb
index 509fa6a08e..7c30bf0778 100644
--- a/actionpack/lib/action_controller/polymorphic_routes.rb
+++ b/actionpack/lib/action_controller/polymorphic_routes.rb
@@ -48,6 +48,9 @@ module ActionController
#
# # calls post_url(post)
# polymorphic_url(post) # => "http://example.com/posts/1"
+ # polymorphic_url([blog, post]) # => "http://example.com/blogs/1/posts/1"
+ # polymorphic_url([:admin, blog, post]) # => "http://example.com/admin/blogs/1/posts/1"
+ # polymorphic_url([user, :blog, post]) # => "http://example.com/users/1/blog/posts/1"
#
# ==== Options
#
@@ -83,8 +86,6 @@ module ActionController
else [ record_or_hash_or_array ]
end
- args << format if format
-
inflection =
case
when options[:action].to_s == "new"
@@ -96,6 +97,9 @@ module ActionController
else
:singular
end
+
+ args.delete_if {|arg| arg.is_a?(Symbol) || arg.is_a?(String)}
+ args << format if format
named_route = build_named_route_call(record_or_hash_or_array, namespace, inflection, options)
send!(named_route, *args)
@@ -136,11 +140,19 @@ module ActionController
else
record = records.pop
route = records.inject("") do |string, parent|
- string << "#{RecordIdentifier.send!("singular_class_name", parent)}_"
+ if parent.is_a?(Symbol) || parent.is_a?(String)
+ string << "#{parent}_"
+ else
+ string << "#{RecordIdentifier.send!("singular_class_name", parent)}_"
+ end
end
end
- route << "#{RecordIdentifier.send!("#{inflection}_class_name", record)}_"
+ if record.is_a?(Symbol) || record.is_a?(String)
+ route << "#{record}_"
+ else
+ route << "#{RecordIdentifier.send!("#{inflection}_class_name", record)}_"
+ end
action_prefix(options) + namespace + route + routing_type(options).to_s
end
@@ -163,16 +175,17 @@ module ActionController
end
end
+ # Remove the first symbols from the array and return the url prefix
+ # implied by those symbols.
def extract_namespace(record_or_hash_or_array)
- returning "" do |namespace|
- if record_or_hash_or_array.is_a?(Array)
- record_or_hash_or_array.delete_if do |record_or_namespace|
- if record_or_namespace.is_a?(String) || record_or_namespace.is_a?(Symbol)
- namespace << "#{record_or_namespace}_"
- end
- end
- end
+ return "" unless record_or_hash_or_array.is_a?(Array)
+
+ namespace_keys = []
+ while (key = record_or_hash_or_array.first) && key.is_a?(String) || key.is_a?(Symbol)
+ namespace_keys << record_or_hash_or_array.shift
end
+
+ namespace_keys.map {|k| "#{k}_"}.join
end
end
end
diff --git a/actionpack/lib/action_controller/rack_process.rb b/actionpack/lib/action_controller/rack_process.rb
index f42212e740..58a0a9280d 100644
--- a/actionpack/lib/action_controller/rack_process.rb
+++ b/actionpack/lib/action_controller/rack_process.rb
@@ -4,6 +4,7 @@ require 'action_controller/session/cookie_store'
module ActionController #:nodoc:
class RackRequest < AbstractRequest #:nodoc:
attr_accessor :env, :session_options
+ attr_reader :cgi
class SessionFixationAttempt < StandardError #:nodoc:
end
@@ -48,21 +49,12 @@ module ActionController #:nodoc:
def cookies
return {} unless @env["HTTP_COOKIE"]
- if @env["rack.request.cookie_string"] == @env["HTTP_COOKIE"]
- @env["rack.request.cookie_hash"]
- else
+ unless @env["rack.request.cookie_string"] == @env["HTTP_COOKIE"]
@env["rack.request.cookie_string"] = @env["HTTP_COOKIE"]
- # According to RFC 2109:
- # If multiple cookies satisfy the criteria above, they are ordered in
- # the Cookie header such that those with more specific Path attributes
- # precede those with less specific. Ordering with respect to other
- # attributes (e.g., Domain) is unspecified.
- @env["rack.request.cookie_hash"] =
- parse_query(@env["rack.request.cookie_string"], ';,').inject({}) { |h, (k,v)|
- h[k] = Array === v ? v.first : v
- h
- }
+ @env["rack.request.cookie_hash"] = CGI::Cookie::parse(@env["rack.request.cookie_string"])
end
+
+ @env["rack.request.cookie_hash"]
end
def host_with_port_without_standard_port_handling
@@ -169,37 +161,13 @@ end_msg
def session_options_with_string_keys
@session_options_with_string_keys ||= DEFAULT_SESSION_OPTIONS.merge(@session_options).stringify_keys
end
-
- # From Rack::Utils
- def parse_query(qs, d = '&;')
- params = {}
- (qs || '').split(/[#{d}] */n).inject(params) { |h,p|
- k, v = unescape(p).split('=',2)
- if cur = params[k]
- if cur.class == Array
- params[k] << v
- else
- params[k] = [cur, v]
- end
- else
- params[k] = v
- end
- }
-
- return params
- end
-
- def unescape(s)
- s.tr('+', ' ').gsub(/((?:%[0-9a-fA-F]{2})+)/n){
- [$1.delete('%')].pack('H*')
- }
- end
end
class RackResponse < AbstractResponse #:nodoc:
attr_accessor :status
- def initialize
+ def initialize(request)
+ @request = request
@writer = lambda { |x| @body << x }
@block = nil
super()
@@ -221,6 +189,8 @@ end_msg
if @body.respond_to?(:call)
@writer = lambda { |x| callback.call(x) }
@body.call(self, self)
+ elsif @body.is_a?(String)
+ @body.each_line(&callback)
else
@body.each(&callback)
end
@@ -270,9 +240,9 @@ end_msg
else cookies << cookie.to_s
end
- @output_cookies.each { |c| cookies << c.to_s } if @output_cookies
+ @request.cgi.output_cookies.each { |c| cookies << c.to_s } if @request.cgi.output_cookies
- headers['Set-Cookie'] = [headers['Set-Cookie'], cookies].compact.join("\n")
+ headers['Set-Cookie'] = [headers['Set-Cookie'], cookies].flatten.compact
end
options.each { |k,v| headers[k] = v }
@@ -283,6 +253,8 @@ end_msg
end
class CGIWrapper < ::CGI
+ attr_reader :output_cookies
+
def initialize(request, *args)
@request = request
@args = *args
diff --git a/actionpack/lib/action_controller/record_identifier.rb b/actionpack/lib/action_controller/record_identifier.rb
index 643ff7e5f4..742d290ad6 100644
--- a/actionpack/lib/action_controller/record_identifier.rb
+++ b/actionpack/lib/action_controller/record_identifier.rb
@@ -31,18 +31,21 @@ module ActionController
module RecordIdentifier
extend self
+ JOIN = '_'.freeze
+ NEW = 'new'.freeze
+
# Returns plural/singular for a record or class. Example:
#
# partial_path(post) # => "posts/post"
# partial_path(Person) # => "people/person"
# partial_path(Person, "admin/games") # => "admin/people/person"
def partial_path(record_or_class, controller_path = nil)
- klass = class_from_record_or_class(record_or_class)
+ name = model_name_from_record_or_class(record_or_class)
if controller_path && controller_path.include?("/")
- "#{File.dirname(controller_path)}/#{klass.name.tableize}/#{klass.name.demodulize.underscore}"
+ "#{File.dirname(controller_path)}/#{name.partial_path}"
else
- "#{klass.name.tableize}/#{klass.name.demodulize.underscore}"
+ name.partial_path
end
end
@@ -56,21 +59,25 @@ module ActionController
# dom_class(post, :edit) # => "edit_post"
# dom_class(Person, :edit) # => "edit_person"
def dom_class(record_or_class, prefix = nil)
- [ prefix, singular_class_name(record_or_class) ].compact * '_'
+ singular = singular_class_name(record_or_class)
+ prefix ? "#{prefix}#{JOIN}#{singular}" : singular
end
# The DOM id convention is to use the singular form of an object or class with the id following an underscore.
# If no id is found, prefix with "new_" instead. Examples:
#
- # dom_id(Post.new(:id => 45)) # => "post_45"
+ # dom_id(Post.find(45)) # => "post_45"
# dom_id(Post.new) # => "new_post"
#
# If you need to address multiple instances of the same class in the same view, you can prefix the dom_id:
#
- # dom_id(Post.new(:id => 45), :edit) # => "edit_post_45"
+ # dom_id(Post.find(45), :edit) # => "edit_post_45"
def dom_id(record, prefix = nil)
- prefix ||= 'new' unless record.id
- [ prefix, singular_class_name(record), record.id ].compact * '_'
+ if record_id = record.id
+ "#{dom_class(record, prefix)}#{JOIN}#{record_id}"
+ else
+ dom_class(record, prefix || NEW)
+ end
end
# Returns the plural class name of a record or class. Examples:
@@ -78,7 +85,7 @@ module ActionController
# plural_class_name(post) # => "posts"
# plural_class_name(Highrise::Person) # => "highrise_people"
def plural_class_name(record_or_class)
- singular_class_name(record_or_class).pluralize
+ model_name_from_record_or_class(record_or_class).plural
end
# Returns the singular class name of a record or class. Examples:
@@ -86,12 +93,12 @@ module ActionController
# singular_class_name(post) # => "post"
# singular_class_name(Highrise::Person) # => "highrise_person"
def singular_class_name(record_or_class)
- class_from_record_or_class(record_or_class).name.underscore.tr('/', '_')
+ model_name_from_record_or_class(record_or_class).singular
end
private
- def class_from_record_or_class(record_or_class)
- record_or_class.is_a?(Class) ? record_or_class : record_or_class.class
+ def model_name_from_record_or_class(record_or_class)
+ (record_or_class.is_a?(Class) ? record_or_class : record_or_class.class).model_name
end
end
-end \ No newline at end of file
+end
diff --git a/actionpack/lib/action_controller/request.rb b/actionpack/lib/action_controller/request.rb
index 914163a709..38f8e10fe7 100755
--- a/actionpack/lib/action_controller/request.rb
+++ b/actionpack/lib/action_controller/request.rb
@@ -134,14 +134,15 @@ module ActionController
# REMOTE_ADDR is a proxy. HTTP_X_FORWARDED_FOR may be a comma-
# delimited list in the case of multiple chained proxies; the last
# address which is not trusted is the originating IP.
-
def remote_ip
if TRUSTED_PROXIES !~ @env['REMOTE_ADDR']
return @env['REMOTE_ADDR']
end
+ remote_ips = @env['HTTP_X_FORWARDED_FOR'] && @env['HTTP_X_FORWARDED_FOR'].split(',')
+
if @env.include? 'HTTP_CLIENT_IP'
- if @env.include? 'HTTP_X_FORWARDED_FOR'
+ if remote_ips && !remote_ips.include?(@env['HTTP_CLIENT_IP'])
# We don't know which came from the proxy, and which from the user
raise ActionControllerError.new(<<EOM)
IP spoofing attack?!
@@ -149,11 +150,11 @@ HTTP_CLIENT_IP=#{@env['HTTP_CLIENT_IP'].inspect}
HTTP_X_FORWARDED_FOR=#{@env['HTTP_X_FORWARDED_FOR'].inspect}
EOM
end
+
return @env['HTTP_CLIENT_IP']
end
- if @env.include? 'HTTP_X_FORWARDED_FOR' then
- remote_ips = @env['HTTP_X_FORWARDED_FOR'].split(',')
+ if remote_ips
while remote_ips.size > 1 && TRUSTED_PROXIES =~ remote_ips.last.strip
remote_ips.pop
end
diff --git a/actionpack/lib/action_controller/resources.rb b/actionpack/lib/action_controller/resources.rb
index 79ec2b13b7..b11aa5625b 100644
--- a/actionpack/lib/action_controller/resources.rb
+++ b/actionpack/lib/action_controller/resources.rb
@@ -72,7 +72,7 @@ module ActionController
end
def conditions
- @conditions = @options[:conditions] || {}
+ @conditions ||= @options[:conditions] || {}
end
def path
@@ -80,9 +80,9 @@ module ActionController
end
def new_path
- new_action = self.options[:path_names][:new] if self.options[:path_names]
+ new_action = self.options[:path_names][:new] if self.options[:path_names]
new_action ||= Base.resources_path_names[:new]
- @new_path ||= "#{path}/#{new_action}"
+ @new_path ||= "#{path}/#{new_action}"
end
def member_path
diff --git a/actionpack/lib/action_controller/routing.rb b/actionpack/lib/action_controller/routing.rb
index 6aa266513d..8846dcc504 100644
--- a/actionpack/lib/action_controller/routing.rb
+++ b/actionpack/lib/action_controller/routing.rb
@@ -369,7 +369,7 @@ module ActionController
Routes = RouteSet.new
- ::Inflector.module_eval do
+ ActiveSupport::Inflector.module_eval do
# Ensures that routes are reloaded when Rails inflections are updated.
def inflections_with_route_reloading(&block)
returning(inflections_without_route_reloading(&block)) {
diff --git a/actionpack/lib/action_controller/routing/segments.rb b/actionpack/lib/action_controller/routing/segments.rb
index 864e068004..f0ad066bad 100644
--- a/actionpack/lib/action_controller/routing/segments.rb
+++ b/actionpack/lib/action_controller/routing/segments.rb
@@ -249,7 +249,7 @@ module ActionController
end
def extract_value
- "#{local_name} = hash[:#{key}] && hash[:#{key}].collect { |path_component| URI.escape(path_component.to_param, ActionController::Routing::Segment::UNSAFE_PCHAR) }.to_param #{"|| #{default.inspect}" if default}"
+ "#{local_name} = hash[:#{key}] && Array(hash[:#{key}]).collect { |path_component| URI.escape(path_component.to_param, ActionController::Routing::Segment::UNSAFE_PCHAR) }.to_param #{"|| #{default.inspect}" if default}"
end
def default
diff --git a/actionpack/lib/action_controller/templates/rescues/layout.erb b/actionpack/lib/action_controller/templates/rescues/layout.erb
index d38f3e67f9..4a04742e40 100644
--- a/actionpack/lib/action_controller/templates/rescues/layout.erb
+++ b/actionpack/lib/action_controller/templates/rescues/layout.erb
@@ -1,4 +1,4 @@
-<html>
+<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Action Controller: Exception caught</title>
<style>
diff --git a/actionpack/lib/action_controller/vendor/html-scanner/html/document.rb b/actionpack/lib/action_controller/vendor/html-scanner/html/document.rb
index 607fd186b9..b8d73c350d 100644
--- a/actionpack/lib/action_controller/vendor/html-scanner/html/document.rb
+++ b/actionpack/lib/action_controller/vendor/html-scanner/html/document.rb
@@ -17,7 +17,7 @@ module HTML #:nodoc:
@root = Node.new(nil)
node_stack = [ @root ]
while token = tokenizer.next
- node = Node.parse(node_stack.last, tokenizer.line, tokenizer.position, token)
+ node = Node.parse(node_stack.last, tokenizer.line, tokenizer.position, token, strict)
node_stack.last.children << node unless node.tag? && node.closing == :close
if node.tag?
diff --git a/actionpack/lib/action_controller/verification.rb b/actionpack/lib/action_controller/verification.rb
index 9f606e7b7c..35b12a7f13 100644
--- a/actionpack/lib/action_controller/verification.rb
+++ b/actionpack/lib/action_controller/verification.rb
@@ -116,7 +116,7 @@ module ActionController #:nodoc:
end
def apply_redirect_to(redirect_to_option) # :nodoc:
- redirect_to_option.is_a?(Symbol) ? self.send!(redirect_to_option) : redirect_to_option
+ (redirect_to_option.is_a?(Symbol) && redirect_to_option != :back) ? self.send!(redirect_to_option) : redirect_to_option
end
def apply_remaining_actions(options) # :nodoc: