aboutsummaryrefslogtreecommitdiffstats
path: root/actionpack/lib/action_controller
diff options
context:
space:
mode:
authorrick <technoweenie@gmail.com>2008-09-20 13:00:20 -0700
committerrick <technoweenie@gmail.com>2008-09-20 13:00:20 -0700
commit22e830f883af0b56de81186c184751b6398d0141 (patch)
tree0de20fad9f3a7ce2e49d660d1243b5b02a32e290 /actionpack/lib/action_controller
parent0aef9d1a2651fa0acd2adcd2de308eeb0ec8cdd2 (diff)
parenta3b7fa78bfdc33e45e39c095b67e02d50a2c7bea (diff)
downloadrails-22e830f883af0b56de81186c184751b6398d0141.tar.gz
rails-22e830f883af0b56de81186c184751b6398d0141.tar.bz2
rails-22e830f883af0b56de81186c184751b6398d0141.zip
Merge branch 'master' of git@github.com:rails/rails
Diffstat (limited to 'actionpack/lib/action_controller')
-rw-r--r--actionpack/lib/action_controller/assertions/routing_assertions.rb28
-rw-r--r--actionpack/lib/action_controller/assertions/selector_assertions.rb86
-rw-r--r--actionpack/lib/action_controller/base.rb106
-rw-r--r--actionpack/lib/action_controller/benchmarking.rb61
-rw-r--r--actionpack/lib/action_controller/caching/actions.rb8
-rw-r--r--actionpack/lib/action_controller/caching/sweeping.rb6
-rw-r--r--actionpack/lib/action_controller/cgi_process.rb9
-rw-r--r--actionpack/lib/action_controller/components.rb5
-rw-r--r--actionpack/lib/action_controller/filters.rb8
-rw-r--r--actionpack/lib/action_controller/helpers.rb4
-rw-r--r--actionpack/lib/action_controller/http_authentication.rb2
-rw-r--r--actionpack/lib/action_controller/integration.rb8
-rw-r--r--actionpack/lib/action_controller/layout.rb80
-rw-r--r--actionpack/lib/action_controller/mime_type.rb2
-rw-r--r--actionpack/lib/action_controller/polymorphic_routes.rb6
-rw-r--r--actionpack/lib/action_controller/rack_process.rb3
-rwxr-xr-x[-rw-r--r--]actionpack/lib/action_controller/request.rb77
-rw-r--r--actionpack/lib/action_controller/rescue.rb5
-rw-r--r--actionpack/lib/action_controller/resources.rb150
-rw-r--r--actionpack/lib/action_controller/response.rb2
-rw-r--r--actionpack/lib/action_controller/routing/builder.rb12
-rw-r--r--actionpack/lib/action_controller/routing/optimisations.rb5
-rw-r--r--actionpack/lib/action_controller/routing/recognition_optimisation.rb22
-rw-r--r--actionpack/lib/action_controller/routing/route.rb2
-rw-r--r--actionpack/lib/action_controller/routing/route_set.rb10
-rw-r--r--actionpack/lib/action_controller/routing/segments.rb6
-rw-r--r--actionpack/lib/action_controller/session/cookie_store.rb3
-rw-r--r--actionpack/lib/action_controller/session_management.rb8
-rw-r--r--actionpack/lib/action_controller/test_process.rb19
-rw-r--r--actionpack/lib/action_controller/translation.rb13
-rw-r--r--actionpack/lib/action_controller/verification.rb4
31 files changed, 406 insertions, 354 deletions
diff --git a/actionpack/lib/action_controller/assertions/routing_assertions.rb b/actionpack/lib/action_controller/assertions/routing_assertions.rb
index 312b4e228b..8a837c592c 100644
--- a/actionpack/lib/action_controller/assertions/routing_assertions.rb
+++ b/actionpack/lib/action_controller/assertions/routing_assertions.rb
@@ -10,32 +10,32 @@ module ActionController
# and a :method containing the required HTTP verb.
#
# # assert that POSTing to /items will call the create action on ItemsController
- # assert_recognizes({:controller => 'items', :action => 'create'}, {:path => 'items', :method => :post})
+ # assert_recognizes {:controller => 'items', :action => 'create'}, {:path => 'items', :method => :post}
#
# You can also pass in +extras+ with a hash containing URL parameters that would normally be in the query string. This can be used
# to assert that values in the query string string will end up in the params hash correctly. To test query strings you must use the
# extras argument, appending the query string on the path directly will not work. For example:
#
# # assert that a path of '/items/list/1?view=print' returns the correct options
- # assert_recognizes({:controller => 'items', :action => 'list', :id => '1', :view => 'print'}, 'items/list/1', { :view => "print" })
+ # assert_recognizes {:controller => 'items', :action => 'list', :id => '1', :view => 'print'}, 'items/list/1', { :view => "print" }
#
# The +message+ parameter allows you to pass in an error message that is displayed upon failure.
#
# ==== Examples
# # Check the default route (i.e., the index action)
- # assert_recognizes({:controller => 'items', :action => 'index'}, 'items')
+ # assert_recognizes {:controller => 'items', :action => 'index'}, 'items'
#
# # Test a specific action
- # assert_recognizes({:controller => 'items', :action => 'list'}, 'items/list')
+ # assert_recognizes {:controller => 'items', :action => 'list'}, 'items/list'
#
# # Test an action with a parameter
- # assert_recognizes({:controller => 'items', :action => 'destroy', :id => '1'}, 'items/destroy/1')
+ # assert_recognizes {:controller => 'items', :action => 'destroy', :id => '1'}, 'items/destroy/1'
#
# # Test a custom route
- # assert_recognizes({:controller => 'items', :action => 'show', :id => '1'}, 'view/item1')
+ # assert_recognizes {:controller => 'items', :action => 'show', :id => '1'}, 'view/item1'
#
# # Check a Simply RESTful generated route
- # assert_recognizes(list_items_url, 'items/list')
+ # assert_recognizes list_items_url, 'items/list'
def assert_recognizes(expected_options, path, extras={}, message=nil)
if path.is_a? Hash
request_method = path[:method]
@@ -67,13 +67,13 @@ module ActionController
#
# ==== Examples
# # Asserts that the default action is generated for a route with no action
- # assert_generates("/items", :controller => "items", :action => "index")
+ # assert_generates "/items", :controller => "items", :action => "index"
#
# # Tests that the list action is properly routed
- # assert_generates("/items/list", :controller => "items", :action => "list")
+ # assert_generates "/items/list", :controller => "items", :action => "list"
#
# # Tests the generation of a route with a parameter
- # assert_generates("/items/list/1", { :controller => "items", :action => "list", :id => "1" })
+ # assert_generates "/items/list/1", { :controller => "items", :action => "list", :id => "1" }
#
# # Asserts that the generated route gives us our custom route
# assert_generates "changesets/12", { :controller => 'scm', :action => 'show_diff', :revision => "12" }
@@ -104,19 +104,19 @@ module ActionController
#
# ==== Examples
# # Assert a basic route: a controller with the default action (index)
- # assert_routing('/home', :controller => 'home', :action => 'index')
+ # assert_routing '/home', :controller => 'home', :action => 'index'
#
# # Test a route generated with a specific controller, action, and parameter (id)
- # assert_routing('/entries/show/23', :controller => 'entries', :action => 'show', id => 23)
+ # assert_routing '/entries/show/23', :controller => 'entries', :action => 'show', id => 23
#
# # Assert a basic route (controller + default action), with an error message if it fails
- # assert_routing('/store', { :controller => 'store', :action => 'index' }, {}, {}, 'Route for store index not generated properly')
+ # assert_routing '/store', { :controller => 'store', :action => 'index' }, {}, {}, 'Route for store index not generated properly'
#
# # Tests a route, providing a defaults hash
# assert_routing 'controller/action/9', {:id => "9", :item => "square"}, {:controller => "controller", :action => "action"}, {}, {:item => "square"}
#
# # Tests a route with a HTTP method
- # assert_routing({ :method => 'put', :path => '/product/321' }, { :controller => "product", :action => "update", :id => "321" })
+ # assert_routing { :method => 'put', :path => '/product/321' }, { :controller => "product", :action => "update", :id => "321" }
def assert_routing(path, options, defaults={}, extras={}, message=nil)
assert_recognizes(options, path, extras, message)
diff --git a/actionpack/lib/action_controller/assertions/selector_assertions.rb b/actionpack/lib/action_controller/assertions/selector_assertions.rb
index 9114894b1d..bcbb570e4b 100644
--- a/actionpack/lib/action_controller/assertions/selector_assertions.rb
+++ b/actionpack/lib/action_controller/assertions/selector_assertions.rb
@@ -396,54 +396,31 @@ module ActionController
# # The same, but shorter.
# assert_select "ol>li", 4
def assert_select_rjs(*args, &block)
- rjs_type = nil
- arg = args.shift
+ rjs_type = args.first.is_a?(Symbol) ? args.shift : nil
+ id = args.first.is_a?(String) ? args.shift : nil
# If the first argument is a symbol, it's the type of RJS statement we're looking
# for (update, replace, insertion, etc). Otherwise, we're looking for just about
# any RJS statement.
- if arg.is_a?(Symbol)
- rjs_type = arg
-
+ if rjs_type
if rjs_type == :insert
- arg = args.shift
- position = arg
- insertion = "insert_#{arg}".to_sym
- raise ArgumentError, "Unknown RJS insertion type #{arg}" unless RJS_STATEMENTS[insertion]
+ position = args.shift
+ insertion = "insert_#{position}".to_sym
+ raise ArgumentError, "Unknown RJS insertion type #{position}" unless RJS_STATEMENTS[insertion]
statement = "(#{RJS_STATEMENTS[insertion]})"
else
raise ArgumentError, "Unknown RJS statement type #{rjs_type}" unless RJS_STATEMENTS[rjs_type]
statement = "(#{RJS_STATEMENTS[rjs_type]})"
end
- arg = args.shift
else
statement = "#{RJS_STATEMENTS[:any]}"
end
- position ||= Regexp.new(RJS_INSERTIONS.join('|'))
# Next argument we're looking for is the element identifier. If missing, we pick
- # any element.
- if arg.is_a?(String)
- id = Regexp.quote(arg)
- arg = args.shift
- else
- id = "[^\"]*"
- end
-
- pattern =
- case rjs_type
- when :chained_replace, :chained_replace_html
- Regexp.new("\\$\\(\"#{id}\"\\)#{statement}\\(#{RJS_PATTERN_HTML}\\)", Regexp::MULTILINE)
- when :remove, :show, :hide, :toggle
- Regexp.new("#{statement}\\(\"#{id}\"\\)")
- when :replace, :replace_html
- Regexp.new("#{statement}\\(\"#{id}\", #{RJS_PATTERN_HTML}\\)")
- when :insert, :insert_html
- Regexp.new("Element.insert\\(\\\"#{id}\\\", \\{ #{position}: #{RJS_PATTERN_HTML} \\}\\);")
- else
- Regexp.union(Regexp.new("#{statement}\\(\"#{id}\", #{RJS_PATTERN_HTML}\\)"),
- Regexp.new("Element.insert\\(\\\"#{id}\\\", \\{ #{position}: #{RJS_PATTERN_HTML} \\}\\);"))
- end
+ # any element, otherwise we replace it in the statement.
+ pattern = Regexp.new(
+ id ? statement.gsub(RJS_ANY_ID, "\"#{id}\"") : statement
+ )
# Duplicate the body since the next step involves destroying it.
matches = nil
@@ -472,7 +449,13 @@ module ActionController
matches
else
# RJS statement not found.
- flunk args.shift || "No RJS statement that replaces or inserts HTML content."
+ case rjs_type
+ when :remove, :show, :hide, :toggle
+ flunk_message = "No RJS statement that #{rjs_type.to_s}s '#{id}' was rendered."
+ else
+ flunk_message = "No RJS statement that replaces or inserts HTML content."
+ end
+ flunk args.shift || flunk_message
end
end
@@ -582,26 +565,23 @@ module ActionController
protected
unless const_defined?(:RJS_STATEMENTS)
- RJS_STATEMENTS = {
- :replace => /Element\.replace/,
- :replace_html => /Element\.update/,
- :chained_replace => /\.replace/,
- :chained_replace_html => /\.update/,
- :remove => /Element\.remove/,
- :show => /Element\.show/,
- :hide => /Element\.hide/,
- :toggle => /Element\.toggle/
+ RJS_PATTERN_HTML = "\"((\\\\\"|[^\"])*)\""
+ RJS_ANY_ID = "\"([^\"])*\""
+ RJS_STATEMENTS = {
+ :chained_replace => "\\$\\(#{RJS_ANY_ID}\\)\\.replace\\(#{RJS_PATTERN_HTML}\\)",
+ :chained_replace_html => "\\$\\(#{RJS_ANY_ID}\\)\\.update\\(#{RJS_PATTERN_HTML}\\)",
+ :replace_html => "Element\\.update\\(#{RJS_ANY_ID}, #{RJS_PATTERN_HTML}\\)",
+ :replace => "Element\\.replace\\(#{RJS_ANY_ID}, #{RJS_PATTERN_HTML}\\)"
}
- RJS_STATEMENTS[:any] = Regexp.new("(#{RJS_STATEMENTS.values.join('|')})")
- RJS_PATTERN_HTML = /"((\\"|[^"])*)"/
- RJS_INSERTIONS = [:top, :bottom, :before, :after]
+ [:remove, :show, :hide, :toggle].each do |action|
+ RJS_STATEMENTS[action] = "Element\\.#{action}\\(#{RJS_ANY_ID}\\)"
+ end
+ RJS_INSERTIONS = ["top", "bottom", "before", "after"]
RJS_INSERTIONS.each do |insertion|
- RJS_STATEMENTS["insert_#{insertion}".to_sym] = /Element.insert\(\"([^\"]*)\", \{ #{insertion.to_s.downcase}: #{RJS_PATTERN_HTML} \}\);/
+ RJS_STATEMENTS["insert_#{insertion}".to_sym] = "Element.insert\\(#{RJS_ANY_ID}, \\{ #{insertion}: #{RJS_PATTERN_HTML} \\}\\)"
end
- RJS_STATEMENTS[:insert_html] = Regexp.new(RJS_INSERTIONS.collect do |insertion|
- /Element.insert\(\"([^\"]*)\", \{ #{insertion.to_s.downcase}: #{RJS_PATTERN_HTML} \}\);/
- end.join('|'))
- RJS_PATTERN_EVERYTHING = Regexp.new("#{RJS_STATEMENTS[:any]}\\(\"([^\"]*)\", #{RJS_PATTERN_HTML}\\)", Regexp::MULTILINE)
+ RJS_STATEMENTS[:insert_html] = "Element.insert\\(#{RJS_ANY_ID}, \\{ (#{RJS_INSERTIONS.join('|')}): #{RJS_PATTERN_HTML} \\}\\)"
+ RJS_STATEMENTS[:any] = Regexp.new("(#{RJS_STATEMENTS.values.join('|')})")
RJS_PATTERN_UNICODE_ESCAPED_CHAR = /\\u([0-9a-zA-Z]{4})/
end
@@ -615,8 +595,8 @@ module ActionController
root = HTML::Node.new(nil)
while true
- next if body.sub!(RJS_PATTERN_EVERYTHING) do |match|
- html = unescape_rjs($3)
+ next if body.sub!(RJS_STATEMENTS[:any]) do |match|
+ html = unescape_rjs(match)
matches = HTML::Document.new(html).root.children.select { |n| n.tag? }
root.children.concat matches
""
diff --git a/actionpack/lib/action_controller/base.rb b/actionpack/lib/action_controller/base.rb
index 91023cd774..457b9e85bc 100644
--- a/actionpack/lib/action_controller/base.rb
+++ b/actionpack/lib/action_controller/base.rb
@@ -260,10 +260,11 @@ module ActionController #:nodoc:
include StatusCodes
+ cattr_reader :protected_instance_variables
# Controller specific instance variables which will not be accessible inside views.
- @@protected_view_variables = %w(@assigns @performed_redirect @performed_render @variables_added @request_origin @url @parent_controller
- @action_name @before_filter_chain_aborted @action_cache_path @_session @_cookies @_headers @_params
- @_flash @_response)
+ @@protected_instance_variables = %w(@assigns @performed_redirect @performed_render @variables_added @request_origin @url @parent_controller
+ @action_name @before_filter_chain_aborted @action_cache_path @_session @_cookies @_headers @_params
+ @_flash @_response)
# Prepends all the URL-generating helpers from AssetHelper. This makes it possible to easily move javascripts, stylesheets,
# and images to a dedicated asset server away from the main web server. Example:
@@ -393,16 +394,9 @@ module ActionController #:nodoc:
# directive. Values should always be specified as strings.
attr_internal :headers
- # Holds the hash of variables that are passed on to the template class to be made available to the view. This hash
- # is generated by taking a snapshot of all the instance variables in the current scope just before a template is rendered.
- attr_accessor :assigns
-
# Returns the name of the action this controller is processing.
attr_accessor :action_name
- # Templates that are exempt from layouts
- @@exempt_from_layout = Set.new([/\.rjs$/])
-
class << self
# Factory for the standard create, process loop where the controller is discarded after processing.
def process(request, response) #:nodoc:
@@ -440,7 +434,11 @@ module ActionController #:nodoc:
# render("test/template") will be looked up in the view load paths array and the closest match will be
# returned.
def view_paths
- @view_paths || superclass.view_paths
+ if defined? @view_paths
+ @view_paths
+ else
+ superclass.view_paths
+ end
end
def view_paths=(value)
@@ -455,7 +453,7 @@ module ActionController #:nodoc:
# ArticleController.prepend_view_path(["views/default", "views/custom"])
#
def prepend_view_path(path)
- @view_paths = superclass.view_paths.dup if @view_paths.nil?
+ @view_paths = superclass.view_paths.dup if !defined?(@view_paths) || @view_paths.nil?
@view_paths.unshift(*path)
end
@@ -520,13 +518,7 @@ module ActionController #:nodoc:
protected :filter_parameters
end
- # Don't render layouts for templates with the given extensions.
- def exempt_from_layout(*extensions)
- regexps = extensions.collect do |extension|
- extension.is_a?(Regexp) ? extension : /\.#{Regexp.escape(extension.to_s)}$/
- end
- @@exempt_from_layout.merge regexps
- end
+ delegate :exempt_from_layout, :to => 'ActionView::Base'
end
public
@@ -538,7 +530,6 @@ module ActionController #:nodoc:
assign_shortcuts(request, response)
initialize_current_url
assign_names
- forget_variables_added_to_assigns
log_processing
@@ -548,12 +539,16 @@ module ActionController #:nodoc:
@@guard.synchronize { send(method, *arguments) }
end
- response.prepare! unless component_request?
- response
+ send_response
ensure
process_cleanup
end
+ def send_response
+ response.prepare! unless component_request?
+ response
+ end
+
# Returns a URL that has been rewritten according to the options hash and the defined Routes.
# (For doing a complete redirect, use redirect_to).
#
@@ -859,7 +854,7 @@ module ActionController #:nodoc:
raise DoubleRenderError, "Can only render or redirect once per action" if performed?
if options.nil?
- return render_for_file(default_template_name, nil, true)
+ return render(:file => default_template_name, :layout => true)
elsif !extra_options.is_a?(Hash)
raise RenderError, "You called render with invalid options : #{options.inspect}, #{extra_options.inspect}"
else
@@ -870,6 +865,9 @@ module ActionController #:nodoc:
end
end
+ response.layout = layout = pick_layout(options)
+ logger.info("Rendering template within #{layout}") if logger && layout
+
if content_type = options[:content_type]
response.content_type = content_type.to_s
end
@@ -879,26 +877,21 @@ module ActionController #:nodoc:
end
if options.has_key?(:text)
- render_for_text(options[:text], options[:status])
+ text = layout ? @template.render(options.merge(:text => options[:text], :layout => layout)) : options[:text]
+ render_for_text(text, options[:status])
else
if file = options[:file]
- render_for_file(file, options[:status], nil, options[:locals] || {})
+ render_for_file(file, options[:status], layout, options[:locals] || {})
elsif template = options[:template]
- render_for_file(template, options[:status], true, options[:locals] || {})
+ render_for_file(template, options[:status], layout, options[:locals] || {})
elsif inline = options[:inline]
- add_variables_to_assigns
- render_for_text(@template.render(options), options[:status])
+ render_for_text(@template.render(options.merge(:layout => layout)), options[:status])
elsif action_name = options[:action]
- template = default_template_name(action_name.to_s)
- if options[:layout] && !template_exempt_from_layout?(template)
- render_with_a_layout(:file => template, :status => options[:status], :layout => true)
- else
- render_with_no_layout(:file => template, :status => options[:status])
- end
+ render_for_file(default_template_name(action_name.to_s), options[:status], layout)
elsif xml = options[:xml]
response.content_type ||= Mime::XML
@@ -912,12 +905,14 @@ module ActionController #:nodoc:
elsif options[:partial]
options[:partial] = default_template_name if options[:partial] == true
- add_variables_to_assigns
- render_for_text(@template.render(options), options[:status])
+ if layout
+ render_for_text(@template.render(:text => @template.render(options), :layout => layout), options[:status])
+ else
+ render_for_text(@template.render(options), options[:status])
+ end
elsif options[:update]
- add_variables_to_assigns
- @template.send! :evaluate_assigns
+ @template.send(:_evaluate_assigns_and_ivars)
generator = ActionView::Helpers::PrototypeHelper::JavaScriptGenerator.new(@template, &block)
response.content_type = Mime::JS
@@ -927,7 +922,7 @@ module ActionController #:nodoc:
render_for_text(nil, options[:status])
else
- render_for_file(default_template_name, options[:status], true)
+ render_for_file(default_template_name, options[:status], layout)
end
end
end
@@ -938,7 +933,6 @@ module ActionController #:nodoc:
render(options, &block)
ensure
erase_render_results
- forget_variables_added_to_assigns
reset_variables_added_to_assigns
end
@@ -1123,10 +1117,9 @@ module ActionController #:nodoc:
private
- def render_for_file(template_path, status = nil, use_full_path = nil, locals = {}) #:nodoc:
- add_variables_to_assigns
+ def render_for_file(template_path, status = nil, layout = nil, locals = {}) #:nodoc:
logger.info("Rendering #{template_path}" + (status ? " (#{status})" : '')) if logger
- render_for_text(@template.render(:file => template_path, :locals => locals), status)
+ render_for_text @template.render(:file => template_path, :locals => locals, :layout => layout), status
end
def render_for_text(text = nil, status = nil, append_response = false) #:nodoc:
@@ -1148,7 +1141,7 @@ module ActionController #:nodoc:
def initialize_template_class(response)
response.template = ActionView::Base.new(self.class.view_paths, {}, self)
- response.template.extend self.class.master_helper_module
+ response.template.helpers.send :include, self.class.master_helper_module
response.redirected_to = nil
@performed_render = @performed_redirect = false
end
@@ -1161,7 +1154,6 @@ module ActionController #:nodoc:
@_session = @_response.session
@template = @_response.template
- @assigns = @_response.template.assigns
@_headers = @_response.headers
end
@@ -1225,27 +1217,10 @@ module ActionController #:nodoc:
hidden_actions
end
- def add_variables_to_assigns
- unless @variables_added
- add_instance_variables_to_assigns
- @variables_added = true
- end
- end
-
- def forget_variables_added_to_assigns
- @variables_added = nil
- end
-
def reset_variables_added_to_assigns
@template.instance_variable_set("@assigns_added", nil)
end
- def add_instance_variables_to_assigns
- (instance_variable_names - @@protected_view_variables).each do |var|
- @assigns[var[1..-1]] = instance_variable_get(var)
- end
- end
-
def request_origin
# this *needs* to be cached!
# otherwise you'd get different results if calling it more than once
@@ -1261,12 +1236,7 @@ module ActionController #:nodoc:
end
def template_exists?(template_name = default_template_name)
- @template.file_exists?(template_name)
- end
-
- def template_exempt_from_layout?(template_name = default_template_name)
- template_name = @template.pick_template(template_name).to_s if @template
- @@exempt_from_layout.any? { |ext| template_name =~ ext }
+ @template.send(:_pick_template, template_name) ? true : false
rescue ActionView::MissingTemplate
false
end
diff --git a/actionpack/lib/action_controller/benchmarking.rb b/actionpack/lib/action_controller/benchmarking.rb
index 98b0325ba3..fa572ebf3d 100644
--- a/actionpack/lib/action_controller/benchmarking.rb
+++ b/actionpack/lib/action_controller/benchmarking.rb
@@ -24,7 +24,7 @@ module ActionController #:nodoc:
if logger && logger.level == log_level
result = nil
seconds = Benchmark.realtime { result = use_silence ? silence { yield } : yield }
- logger.add(log_level, "#{title} (#{'%.5f' % seconds})")
+ logger.add(log_level, "#{title} (#{('%.1f' % (seconds * 1000))}ms)")
result
else
yield
@@ -42,53 +42,66 @@ module ActionController #:nodoc:
protected
def render_with_benchmark(options = nil, extra_options = {}, &block)
- unless logger
- render_without_benchmark(options, extra_options, &block)
- else
- db_runtime = ActiveRecord::Base.connection.reset_runtime if Object.const_defined?("ActiveRecord") && ActiveRecord::Base.connected?
+ if logger
+ if Object.const_defined?("ActiveRecord") && ActiveRecord::Base.connected?
+ db_runtime = ActiveRecord::Base.connection.reset_runtime
+ end
render_output = nil
- @rendering_runtime = Benchmark::realtime{ render_output = render_without_benchmark(options, extra_options, &block) }
+ @view_runtime = Benchmark::realtime { render_output = render_without_benchmark(options, extra_options, &block) }
if Object.const_defined?("ActiveRecord") && ActiveRecord::Base.connected?
@db_rt_before_render = db_runtime
@db_rt_after_render = ActiveRecord::Base.connection.reset_runtime
- @rendering_runtime -= @db_rt_after_render
+ @view_runtime -= @db_rt_after_render
end
render_output
+ else
+ render_without_benchmark(options, extra_options, &block)
end
end
private
def perform_action_with_benchmark
- unless logger
- perform_action_without_benchmark
- else
- runtime = [ Benchmark::measure{ perform_action_without_benchmark }.real, 0.0001 ].max
+ if logger
+ seconds = [ Benchmark::measure{ perform_action_without_benchmark }.real, 0.0001 ].max
+ logging_view = defined?(@view_runtime)
+ logging_active_record = Object.const_defined?("ActiveRecord") && ActiveRecord::Base.connected?
+
+ log_message = "Completed in #{sprintf("%.0f", seconds * 1000)}ms"
+
+ if logging_view || logging_active_record
+ log_message << " ("
+ log_message << view_runtime if logging_view
+
+ if logging_active_record
+ log_message << ", " if logging_view
+ log_message << active_record_runtime + ")"
+ else
+ ")"
+ end
+ end
- log_message = "Completed in #{sprintf("%.5f", runtime)} (#{(1 / runtime).floor} reqs/sec)"
- log_message << rendering_runtime(runtime) if defined?(@rendering_runtime)
- log_message << active_record_runtime(runtime) if Object.const_defined?("ActiveRecord") && ActiveRecord::Base.connected?
log_message << " | #{headers["Status"]}"
log_message << " [#{complete_request_uri rescue "unknown"}]"
logger.info(log_message)
- response.headers["X-Runtime"] = sprintf("%.5f", runtime)
+ response.headers["X-Runtime"] = "#{sprintf("%.0f", seconds * 1000)}ms"
+ else
+ perform_action_without_benchmark
end
end
- def rendering_runtime(runtime)
- percentage = @rendering_runtime * 100 / runtime
- " | Rendering: %.5f (%d%%)" % [@rendering_runtime, percentage.to_i]
+ def view_runtime
+ "View: %.0f" % (@view_runtime * 1000)
end
- def active_record_runtime(runtime)
- db_runtime = ActiveRecord::Base.connection.reset_runtime
- db_runtime += @db_rt_before_render if @db_rt_before_render
- db_runtime += @db_rt_after_render if @db_rt_after_render
- db_percentage = db_runtime * 100 / runtime
- " | DB: %.5f (%d%%)" % [db_runtime, db_percentage.to_i]
+ def active_record_runtime
+ db_runtime = ActiveRecord::Base.connection.reset_runtime
+ db_runtime += @db_rt_before_render if @db_rt_before_render
+ db_runtime += @db_rt_after_render if @db_rt_after_render
+ "DB: %.0f" % (db_runtime * 1000)
end
end
end
diff --git a/actionpack/lib/action_controller/caching/actions.rb b/actionpack/lib/action_controller/caching/actions.rb
index f3535f8330..7c803a9830 100644
--- a/actionpack/lib/action_controller/caching/actions.rb
+++ b/actionpack/lib/action_controller/caching/actions.rb
@@ -38,8 +38,8 @@ module ActionController #:nodoc:
# caches_action :show, :cache_path => { :project => 1 }, :expires_in => 1.hour
# caches_action :feed, :cache_path => Proc.new { |controller|
# controller.params[:user_id] ?
- # controller.send(:user_list_url, c.params[:user_id], c.params[:id]) :
- # controller.send(:list_url, c.params[:id]) }
+ # controller.send(:user_list_url, controller.params[:user_id], controller.params[:id]) :
+ # controller.send(:list_url, controller.params[:id]) }
# end
#
# If you pass :layout => false, it will only cache your action content. It is useful when your layout has dynamic information.
@@ -90,7 +90,7 @@ module ActionController #:nodoc:
set_content_type!(controller, cache_path.extension)
options = { :text => cache }
options.merge!(:layout => true) if cache_layout?
- controller.send!(:render, options)
+ controller.__send__(:render, options)
false
else
controller.action_cache_path = cache_path
@@ -121,7 +121,7 @@ module ActionController #:nodoc:
end
def content_for_layout(controller)
- controller.response.layout && controller.response.template.instance_variable_get('@content_for_layout')
+ controller.response.layout && controller.response.template.instance_variable_get('@cached_content_for_layout')
end
end
diff --git a/actionpack/lib/action_controller/caching/sweeping.rb b/actionpack/lib/action_controller/caching/sweeping.rb
index 61559e9ec7..c7992d7769 100644
--- a/actionpack/lib/action_controller/caching/sweeping.rb
+++ b/actionpack/lib/action_controller/caching/sweeping.rb
@@ -83,13 +83,13 @@ module ActionController #:nodoc:
controller_callback_method_name = "#{timing}_#{controller.controller_name.underscore}"
action_callback_method_name = "#{controller_callback_method_name}_#{controller.action_name}"
- send!(controller_callback_method_name) if respond_to?(controller_callback_method_name, true)
- send!(action_callback_method_name) if respond_to?(action_callback_method_name, true)
+ __send__(controller_callback_method_name) if respond_to?(controller_callback_method_name, true)
+ __send__(action_callback_method_name) if respond_to?(action_callback_method_name, true)
end
def method_missing(method, *arguments)
return if @controller.nil?
- @controller.send!(method, *arguments)
+ @controller.__send__(method, *arguments)
end
end
end
diff --git a/actionpack/lib/action_controller/cgi_process.rb b/actionpack/lib/action_controller/cgi_process.rb
index 0ca27b30db..fabacd9b83 100644
--- a/actionpack/lib/action_controller/cgi_process.rb
+++ b/actionpack/lib/action_controller/cgi_process.rb
@@ -42,13 +42,14 @@ module ActionController #:nodoc:
:prefix => "ruby_sess.", # prefix session file names
:session_path => "/", # available to all paths in app
:session_key => "_session_id",
- :cookie_only => true
+ :cookie_only => true,
+ :session_http_only=> true
}
def initialize(cgi, session_options = {})
@cgi = cgi
@session_options = session_options
- @env = @cgi.send!(:env_table)
+ @env = @cgi.__send__(:env_table)
super()
end
@@ -107,7 +108,7 @@ module ActionController #:nodoc:
end
def method_missing(method_id, *arguments)
- @cgi.send!(method_id, *arguments) rescue super
+ @cgi.__send__(method_id, *arguments) rescue super
end
private
@@ -164,7 +165,7 @@ end_msg
begin
output.write(@cgi.header(@headers))
- if @cgi.send!(:env_table)['REQUEST_METHOD'] == 'HEAD'
+ if @cgi.__send__(:env_table)['REQUEST_METHOD'] == 'HEAD'
return
elsif @body.respond_to?(:call)
# Flush the output now in case the @body Proc uses
diff --git a/actionpack/lib/action_controller/components.rb b/actionpack/lib/action_controller/components.rb
index 8275bd380a..f446b91e7e 100644
--- a/actionpack/lib/action_controller/components.rb
+++ b/actionpack/lib/action_controller/components.rb
@@ -38,6 +38,7 @@ module ActionController #:nodoc:
def self.included(base) #:nodoc:
base.class_eval do
include InstanceMethods
+ include ActiveSupport::Deprecation
extend ClassMethods
helper HelperMethods
@@ -64,7 +65,7 @@ module ActionController #:nodoc:
module HelperMethods
def render_component(options)
- @controller.send!(:render_component_as_string, options)
+ @controller.__send__(:render_component_as_string, options)
end
end
@@ -82,6 +83,7 @@ module ActionController #:nodoc:
render_for_text(component_response(options, true).body, response.headers["Status"])
end
end
+ deprecate :render_component => "Please install render_component plugin from http://github.com/rails/render_component/tree/master"
# Returns the component response as a string
def render_component_as_string(options) #:doc:
@@ -95,6 +97,7 @@ module ActionController #:nodoc:
end
end
end
+ deprecate :render_component_as_string => "Please install render_component plugin from http://github.com/rails/render_component/tree/master"
def flash_with_components(refresh = false) #:nodoc:
if !defined?(@_flash) || refresh
diff --git a/actionpack/lib/action_controller/filters.rb b/actionpack/lib/action_controller/filters.rb
index 1d7236f18a..9022b8b279 100644
--- a/actionpack/lib/action_controller/filters.rb
+++ b/actionpack/lib/action_controller/filters.rb
@@ -199,8 +199,8 @@ module ActionController #:nodoc:
Proc.new do |controller, action|
method.before(controller)
- if controller.send!(:performed?)
- controller.send!(:halt_filter_chain, method, :rendered_or_redirected)
+ if controller.__send__(:performed?)
+ controller.__send__(:halt_filter_chain, method, :rendered_or_redirected)
else
begin
action.call
@@ -223,8 +223,8 @@ module ActionController #:nodoc:
def call(controller, &block)
super
- if controller.send!(:performed?)
- controller.send!(:halt_filter_chain, method, :rendered_or_redirected)
+ if controller.__send__(:performed?)
+ controller.__send__(:halt_filter_chain, method, :rendered_or_redirected)
end
end
end
diff --git a/actionpack/lib/action_controller/helpers.rb b/actionpack/lib/action_controller/helpers.rb
index ce5e8be54c..9cffa07b26 100644
--- a/actionpack/lib/action_controller/helpers.rb
+++ b/actionpack/lib/action_controller/helpers.rb
@@ -204,8 +204,8 @@ module ActionController #:nodoc:
begin
child.master_helper_module = Module.new
- child.master_helper_module.send! :include, master_helper_module
- child.send! :default_helper_module!
+ child.master_helper_module.__send__ :include, master_helper_module
+ child.__send__ :default_helper_module!
rescue MissingSourceFile => e
raise unless e.is_missing?("helpers/#{child.controller_path}_helper")
end
diff --git a/actionpack/lib/action_controller/http_authentication.rb b/actionpack/lib/action_controller/http_authentication.rb
index 31db012ef2..2ed810db7d 100644
--- a/actionpack/lib/action_controller/http_authentication.rb
+++ b/actionpack/lib/action_controller/http_authentication.rb
@@ -117,7 +117,7 @@ module ActionController
def authentication_request(controller, realm)
controller.headers["WWW-Authenticate"] = %(Basic realm="#{realm.gsub(/"/, "")}")
- controller.send! :render, :text => "HTTP Basic: Access denied.\n", :status => :unauthorized
+ controller.__send__ :render, :text => "HTTP Basic: Access denied.\n", :status => :unauthorized
end
end
end
diff --git a/actionpack/lib/action_controller/integration.rb b/actionpack/lib/action_controller/integration.rb
index 198a22e8dc..a98c1af7f9 100644
--- a/actionpack/lib/action_controller/integration.rb
+++ b/actionpack/lib/action_controller/integration.rb
@@ -444,7 +444,7 @@ EOF
reset! unless @integration_session
# reset the html_document variable, but only for new get/post calls
@html_document = nil unless %w(cookies assigns).include?(method)
- returning @integration_session.send!(method, *args) do
+ returning @integration_session.__send__(method, *args) do
copy_session_variables!
end
end
@@ -469,12 +469,12 @@ EOF
self.class.fixture_table_names.each do |table_name|
name = table_name.tr(".", "_")
next unless respond_to?(name)
- extras.send!(:define_method, name) { |*args| delegate.send(name, *args) }
+ extras.__send__(:define_method, name) { |*args| delegate.send(name, *args) }
end
end
# delegate add_assertion to the test case
- extras.send!(:define_method, :add_assertion) { test_result.add_assertion }
+ extras.__send__(:define_method, :add_assertion) { test_result.add_assertion }
session.extend(extras)
session.delegate = self
session.test_result = @_result
@@ -488,7 +488,7 @@ EOF
def copy_session_variables! #:nodoc:
return unless @integration_session
%w(controller response request).each do |var|
- instance_variable_set("@#{var}", @integration_session.send!(var))
+ instance_variable_set("@#{var}", @integration_session.__send__(var))
end
end
diff --git a/actionpack/lib/action_controller/layout.rb b/actionpack/lib/action_controller/layout.rb
index 8b6febe254..3631ce86af 100644
--- a/actionpack/lib/action_controller/layout.rb
+++ b/actionpack/lib/action_controller/layout.rb
@@ -3,11 +3,6 @@ module ActionController #:nodoc:
def self.included(base)
base.extend(ClassMethods)
base.class_eval do
- # NOTE: Can't use alias_method_chain here because +render_without_layout+ is already
- # defined as a publicly exposed method
- alias_method :render_with_no_layout, :render
- alias_method :render, :render_with_a_layout
-
class << self
alias_method_chain :inherited, :layout
end
@@ -169,17 +164,17 @@ module ActionController #:nodoc:
# performance and have access to them as any normal template would.
def layout(template_name, conditions = {}, auto = false)
add_layout_conditions(conditions)
- write_inheritable_attribute "layout", template_name
- write_inheritable_attribute "auto_layout", auto
+ write_inheritable_attribute(:layout, template_name)
+ write_inheritable_attribute(:auto_layout, auto)
end
def layout_conditions #:nodoc:
- @layout_conditions ||= read_inheritable_attribute("layout_conditions")
+ @layout_conditions ||= read_inheritable_attribute(:layout_conditions)
end
def default_layout(format) #:nodoc:
- layout = read_inheritable_attribute("layout")
- return layout unless read_inheritable_attribute("auto_layout")
+ layout = read_inheritable_attribute(:layout)
+ return layout unless read_inheritable_attribute(:auto_layout)
@default_layout ||= {}
@default_layout[format] ||= default_layout_with_format(format, layout)
@default_layout[format]
@@ -199,7 +194,7 @@ module ActionController #:nodoc:
end
def add_layout_conditions(conditions)
- write_inheritable_hash "layout_conditions", normalize_conditions(conditions)
+ write_inheritable_hash(:layout_conditions, normalize_conditions(conditions))
end
def normalize_conditions(conditions)
@@ -221,10 +216,10 @@ module ActionController #:nodoc:
# object). If the layout was defined without a directory, layouts is assumed. So <tt>layout "weblog/standard"</tt> will return
# weblog/standard, but <tt>layout "standard"</tt> will return layouts/standard.
def active_layout(passed_layout = nil)
- layout = passed_layout || self.class.default_layout(response.template.template_format)
+ layout = passed_layout || self.class.default_layout(default_template_format)
active_layout = case layout
when String then layout
- when Symbol then send!(layout)
+ when Symbol then __send__(layout)
when Proc then layout.call(self)
end
@@ -240,51 +235,24 @@ module ActionController #:nodoc:
end
end
- protected
- def render_with_a_layout(options = nil, extra_options = {}, &block) #:nodoc:
- template_with_options = options.is_a?(Hash)
-
- if (layout = pick_layout(template_with_options, options)) && apply_layout?(template_with_options, options)
- options = options.merge :layout => false if template_with_options
- logger.info("Rendering template within #{layout}") if logger
-
- content_for_layout = render_with_no_layout(options, extra_options, &block)
- erase_render_results
- add_variables_to_assigns
- @template.instance_variable_set("@content_for_layout", content_for_layout)
- response.layout = layout
- status = template_with_options ? options[:status] : nil
- render_for_text(@template.render(layout), status)
- else
- render_with_no_layout(options, extra_options, &block)
- end
- end
-
-
private
- def apply_layout?(template_with_options, options)
- return false if options == :update
- template_with_options ? candidate_for_layout?(options) : !template_exempt_from_layout?
- end
-
def candidate_for_layout?(options)
- (options.has_key?(:layout) && options[:layout] != false) ||
- options.values_at(:text, :xml, :json, :file, :inline, :partial, :nothing).compact.empty? &&
- !template_exempt_from_layout?(options[:template] || default_template_name(options[:action]))
+ options.values_at(:text, :xml, :json, :file, :inline, :partial, :nothing, :update).compact.empty? &&
+ !@template.__send__(:_exempt_from_layout?, options[:template] || default_template_name(options[:action]))
end
- def pick_layout(template_with_options, options)
- if template_with_options
- case layout = options[:layout]
- when FalseClass
- nil
- when NilClass, TrueClass
- active_layout if action_has_layout?
- else
- active_layout(layout)
+ def pick_layout(options)
+ if options.has_key?(:layout)
+ case layout = options.delete(:layout)
+ when FalseClass
+ nil
+ when NilClass, TrueClass
+ active_layout if action_has_layout? && !@template.__send__(:_exempt_from_layout?, default_template_name)
+ else
+ active_layout(layout)
end
else
- active_layout if action_has_layout?
+ active_layout if action_has_layout? && candidate_for_layout?(options)
end
end
@@ -304,7 +272,13 @@ module ActionController #:nodoc:
end
def layout_directory?(layout_name)
- @template.file_exists?("#{File.join('layouts', layout_name)}.#{@template.template_format}")
+ @template.__send__(:_pick_template, "#{File.join('layouts', layout_name)}.#{@template.template_format}") ? true : false
+ rescue ActionView::MissingTemplate
+ false
+ end
+
+ def default_template_format
+ response.template.template_format
end
end
end
diff --git a/actionpack/lib/action_controller/mime_type.rb b/actionpack/lib/action_controller/mime_type.rb
index a7215e6ea3..26edca3b69 100644
--- a/actionpack/lib/action_controller/mime_type.rb
+++ b/actionpack/lib/action_controller/mime_type.rb
@@ -1,3 +1,5 @@
+require 'set'
+
module Mime
SET = []
EXTENSION_LOOKUP = Hash.new { |h, k| h[k] = Type.new(k) unless k.blank? }
diff --git a/actionpack/lib/action_controller/polymorphic_routes.rb b/actionpack/lib/action_controller/polymorphic_routes.rb
index 30564c7bb3..cc228c4230 100644
--- a/actionpack/lib/action_controller/polymorphic_routes.rb
+++ b/actionpack/lib/action_controller/polymorphic_routes.rb
@@ -108,7 +108,7 @@ module ActionController
args.last.kind_of?(Hash) ? args.last.merge!(url_options) : args << url_options
end
- send!(named_route, *args)
+ __send__(named_route, *args)
end
# Returns the path component of a URL for the given record. It uses
@@ -149,7 +149,7 @@ module ActionController
if parent.is_a?(Symbol) || parent.is_a?(String)
string << "#{parent}_"
else
- string << "#{RecordIdentifier.send!("singular_class_name", parent)}_"
+ string << "#{RecordIdentifier.__send__("singular_class_name", parent)}_"
end
end
end
@@ -157,7 +157,7 @@ module ActionController
if record.is_a?(Symbol) || record.is_a?(String)
route << "#{record}_"
else
- route << "#{RecordIdentifier.send!("#{inflection}_class_name", record)}_"
+ route << "#{RecordIdentifier.__send__("#{inflection}_class_name", record)}_"
end
action_prefix(options) + namespace + route + routing_type(options).to_s
diff --git a/actionpack/lib/action_controller/rack_process.rb b/actionpack/lib/action_controller/rack_process.rb
index 1ace16da07..e8ea3704a8 100644
--- a/actionpack/lib/action_controller/rack_process.rb
+++ b/actionpack/lib/action_controller/rack_process.rb
@@ -14,7 +14,8 @@ module ActionController #:nodoc:
:prefix => "ruby_sess.", # prefix session file names
:session_path => "/", # available to all paths in app
:session_key => "_session_id",
- :cookie_only => true
+ :cookie_only => true,
+ :session_http_only=> true
}
def initialize(env, session_options = DEFAULT_SESSION_OPTIONS)
diff --git a/actionpack/lib/action_controller/request.rb b/actionpack/lib/action_controller/request.rb
index 364e6201cc..8e6cfb41dc 100644..100755
--- a/actionpack/lib/action_controller/request.rb
+++ b/actionpack/lib/action_controller/request.rb
@@ -22,7 +22,7 @@ module ActionController
# such as { 'RAILS_ENV' => 'production' }.
attr_reader :env
- # The true HTTP request method as a lowercase symbol, such as <tt>:get</tt>.
+ # The true HTTP request \method as a lowercase symbol, such as <tt>:get</tt>.
# UnknownHttpMethod is raised for invalid methods not listed in ACCEPTED_HTTP_METHODS.
def request_method
method = @env['REQUEST_METHOD']
@@ -32,7 +32,7 @@ module ActionController
end
memoize :request_method
- # The HTTP request method as a lowercase symbol, such as <tt>:get</tt>.
+ # The HTTP request \method as a lowercase symbol, such as <tt>:get</tt>.
# Note, HEAD is returned as <tt>:get</tt> since the two are functionally
# equivalent from the application's perspective.
def method
@@ -59,19 +59,21 @@ module ActionController
request_method == :delete
end
- # Is this a HEAD request? <tt>request.method</tt> sees HEAD as <tt>:get</tt>,
- # so check the HTTP method directly.
+ # Is this a HEAD request? Since <tt>request.method</tt> sees HEAD as <tt>:get</tt>,
+ # this \method checks the actual HTTP \method directly.
def head?
request_method == :head
end
# Provides access to the request's HTTP headers, for example:
- # request.headers["Content-Type"] # => "text/plain"
+ #
+ # request.headers["Content-Type"] # => "text/plain"
def headers
ActionController::Http::Headers.new(@env)
end
memoize :headers
+ # Returns the content length of the request as an integer.
def content_length
@env['CONTENT_LENGTH'].to_i
end
@@ -79,14 +81,14 @@ module ActionController
# The MIME type of the HTTP request, such as Mime::XML.
#
- # For backward compatibility, the post format is extracted from the
+ # For backward compatibility, the post \format is extracted from the
# X-Post-Data-Format HTTP header if present.
def content_type
Mime::Type.lookup(content_type_without_parameters)
end
memoize :content_type
- # Returns the accepted MIME type for the request
+ # Returns the accepted MIME type for the request.
def accepts
header = @env['HTTP_ACCEPT'].to_s.strip
@@ -123,7 +125,7 @@ module ActionController
not_modified?(response.last_modified) || etag_matches?(response.etag)
end
- # Returns the Mime type for the format used in the request.
+ # Returns the Mime type for the \format used in the request.
#
# GET /posts/5.xml | request.format => Mime::XML
# GET /posts/5.xhtml | request.format => Mime::HTML
@@ -142,8 +144,8 @@ module ActionController
end
- # Sets the format by string extension, which can be used to force custom formats that are not controlled by the extension.
- # Example:
+ # Sets the \format by string extension, which can be used to force custom formats
+ # that are not controlled by the extension.
#
# class ApplicationController < ActionController::Base
# before_filter :adjust_format_for_iphone
@@ -159,7 +161,7 @@ module ActionController
end
# Returns a symbolized version of the <tt>:format</tt> parameter of the request.
- # If no format is given it returns <tt>:js</tt>for AJAX requests and <tt>:html</tt>
+ # If no \format is given it returns <tt>:js</tt>for Ajax requests and <tt>:html</tt>
# otherwise.
def template_format
parameter_format = parameters[:format]
@@ -190,17 +192,19 @@ module ActionController
# the right-hand-side of X-Forwarded-For
TRUSTED_PROXIES = /^127\.0\.0\.1$|^(10|172\.(1[6-9]|2[0-9]|30|31)|192\.168)\./i
- # Determine originating IP address. REMOTE_ADDR is the standard
+ # Determines originating IP address. REMOTE_ADDR is the standard
# but will fail if the user is behind a proxy. HTTP_CLIENT_IP and/or
# HTTP_X_FORWARDED_FOR are set by proxies so check for these if
# 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_addr_list = @env['REMOTE_ADDR'] && @env['REMOTE_ADDR'].split(',').collect(&:strip)
+ unless remote_addr_list.blank?
+ not_trusted_addrs = remote_addr_list.reject {|addr| addr =~ TRUSTED_PROXIES}
+ return not_trusted_addrs.first unless not_trusted_addrs.empty?
+ end
remote_ips = @env['HTTP_X_FORWARDED_FOR'] && @env['HTTP_X_FORWARDED_FOR'].split(',')
if @env.include? 'HTTP_CLIENT_IP'
@@ -235,13 +239,13 @@ EOM
memoize :server_software
- # Returns the complete URL used for this request
+ # Returns the complete URL used for this request.
def url
protocol + host_with_port + request_uri
end
memoize :url
- # Return 'https://' if this is an SSL request and 'http://' otherwise.
+ # Returns 'https://' if this is an SSL request and 'http://' otherwise.
def protocol
ssl? ? 'https://' : 'http://'
end
@@ -252,6 +256,7 @@ EOM
@env['HTTPS'] == 'on' || @env['HTTP_X_FORWARDED_PROTO'] == 'https'
end
+ # Returns the \host for this request, such as "example.com".
def raw_host_with_port
if forwarded = env["HTTP_X_FORWARDED_HOST"]
forwarded.split(/,\s?/).last
@@ -266,8 +271,8 @@ EOM
end
memoize :host
- # Returns a host:port string for this request, such as example.com or
- # example.com:8080.
+ # Returns a \host:\port string for this request, such as "example.com" or
+ # "example.com:8080".
def host_with_port
"#{host}#{port_string}"
end
@@ -283,7 +288,7 @@ EOM
end
memoize :port
- # Returns the standard port number for this request's protocol
+ # Returns the standard \port number for this request's protocol.
def standard_port
case protocol
when 'https://' then 443
@@ -291,13 +296,13 @@ EOM
end
end
- # Returns a port suffix like ":8080" if the port number of this request
- # is not the default HTTP port 80 or HTTPS port 443.
+ # Returns a \port suffix like ":8080" if the \port number of this request
+ # is not the default HTTP \port 80 or HTTPS \port 443.
def port_string
port == standard_port ? '' : ":#{port}"
end
- # Returns the domain part of a host, such as rubyonrails.org in "www.rubyonrails.org". You can specify
+ # Returns the \domain part of a \host, such as "rubyonrails.org" in "www.rubyonrails.org". You can specify
# a different <tt>tld_length</tt>, such as 2 to catch rubyonrails.co.uk in "www.rubyonrails.co.uk".
def domain(tld_length = 1)
return nil unless named_host?(host)
@@ -305,8 +310,9 @@ EOM
host.split('.').last(1 + tld_length).join('.')
end
- # Returns all the subdomains as an array, so ["dev", "www"] would be returned for "dev.www.rubyonrails.org".
- # You can specify a different <tt>tld_length</tt>, such as 2 to catch ["www"] instead of ["www", "rubyonrails"]
+ # Returns all the \subdomains as an array, so <tt>["dev", "www"]</tt> would be
+ # returned for "dev.www.rubyonrails.org". You can specify a different <tt>tld_length</tt>,
+ # such as 2 to catch <tt>["www"]</tt> instead of <tt>["www", "rubyonrails"]</tt>
# in "www.rubyonrails.co.uk".
def subdomains(tld_length = 1)
return [] unless named_host?(host)
@@ -314,7 +320,7 @@ EOM
parts[0..-(tld_length+2)]
end
- # Return the query string, accounting for server idiosyncrasies.
+ # Returns the query string, accounting for server idiosyncrasies.
def query_string
if uri = @env['REQUEST_URI']
uri.split('?', 2)[1] || ''
@@ -324,7 +330,7 @@ EOM
end
memoize :query_string
- # Return the request URI, accounting for server idiosyncrasies.
+ # Returns the request URI, accounting for server idiosyncrasies.
# WEBrick includes the full URL. IIS leaves REQUEST_URI blank.
def request_uri
if uri = @env['REQUEST_URI']
@@ -350,7 +356,8 @@ EOM
end
memoize :request_uri
- # Returns the interpreted path to requested resource after all the installation directory of this application was taken into account
+ # Returns the interpreted \path to requested resource after all the installation
+ # directory of this application was taken into account.
def path
path = (uri = request_uri) ? uri.split('?').first.to_s : ''
@@ -360,7 +367,7 @@ EOM
end
memoize :path
- # Read the request body. This is useful for web services that need to
+ # Read the request \body. This is useful for web services that need to
# work with raw requests directly.
def raw_post
unless env.include? 'RAW_POST_DATA'
@@ -370,7 +377,7 @@ EOM
env['RAW_POST_DATA']
end
- # Returns both GET and POST parameters in a single hash.
+ # Returns both GET and POST \parameters in a single hash.
def parameters
@parameters ||= request_parameters.merge(query_parameters).update(path_parameters).with_indifferent_access
end
@@ -380,17 +387,17 @@ EOM
@symbolized_path_parameters = @parameters = nil
end
- # The same as <tt>path_parameters</tt> with explicitly symbolized keys
+ # The same as <tt>path_parameters</tt> with explicitly symbolized keys.
def symbolized_path_parameters
@symbolized_path_parameters ||= path_parameters.symbolize_keys
end
- # Returns a hash with the parameters used to form the path of the request.
- # Returned hash keys are strings. See <tt>symbolized_path_parameters</tt> for symbolized keys.
- #
- # Example:
+ # Returns a hash with the \parameters used to form the \path of the request.
+ # Returned hash keys are strings:
#
# {'action' => 'my_action', 'controller' => 'my_controller'}
+ #
+ # See <tt>symbolized_path_parameters</tt> for symbolized keys.
def path_parameters
@path_parameters ||= {}
end
diff --git a/actionpack/lib/action_controller/rescue.rb b/actionpack/lib/action_controller/rescue.rb
index a1a9d68a35..83c4218af4 100644
--- a/actionpack/lib/action_controller/rescue.rb
+++ b/actionpack/lib/action_controller/rescue.rb
@@ -148,7 +148,7 @@ module ActionController #:nodoc:
end
# Overwrite to implement public exception handling (for requests answering false to <tt>local_request?</tt>). By
- # default will call render_optional_error_file. Override this method to provide more user friendly error messages.s
+ # default will call render_optional_error_file. Override this method to provide more user friendly error messages.
def rescue_action_in_public(exception) #:doc:
render_optional_error_file response_code_for_rescue(exception)
end
@@ -177,11 +177,8 @@ module ActionController #:nodoc:
# Render detailed diagnostics for unhandled exceptions rescued from
# a controller action.
def rescue_action_locally(exception)
- add_variables_to_assigns
@template.instance_variable_set("@exception", exception)
@template.instance_variable_set("@rescues_path", File.dirname(rescues_path("stub")))
- @template.send!(:assign_variables_from_controller)
-
@template.instance_variable_set("@contents", @template.render(:file => template_path_for_local_rescue(exception)))
response.content_type = Mime::HTML
diff --git a/actionpack/lib/action_controller/resources.rb b/actionpack/lib/action_controller/resources.rb
index 5f579cdb11..872b0dab3d 100644
--- a/actionpack/lib/action_controller/resources.rb
+++ b/actionpack/lib/action_controller/resources.rb
@@ -1,23 +1,23 @@
module ActionController
# == Overview
#
- # ActionController::Resources are a way of defining RESTful resources. A RESTful resource, in basic terms,
+ # ActionController::Resources are a way of defining RESTful \resources. A RESTful \resource, in basic terms,
# is something that can be pointed at and it will respond with a representation of the data requested.
# In real terms this could mean a user with a browser requests an HTML page, or that a desktop application
# requests XML data.
#
# RESTful design is based on the assumption that there are four generic verbs that a user of an
- # application can request from a resource (the noun).
+ # application can request from a \resource (the noun).
#
- # Resources can be requested using four basic HTTP verbs (GET, POST, PUT, DELETE), the method used
+ # \Resources can be requested using four basic HTTP verbs (GET, POST, PUT, DELETE), the method used
# denotes the type of action that should take place.
#
# === The Different Methods and their Usage
#
- # [+GET+] Requests for a resource, no saving or editing of a resource should occur in a GET request
- # [+POST+] Creation of resources
- # [+PUT+] Editing of attributes on a resource
- # [+DELETE+] Deletion of a resource
+ # * GET - Requests for a \resource, no saving or editing of a \resource should occur in a GET request.
+ # * POST - Creation of \resources.
+ # * PUT - Editing of attributes on a \resource.
+ # * DELETE - Deletion of a \resource.
#
# === Examples
#
@@ -85,16 +85,24 @@ module ActionController
@new_path ||= "#{path}/#{new_action}"
end
+ def shallow_path_prefix
+ @shallow_path_prefix ||= "#{path_prefix unless @options[:shallow]}"
+ end
+
def member_path
- @member_path ||= "#{path}/:id"
+ @member_path ||= "#{shallow_path_prefix}/#{path_segment}/:id"
end
def nesting_path_prefix
- @nesting_path_prefix ||= "#{path}/:#{singular}_id"
+ @nesting_path_prefix ||= "#{shallow_path_prefix}/#{path_segment}/:#{singular}_id"
+ end
+
+ def shallow_name_prefix
+ @shallow_name_prefix ||= "#{name_prefix unless @options[:shallow]}"
end
def nesting_name_prefix
- "#{name_prefix}#{singular}_"
+ "#{shallow_name_prefix}#{singular}_"
end
def action_separator
@@ -141,12 +149,14 @@ module ActionController
super
end
+ alias_method :shallow_path_prefix, :path_prefix
+ alias_method :shallow_name_prefix, :name_prefix
alias_method :member_path, :path
alias_method :nesting_path_prefix, :path
end
# Creates named routes for implementing verb-oriented controllers
- # for a collection resource.
+ # for a collection \resource.
#
# For example:
#
@@ -238,23 +248,24 @@ module ActionController
#
# The +resources+ method accepts the following options to customize the resulting routes:
# * <tt>:collection</tt> - Add named routes for other actions that operate on the collection.
- # Takes a hash of <tt>#{action} => #{method}</tt>, where method is <tt>:get</tt>/<tt>:post</tt>/<tt>:put</tt>/<tt>:delete</tt>
- # or <tt>:any</tt> if the method does not matter. These routes map to a URL like /messages/rss, with a route of +rss_messages_url+.
+ # Takes a hash of <tt>#{action} => #{method}</tt>, where method is <tt>:get</tt>/<tt>:post</tt>/<tt>:put</tt>/<tt>:delete</tt>,
+ # an array of any of the previous, or <tt>:any</tt> if the method does not matter.
+ # These routes map to a URL like /messages/rss, with a route of +rss_messages_url+.
# * <tt>:member</tt> - Same as <tt>:collection</tt>, but for actions that operate on a specific member.
- # * <tt>:new</tt> - Same as <tt>:collection</tt>, but for actions that operate on the new resource action.
+ # * <tt>:new</tt> - Same as <tt>:collection</tt>, but for actions that operate on the new \resource action.
# * <tt>:controller</tt> - Specify the controller name for the routes.
# * <tt>:singular</tt> - Specify the singular name used in the member routes.
# * <tt>:requirements</tt> - Set custom routing parameter requirements.
- # * <tt>:conditions</tt> - Specify custom routing recognition conditions. Resources sets the <tt>:method</tt> value for the method-specific routes.
- # * <tt>:as</tt> - Specify a different resource name to use in the URL path. For example:
+ # * <tt>:conditions</tt> - Specify custom routing recognition conditions. \Resources sets the <tt>:method</tt> value for the method-specific routes.
+ # * <tt>:as</tt> - Specify a different \resource name to use in the URL path. For example:
# # products_path == '/productos'
# map.resources :products, :as => 'productos' do |product|
# # product_reviews_path(product) == '/productos/1234/comentarios'
# product.resources :product_reviews, :as => 'comentarios'
# end
#
- # * <tt>:has_one</tt> - Specify nested resources, this is a shorthand for mapping singleton resources beneath the current.
- # * <tt>:has_many</tt> - Same has <tt>:has_one</tt>, but for plural resources.
+ # * <tt>:has_one</tt> - Specify nested \resources, this is a shorthand for mapping singleton \resources beneath the current.
+ # * <tt>:has_many</tt> - Same has <tt>:has_one</tt>, but for plural \resources.
#
# You may directly specify the routing association with +has_one+ and +has_many+ like:
#
@@ -277,18 +288,18 @@ module ActionController
#
# * <tt>:path_prefix</tt> - Set a prefix to the routes with required route variables.
#
- # Weblog comments usually belong to a post, so you might use resources like:
+ # Weblog comments usually belong to a post, so you might use +resources+ like:
#
# map.resources :articles
# map.resources :comments, :path_prefix => '/articles/:article_id'
#
- # You can nest resources calls to set this automatically:
+ # You can nest +resources+ calls to set this automatically:
#
# map.resources :articles do |article|
# article.resources :comments
# end
#
- # The comment resources work the same, but must now include a value for <tt>:article_id</tt>.
+ # The comment \resources work the same, but must now include a value for <tt>:article_id</tt>.
#
# article_comments_url(@article)
# article_comment_url(@article, @comment)
@@ -306,17 +317,42 @@ module ActionController
# map.resources :tags, :path_prefix => '/books/:book_id', :name_prefix => 'book_'
# map.resources :tags, :path_prefix => '/toys/:toy_id', :name_prefix => 'toy_'
#
- # You may also use <tt>:name_prefix</tt> to override the generic named routes in a nested resource:
+ # You may also use <tt>:name_prefix</tt> to override the generic named routes in a nested \resource:
#
# map.resources :articles do |article|
# article.resources :comments, :name_prefix => nil
# end
#
- # This will yield named resources like so:
+ # This will yield named \resources like so:
#
# comments_url(@article)
# comment_url(@article, @comment)
#
+ # * <tt>:shallow</tt> - If true, paths for nested resources which reference a specific member
+ # (ie. those with an :id parameter) will not use the parent path prefix or name prefix.
+ #
+ # The <tt>:shallow</tt> option is inherited by any nested resource(s).
+ #
+ # For example, 'users', 'posts' and 'comments' all use shallow paths with the following nested resources:
+ #
+ # map.resources :users, :shallow => true do |user|
+ # user.resources :posts do |post|
+ # post.resources :comments
+ # end
+ # end
+ # # --> GET /users/1/posts (maps to the PostsController#index action as usual)
+ # # also adds the usual named route called "user_posts"
+ # # --> GET /posts/2 (maps to the PostsController#show action as if it were not nested)
+ # # also adds the named route called "post"
+ # # --> GET /posts/2/comments (maps to the CommentsController#index action)
+ # # also adds the named route called "post_comments"
+ # # --> GET /comments/2 (maps to the CommentsController#show action as if it were not nested)
+ # # also adds the named route called "comment"
+ #
+ # You may also use <tt>:shallow</tt> in combination with the +has_one+ and +has_many+ shorthand notations like:
+ #
+ # map.resources :users, :has_many => { :posts => :comments }, :shallow => true
+ #
# If <tt>map.resources</tt> is called with multiple resources, they all get the same options applied.
#
# Examples:
@@ -349,28 +385,28 @@ module ActionController
#
# The +resources+ method sets HTTP method restrictions on the routes it generates. For example, making an
# HTTP POST on <tt>new_message_url</tt> will raise a RoutingError exception. The default route in
- # <tt>config/routes.rb</tt> overrides this and allows invalid HTTP methods for resource routes.
+ # <tt>config/routes.rb</tt> overrides this and allows invalid HTTP methods for \resource routes.
def resources(*entities, &block)
options = entities.extract_options!
entities.each { |entity| map_resource(entity, options.dup, &block) }
end
- # Creates named routes for implementing verb-oriented controllers for a singleton resource.
- # A singleton resource is global to its current context. For unnested singleton resources,
- # the resource is global to the current user visiting the application, such as a user's
- # /account profile. For nested singleton resources, the resource is global to its parent
- # resource, such as a <tt>projects</tt> resource that <tt>has_one :project_manager</tt>.
- # The <tt>project_manager</tt> should be mapped as a singleton resource under <tt>projects</tt>:
+ # Creates named routes for implementing verb-oriented controllers for a singleton \resource.
+ # A singleton \resource is global to its current context. For unnested singleton \resources,
+ # the \resource is global to the current user visiting the application, such as a user's
+ # <tt>/account</tt> profile. For nested singleton \resources, the \resource is global to its parent
+ # \resource, such as a <tt>projects</tt> \resource that <tt>has_one :project_manager</tt>.
+ # The <tt>project_manager</tt> should be mapped as a singleton \resource under <tt>projects</tt>:
#
# map.resources :projects do |project|
# project.resource :project_manager
# end
#
- # See map.resources for general conventions. These are the main differences:
- # * A singular name is given to map.resource. The default controller name is still taken from the plural name.
+ # See +resources+ for general conventions. These are the main differences:
+ # * A singular name is given to <tt>map.resource</tt>. The default controller name is still taken from the plural name.
# * To specify a custom plural name, use the <tt>:plural</tt> option. There is no <tt>:singular</tt> option.
- # * No default index route is created for the singleton resource controller.
- # * When nesting singleton resources, only the singular name is used as the path prefix (example: 'account/messages/1')
+ # * No default index route is created for the singleton \resource controller.
+ # * When nesting singleton \resources, only the singular name is used as the path prefix (example: 'account/messages/1')
#
# For example:
#
@@ -442,7 +478,7 @@ module ActionController
map_associations(resource, options)
if block_given?
- with_options(:path_prefix => resource.nesting_path_prefix, :name_prefix => resource.nesting_name_prefix, :namespace => options[:namespace], &block)
+ with_options(:path_prefix => resource.nesting_path_prefix, :name_prefix => resource.nesting_name_prefix, :namespace => options[:namespace], :shallow => options[:shallow], &block)
end
end
end
@@ -459,29 +495,45 @@ module ActionController
map_associations(resource, options)
if block_given?
- with_options(:path_prefix => resource.nesting_path_prefix, :name_prefix => resource.nesting_name_prefix, :namespace => options[:namespace], &block)
+ with_options(:path_prefix => resource.nesting_path_prefix, :name_prefix => resource.nesting_name_prefix, :namespace => options[:namespace], :shallow => options[:shallow], &block)
end
end
end
def map_associations(resource, options)
+ map_has_many_associations(resource, options.delete(:has_many), options) if options[:has_many]
+
path_prefix = "#{options.delete(:path_prefix)}#{resource.nesting_path_prefix}"
name_prefix = "#{options.delete(:name_prefix)}#{resource.nesting_name_prefix}"
- Array(options[:has_many]).each do |association|
- resources(association, :path_prefix => path_prefix, :name_prefix => name_prefix, :namespace => options[:namespace])
+ Array(options[:has_one]).each do |association|
+ resource(association, :path_prefix => path_prefix, :name_prefix => name_prefix, :namespace => options[:namespace], :shallow => options[:shallow])
end
+ end
- Array(options[:has_one]).each do |association|
- resource(association, :path_prefix => path_prefix, :name_prefix => name_prefix, :namespace => options[:namespace])
+ def map_has_many_associations(resource, associations, options)
+ case associations
+ when Hash
+ associations.each do |association,has_many|
+ map_has_many_associations(resource, association, options.merge(:has_many => has_many))
+ end
+ when Array
+ associations.each do |association|
+ map_has_many_associations(resource, association, options)
+ end
+ when Symbol, String
+ resources(associations, :path_prefix => resource.nesting_path_prefix, :name_prefix => resource.nesting_name_prefix, :namespace => options[:namespace], :shallow => options[:shallow], :has_many => options[:has_many])
+ else
end
end
def map_collection_actions(map, resource)
resource.collection_methods.each do |method, actions|
actions.each do |action|
- action_options = action_options_for(action, resource, method)
- map_named_routes(map, "#{action}_#{resource.name_prefix}#{resource.plural}", "#{resource.path}#{resource.action_separator}#{action}", action_options)
+ [method].flatten.each do |m|
+ action_options = action_options_for(action, resource, m)
+ map_named_routes(map, "#{action}_#{resource.name_prefix}#{resource.plural}", "#{resource.path}#{resource.action_separator}#{action}", action_options)
+ end
end
end
end
@@ -521,17 +573,19 @@ module ActionController
def map_member_actions(map, resource)
resource.member_methods.each do |method, actions|
actions.each do |action|
- action_options = action_options_for(action, resource, method)
+ [method].flatten.each do |m|
+ action_options = action_options_for(action, resource, m)
- action_path = resource.options[:path_names][action] if resource.options[:path_names].is_a?(Hash)
- action_path ||= Base.resources_path_names[action] || action
+ action_path = resource.options[:path_names][action] if resource.options[:path_names].is_a?(Hash)
+ action_path ||= Base.resources_path_names[action] || action
- map_named_routes(map, "#{action}_#{resource.name_prefix}#{resource.singular}", "#{resource.member_path}#{resource.action_separator}#{action_path}", action_options)
+ map_named_routes(map, "#{action}_#{resource.shallow_name_prefix}#{resource.singular}", "#{resource.member_path}#{resource.action_separator}#{action_path}", action_options)
+ end
end
end
show_action_options = action_options_for("show", resource)
- map_named_routes(map, "#{resource.name_prefix}#{resource.singular}", resource.member_path, show_action_options)
+ map_named_routes(map, "#{resource.shallow_name_prefix}#{resource.singular}", resource.member_path, show_action_options)
update_action_options = action_options_for("update", resource)
map_unnamed_routes(map, resource.member_path, update_action_options)
@@ -574,4 +628,4 @@ end
class ActionController::Routing::RouteSet::Mapper
include ActionController::Resources
-end \ No newline at end of file
+end
diff --git a/actionpack/lib/action_controller/response.rb b/actionpack/lib/action_controller/response.rb
index 5dac4128bb..54a99996ef 100644
--- a/actionpack/lib/action_controller/response.rb
+++ b/actionpack/lib/action_controller/response.rb
@@ -129,8 +129,8 @@ module ActionController # :nodoc:
def prepare!
assign_default_content_type_and_charset!
- set_content_length!
handle_conditional_get!
+ set_content_length!
convert_content_type!
end
diff --git a/actionpack/lib/action_controller/routing/builder.rb b/actionpack/lib/action_controller/routing/builder.rb
index 03427e41de..5704d9d01a 100644
--- a/actionpack/lib/action_controller/routing/builder.rb
+++ b/actionpack/lib/action_controller/routing/builder.rb
@@ -187,12 +187,14 @@ module ActionController
private
def validate_route_conditions(conditions)
if method = conditions[:method]
- if method == :head
- raise ArgumentError, "HTTP method HEAD is invalid in route conditions. Rails processes HEAD requests the same as GETs, returning just the response headers"
- end
+ [method].flatten.each do |m|
+ if m == :head
+ raise ArgumentError, "HTTP method HEAD is invalid in route conditions. Rails processes HEAD requests the same as GETs, returning just the response headers"
+ end
- unless HTTP_METHODS.include?(method.to_sym)
- raise ArgumentError, "Invalid HTTP method specified in route conditions: #{conditions.inspect}"
+ unless HTTP_METHODS.include?(m.to_sym)
+ raise ArgumentError, "Invalid HTTP method specified in route conditions: #{conditions.inspect}"
+ end
end
end
end
diff --git a/actionpack/lib/action_controller/routing/optimisations.rb b/actionpack/lib/action_controller/routing/optimisations.rb
index 0fe836606c..894d4109e4 100644
--- a/actionpack/lib/action_controller/routing/optimisations.rb
+++ b/actionpack/lib/action_controller/routing/optimisations.rb
@@ -103,9 +103,10 @@ module ActionController
end
# This case uses almost the same code as positional arguments,
- # but add an args.last.to_query on the end
+ # but add a question mark and args.last.to_query on the end,
+ # unless the last arg is empty
def generation_code
- super.insert(-2, '?#{args.last.to_query}')
+ super.insert(-2, '#{\'?\' + args.last.to_query unless args.last.empty?}')
end
# To avoid generating "http://localhost/?host=foo.example.com" we
diff --git a/actionpack/lib/action_controller/routing/recognition_optimisation.rb b/actionpack/lib/action_controller/routing/recognition_optimisation.rb
index 6d54d0334c..4935432d87 100644
--- a/actionpack/lib/action_controller/routing/recognition_optimisation.rb
+++ b/actionpack/lib/action_controller/routing/recognition_optimisation.rb
@@ -134,6 +134,9 @@ module ActionController
def write_recognize_optimized!
tree = segment_tree(routes)
body = generate_code(tree)
+
+ remove_recognize_optimized!
+
instance_eval %{
def recognize_optimized(path, env)
segments = to_plain_segments(path)
@@ -147,6 +150,25 @@ module ActionController
end
}, __FILE__, __LINE__
end
+
+ def clear_recognize_optimized!
+ remove_recognize_optimized!
+
+ class << self
+ def recognize_optimized(path, environment)
+ write_recognize_optimized!
+ recognize_optimized(path, environment)
+ end
+ end
+ end
+
+ def remove_recognize_optimized!
+ if respond_to?(:recognize_optimized)
+ class << self
+ remove_method :recognize_optimized
+ end
+ end
+ end
end
end
end
diff --git a/actionpack/lib/action_controller/routing/route.rb b/actionpack/lib/action_controller/routing/route.rb
index 2106ac09e0..3b2cb28545 100644
--- a/actionpack/lib/action_controller/routing/route.rb
+++ b/actionpack/lib/action_controller/routing/route.rb
@@ -201,7 +201,7 @@ module ActionController
# recognition, not generation.
def recognition_conditions
result = ["(match = #{Regexp.new(recognition_pattern).inspect}.match(path))"]
- result << "conditions[:method] === env[:method]" if conditions[:method]
+ result << "[conditions[:method]].flatten.include?(env[:method])" if conditions[:method]
result
end
diff --git a/actionpack/lib/action_controller/routing/route_set.rb b/actionpack/lib/action_controller/routing/route_set.rb
index 8dfc22f94f..ff448490e9 100644
--- a/actionpack/lib/action_controller/routing/route_set.rb
+++ b/actionpack/lib/action_controller/routing/route_set.rb
@@ -115,7 +115,7 @@ module ActionController
def install(destinations = [ActionController::Base, ActionView::Base], regenerate = false)
reset! if regenerate
Array(destinations).each do |dest|
- dest.send! :include, @module
+ dest.__send__(:include, @module)
end
end
@@ -195,7 +195,7 @@ module ActionController
self.routes = []
self.named_routes = NamedRouteCollection.new
- write_recognize_optimized!
+ clear_recognize_optimized!
end
# Subclasses and plugins may override this method to specify a different
@@ -217,7 +217,7 @@ module ActionController
@routes_by_controller = nil
# This will force routing/recognition_optimization.rb
# to refresh optimisations.
- @compiled_recognize_optimized = nil
+ clear_recognize_optimized!
end
def install_helpers(destinations = [ActionController::Base, ActionView::Base], regenerate_code = false)
@@ -353,7 +353,7 @@ module ActionController
if generate_all
# Used by caching to expire all paths for a resource
return routes.collect do |route|
- route.send!(method, options, merged, expire_on)
+ route.__send__(method, options, merged, expire_on)
end.compact
end
@@ -361,7 +361,7 @@ module ActionController
routes = routes_by_controller[controller][action][options.keys.sort_by { |x| x.object_id }]
routes.each do |route|
- results = route.send!(method, options, merged, expire_on)
+ results = route.__send__(method, options, merged, expire_on)
return results if results && (!results.is_a?(Array) || results.first)
end
end
diff --git a/actionpack/lib/action_controller/routing/segments.rb b/actionpack/lib/action_controller/routing/segments.rb
index 9d4b740a44..e5f174ae2c 100644
--- a/actionpack/lib/action_controller/routing/segments.rb
+++ b/actionpack/lib/action_controller/routing/segments.rb
@@ -160,7 +160,7 @@ module ActionController
s << "\n#{expiry_statement}"
end
- def interpolation_chunk(value_code = "#{local_name}")
+ def interpolation_chunk(value_code = local_name)
"\#{URI.escape(#{value_code}.to_s, ActionController::Routing::Segment::UNSAFE_PCHAR)}"
end
@@ -231,7 +231,7 @@ module ActionController
end
# Don't URI.escape the controller name since it may contain slashes.
- def interpolation_chunk(value_code = "#{local_name}")
+ def interpolation_chunk(value_code = local_name)
"\#{#{value_code}.to_s}"
end
@@ -251,7 +251,7 @@ module ActionController
end
class PathSegment < DynamicSegment #:nodoc:
- def interpolation_chunk(value_code = "#{local_name}")
+ def interpolation_chunk(value_code = local_name)
"\#{#{value_code}}"
end
diff --git a/actionpack/lib/action_controller/session/cookie_store.rb b/actionpack/lib/action_controller/session/cookie_store.rb
index 5bf7503f04..f2fb200950 100644
--- a/actionpack/lib/action_controller/session/cookie_store.rb
+++ b/actionpack/lib/action_controller/session/cookie_store.rb
@@ -70,7 +70,8 @@ class CGI::Session::CookieStore
'path' => options['session_path'],
'domain' => options['session_domain'],
'expires' => options['session_expires'],
- 'secure' => options['session_secure']
+ 'secure' => options['session_secure'],
+ 'http_only' => options['session_http_only']
}
# Set no_hidden and no_cookies since the session id is unused and we
diff --git a/actionpack/lib/action_controller/session_management.rb b/actionpack/lib/action_controller/session_management.rb
index 80a3ddd2c5..fd3d94ed97 100644
--- a/actionpack/lib/action_controller/session_management.rb
+++ b/actionpack/lib/action_controller/session_management.rb
@@ -60,6 +60,10 @@ module ActionController #:nodoc:
# # the session will only work over HTTPS, but only for the foo action
# session :only => :foo, :session_secure => true
#
+ # # the session by default uses HttpOnly sessions for security reasons.
+ # # this can be switched off.
+ # session :only => :foo, :session_http_only => false
+ #
# # the session will only be disabled for 'foo', and only if it is
# # requested as a web service
# session :off, :only => :foo,
@@ -86,14 +90,14 @@ module ActionController #:nodoc:
raise ArgumentError, "only one of either :only or :except are allowed"
end
- write_inheritable_array("session_options", [options])
+ write_inheritable_array(:session_options, [options])
end
# So we can declare session options in the Rails initializer.
alias_method :session=, :session
def cached_session_options #:nodoc:
- @session_options ||= read_inheritable_attribute("session_options") || []
+ @session_options ||= read_inheritable_attribute(:session_options) || []
end
def session_options_for(request, action) #:nodoc:
diff --git a/actionpack/lib/action_controller/test_process.rb b/actionpack/lib/action_controller/test_process.rb
index c6b1470070..cde1f2052b 100644
--- a/actionpack/lib/action_controller/test_process.rb
+++ b/actionpack/lib/action_controller/test_process.rb
@@ -3,6 +3,8 @@ require 'action_controller/test_case'
module ActionController #:nodoc:
class Base
+ attr_reader :assigns
+
# Process a test request called with a TestRequest object.
def self.process_test(request)
new.process_test(request)
@@ -14,7 +16,12 @@ module ActionController #:nodoc:
def process_with_test(*args)
returning process_without_test(*args) do
- add_variables_to_assigns
+ @assigns = {}
+ (instance_variable_names - @@protected_instance_variables).each do |var|
+ value = instance_variable_get(var)
+ @assigns[var[1..-1]] = value
+ response.template.assigns[var[1..-1]] = value if response
+ end
end
end
@@ -211,7 +218,7 @@ module ActionController #:nodoc:
# Returns the template of the file which was used to
# render this response (or nil)
def rendered_template
- template._first_render
+ template.send(:_first_render)
end
# A shortcut to the flash. Returns an empty hash if no session flash exists.
@@ -331,7 +338,7 @@ module ActionController #:nodoc:
attr_reader :original_filename
# The content type of the "uploaded" file
- attr_reader :content_type
+ attr_accessor :content_type
def initialize(path, content_type = Mime::TEXT, binary = false)
raise "#{path} file does not exist" unless File.exist?(path)
@@ -350,7 +357,7 @@ module ActionController #:nodoc:
alias local_path path
def method_missing(method_name, *args, &block) #:nodoc:
- @tempfile.send!(method_name, *args, &block)
+ @tempfile.__send__(method_name, *args, &block)
end
end
@@ -396,7 +403,7 @@ module ActionController #:nodoc:
def xml_http_request(request_method, action, parameters = nil, session = nil, flash = nil)
@request.env['HTTP_X_REQUESTED_WITH'] = 'XMLHttpRequest'
@request.env['HTTP_ACCEPT'] = 'text/javascript, text/html, application/xml, text/xml, */*'
- returning send!(request_method, action, parameters, session, flash) do
+ returning __send__(request_method, action, parameters, session, flash) do
@request.env.delete 'HTTP_X_REQUESTED_WITH'
@request.env.delete 'HTTP_ACCEPT'
end
@@ -429,7 +436,7 @@ module ActionController #:nodoc:
def build_request_uri(action, parameters)
unless @request.env['REQUEST_URI']
- options = @controller.send!(:rewrite_options, parameters)
+ options = @controller.__send__(:rewrite_options, parameters)
options.update(:only_path => true, :action => action)
url = ActionController::UrlRewriter.new(@request, parameters)
diff --git a/actionpack/lib/action_controller/translation.rb b/actionpack/lib/action_controller/translation.rb
new file mode 100644
index 0000000000..9bb63cdb15
--- /dev/null
+++ b/actionpack/lib/action_controller/translation.rb
@@ -0,0 +1,13 @@
+module ActionController
+ module Translation
+ def translate(*args)
+ I18n.translate *args
+ end
+ alias :t :translate
+
+ def localize(*args)
+ I18n.localize *args
+ end
+ alias :l :localize
+ end
+end \ No newline at end of file
diff --git a/actionpack/lib/action_controller/verification.rb b/actionpack/lib/action_controller/verification.rb
index 35b12a7f13..7bf09ba6ea 100644
--- a/actionpack/lib/action_controller/verification.rb
+++ b/actionpack/lib/action_controller/verification.rb
@@ -80,7 +80,7 @@ module ActionController #:nodoc:
# array (may also be a single value).
def verify(options={})
before_filter :only => options[:only], :except => options[:except] do |c|
- c.send! :verify_action, options
+ c.__send__ :verify_action, options
end
end
end
@@ -116,7 +116,7 @@ module ActionController #:nodoc:
end
def apply_redirect_to(redirect_to_option) # :nodoc:
- (redirect_to_option.is_a?(Symbol) && redirect_to_option != :back) ? 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: