Update to Rails 2.3.8

This commit is contained in:
Jacques Distler 2010-05-25 12:45:45 -05:00
parent 6677b46cb4
commit f0635301aa
429 changed files with 17683 additions and 4047 deletions

View file

@ -144,16 +144,25 @@ module ActionController
end
def normalize_argument_to_redirection(fragment)
after_routing = @controller.url_for(fragment)
if after_routing =~ %r{^\w+://.*}
after_routing
else
# FIXME - this should probably get removed.
if after_routing.first != '/'
after_routing = '/' + after_routing
case fragment
when %r{^\w[\w\d+.-]*:.*}
fragment
when String
if fragment =~ %r{^\w[\w\d+.-]*:.*}
fragment
else
if fragment !~ /^\//
ActiveSupport::Deprecation.warn "Omitting the leading slash on a path with assert_redirected_to is deprecated. Use '/#{fragment}' instead.", caller(2)
fragment = "/#{fragment}"
end
@request.protocol + @request.host_with_port + fragment
end
@request.protocol + @request.host_with_port + after_routing
end
when :back
raise RedirectBackError unless refer = @request.headers["Referer"]
refer
else
@controller.url_for(fragment)
end.gsub(/[\r\n]/, '')
end
end
end

View file

@ -616,15 +616,6 @@ module ActionController #:nodoc:
# displayed on:
#
# url_for :controller => 'posts', :action => nil
#
# If you explicitly want to create a URL that's almost the same as the current URL, you can do so using the
# <tt>:overwrite_params</tt> options. Say for your posts you have different views for showing and printing them.
# Then, in the show view, you get the URL for the print view like this
#
# url_for :overwrite_params => { :action => 'print' }
#
# 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 = {})
options ||= {}
case options
@ -1092,10 +1083,19 @@ module ActionController #:nodoc:
# The redirection happens as a "302 Moved" header unless otherwise specified.
#
# Examples:
# redirect_to post_url(@post), :status=>:found
# redirect_to :action=>'atom', :status=>:moved_permanently
# redirect_to post_url(@post), :status=>301
# redirect_to :action=>'atom', :status=>302
# redirect_to post_url(@post), :status => :found
# redirect_to :action=>'atom', :status => :moved_permanently
# redirect_to post_url(@post), :status => 301
# redirect_to :action=>'atom', :status => 302
#
# It is also possible to assign a flash message as part of the redirection. There are two special accessors for commonly used the flash names
# +alert+ and +notice+ as well as a general purpose +flash+ bucket.
#
# Examples:
# redirect_to post_url(@post), :alert => "Watch it, mister!"
# redirect_to post_url(@post), :status=> :found, :notice => "Pay attention to the road"
# redirect_to post_url(@post), :status => 301, :flash => { :updated_post_id => @post.id }
# redirect_to { :action=>'atom' }, :alert => "Something serious happened"
#
# When using <tt>redirect_to :back</tt>, if there is no referrer,
# RedirectBackError will be raised. You may specify some fallback
@ -1412,7 +1412,7 @@ module ActionController #:nodoc:
end
Base.class_eval do
[ Filters, Layout, Benchmarking, Rescue, Flash, MimeResponds, Helpers,
[ Filters, Layout, Benchmarking, Rescue, MimeResponds, Helpers, Flash,
Cookies, Caching, Verification, Streaming, SessionManagement,
HttpAuthentication::Basic::ControllerMethods, HttpAuthentication::Digest::ControllerMethods,
RecordIdentifier, RequestForgeryProtection, Translation

View file

@ -37,7 +37,7 @@ module ActionController #:nodoc:
def fragment_for(buffer, name = {}, options = nil, &block) #:nodoc:
if perform_caching
if cache = read_fragment(name, options)
buffer.concat(cache)
buffer.safe_concat(cache.html_safe)
else
pos = buffer.length
block.call
@ -52,9 +52,9 @@ module ActionController #:nodoc:
def write_fragment(key, content, options = nil)
return content unless cache_configured?
key = fragment_cache_key(key)
self.class.benchmark "Cached fragment miss: #{key}" do
key = fragment_cache_key(key)
content = content.html_safe.to_str if content.respond_to?(:html_safe)
cache_store.write(key, content, options)
end
@ -65,10 +65,10 @@ module ActionController #:nodoc:
def read_fragment(key, options = nil)
return unless cache_configured?
key = fragment_cache_key(key)
self.class.benchmark "Cached fragment hit: #{key}" do
cache_store.read(key, options)
key = fragment_cache_key(key)
result = cache_store.read(key, options)
result.respond_to?(:html_safe) ? result.html_safe : result
end
end

View file

@ -46,6 +46,7 @@ module ActionController #:nodoc:
module Cookies
def self.included(base)
base.helper_method :cookies
base.cattr_accessor :cookie_verifier_secret
end
protected
@ -56,6 +57,8 @@ module ActionController #:nodoc:
end
class CookieJar < Hash #:nodoc:
attr_reader :controller
def initialize(controller)
@controller, @cookies = controller, controller.request.cookies
super()
@ -91,5 +94,98 @@ module ActionController #:nodoc:
@controller.response.delete_cookie(key, options)
value
end
# Returns a jar that'll automatically set the assigned cookies to have an expiration date 20 years from now. Example:
#
# cookies.permanent[:prefers_open_id] = true
# # => Set-Cookie: prefers_open_id=true; path=/; expires=Sun, 16-Dec-2029 03:24:16 GMT
#
# This jar is only meant for writing. You'll read permanent cookies through the regular accessor.
#
# This jar allows chaining with the signed jar as well, so you can set permanent, signed cookies. Examples:
#
# cookies.permanent.signed[:remember_me] = current_user.id
# # => Set-Cookie: discount=BAhU--848956038e692d7046deab32b7131856ab20e14e; path=/; expires=Sun, 16-Dec-2029 03:24:16 GMT
def permanent
@permanent ||= PermanentCookieJar.new(self)
end
# Returns a jar that'll automatically generate a signed representation of cookie value and verify it when reading from
# the cookie again. This is useful for creating cookies with values that the user is not supposed to change. If a signed
# cookie was tampered with by the user (or a 3rd party), an ActiveSupport::MessageVerifier::InvalidSignature exception will
# be raised.
#
# This jar requires that you set a suitable secret for the verification on ActionController::Base.cookie_verifier_secret.
#
# Example:
#
# cookies.signed[:discount] = 45
# # => Set-Cookie: discount=BAhpMg==--2c1c6906c90a3bc4fd54a51ffb41dffa4bf6b5f7; path=/
#
# cookies.signed[:discount] # => 45
def signed
@signed ||= SignedCookieJar.new(self)
end
end
class PermanentCookieJar < CookieJar #:nodoc:
def initialize(parent_jar)
@parent_jar = parent_jar
end
def []=(key, options)
if options.is_a?(Hash)
options.symbolize_keys!
else
options = { :value => options }
end
options[:expires] = 20.years.from_now
@parent_jar[key] = options
end
def signed
@signed ||= SignedCookieJar.new(self)
end
def controller
@parent_jar.controller
end
def method_missing(method, *arguments, &block)
@parent_jar.send(method, *arguments, &block)
end
end
class SignedCookieJar < CookieJar #:nodoc:
def initialize(parent_jar)
unless parent_jar.controller.class.cookie_verifier_secret
raise "You must set ActionController::Base.cookie_verifier_secret to use signed cookies"
end
@parent_jar = parent_jar
@verifier = ActiveSupport::MessageVerifier.new(@parent_jar.controller.class.cookie_verifier_secret)
end
def [](name)
if value = @parent_jar[name]
@verifier.verify(value)
end
end
def []=(key, options)
if options.is_a?(Hash)
options.symbolize_keys!
options[:value] = @verifier.generate(options[:value])
else
options = { :value => @verifier.generate(options) }
end
@parent_jar[key] = options
end
def method_missing(method, *arguments, &block)
@parent_jar.send(method, *arguments, &block)
end
end
end

View file

@ -73,6 +73,7 @@ module ActionController
message = "/!\\ FAILSAFE /!\\ #{Time.now}\n Status: 500 Internal Server Error\n"
message << " #{exception}\n #{exception.backtrace.join("\n ")}" if exception
failsafe_logger.fatal(message)
failsafe_logger.flush if failsafe_logger.respond_to?(:flush)
end
def failsafe_logger

View file

@ -29,8 +29,13 @@ module ActionController #:nodoc:
def self.included(base)
base.class_eval do
include InstanceMethods
alias_method_chain :perform_action, :flash
alias_method_chain :reset_session, :flash
alias_method_chain :redirect_to, :flash
helper_method :alert
helper_method :notice
end
end
@ -155,6 +160,22 @@ module ActionController #:nodoc:
remove_instance_variable(:@_flash) if defined? @_flash
end
def redirect_to_with_flash(options = {}, response_status_and_flash = {}) #:doc:
if alert = response_status_and_flash.delete(:alert)
flash[:alert] = alert
end
if notice = response_status_and_flash.delete(:notice)
flash[:notice] = notice
end
if other_flashes = response_status_and_flash.delete(:flash)
flash.update(other_flashes)
end
redirect_to_without_flash(options, response_status_and_flash)
end
# Access the contents of the flash. Use <tt>flash["notice"]</tt> to
# read a notice you put there or <tt>flash["notice"] = "hello"</tt>
# to put a new one.
@ -166,6 +187,27 @@ module ActionController #:nodoc:
@_flash
end
# Convenience accessor for flash[:alert]
def alert
flash[:alert]
end
# Convenience accessor for flash[:alert]=
def alert=(message)
flash[:alert] = message
end
# Convenience accessor for flash[:notice]
def notice
flash[:notice]
end
# Convenience accessor for flash[:notice]=
def notice=(message)
flash[:notice] = message
end
end
end
end

View file

@ -323,7 +323,9 @@ module ActionController
@headers = Rack::Utils::HeaderHash.new(headers)
(@headers['Set-Cookie'] || "").split("\n").each do |cookie|
cookies = @headers['Set-Cookie']
cookies = cookies.to_s.split("\n") unless cookies.is_a?(Array)
cookies.each do |cookie|
name, value = cookie.match(/^([^=]*)=([^;]*);/)[1,2]
@cookies[name] = value
end
@ -353,6 +355,8 @@ module ActionController
# used in integration tests.
@response.extend(TestResponseBehavior)
body.close if body.respond_to?(:close)
return @status
rescue MultiPartNeededException
boundary = "----------XnJLe9ZIbbGUYtzPQJ16u1"

View file

@ -115,7 +115,7 @@ module ActionController
end
%w(edit new).each do |action|
module_eval <<-EOT, __FILE__, __LINE__
module_eval <<-EOT, __FILE__, __LINE__ + 1
def #{action}_polymorphic_url(record_or_hash, options = {}) # def edit_polymorphic_url(record_or_hash, options = {})
polymorphic_url( # polymorphic_url(
record_or_hash, # record_or_hash,

View file

@ -1,4 +1,4 @@
# Rack 1.0 does not allow string subclass body. This does not play well with our ActionView::SafeBuffer.
# Rack 1.0 does not allow string subclass body. This does not play well with our ActiveSupport::SafeBuffer.
# The next release of Rack will be allowing string subclass body - http://github.com/rack/rack/commit/de668df02802a0335376a81ba709270e43ba9d55
# TODO : Remove this monkey patch after the next release of Rack

View file

@ -15,7 +15,7 @@ module ActionController #:nodoc:
# behavior is achieved by overriding the <tt>rescue_action_in_public</tt>
# and <tt>rescue_action_locally</tt> methods.
module Rescue
LOCALHOST = '127.0.0.1'.freeze
LOCALHOST = ['127.0.0.1', '::1'].freeze
DEFAULT_RESCUE_RESPONSE = :internal_server_error
DEFAULT_RESCUE_RESPONSES = {
@ -122,7 +122,7 @@ module ActionController #:nodoc:
# method if you wish to redefine the meaning of a local request to
# include remote IP addresses or other criteria.
def local_request? #:doc:
request.remote_addr == LOCALHOST && request.remote_ip == LOCALHOST
LOCALHOST.any?{ |local_ip| request.remote_addr == local_ip && request.remote_ip == local_ip }
end
# Render detailed diagnostics for unhandled exceptions rescued from

View file

@ -117,11 +117,7 @@ module ActionController # :nodoc:
end
def etag=(etag)
if etag.blank?
headers.delete('ETag')
else
headers['ETag'] = %("#{Digest::MD5.hexdigest(ActiveSupport::Cache.expand_cache_key(etag))}")
end
headers['ETag'] = %("#{Digest::MD5.hexdigest(ActiveSupport::Cache.expand_cache_key(etag))}")
end
def redirect(url, status)
@ -202,7 +198,7 @@ module ActionController # :nodoc:
def nonempty_ok_response?
ok = !status || status.to_s[0..2] == '200'
ok && body.is_a?(String) && !body.empty?
ok && body.is_a?(String) && !body.blank?
end
def set_conditional_cache_control!
@ -233,7 +229,8 @@ module ActionController # :nodoc:
end
def convert_cookies!
headers['Set-Cookie'] = Array(headers['Set-Cookie']).compact
cookies = Array(headers['Set-Cookie']).compact
headers['Set-Cookie'] = cookies unless cookies.empty?
end
end
end

View file

@ -174,6 +174,7 @@ module ActionController
#
named_helper_module_eval <<-end_eval # We use module_eval to avoid leaks
def #{selector}(*args) # def users_url(*args)
args.compact! #
#
#{generate_optimisation_block(route, kind)} # #{generate_optimisation_block(route, kind)}
#

View file

@ -98,12 +98,18 @@ module ActionController
# Process legacy CGI options
options = options.symbolize_keys
if options.has_key?(:session_path)
ActiveSupport::Deprecation.warn "Giving :session_path to SessionStore is deprecated, " <<
"please use :path instead", caller
options[:path] = options.delete(:session_path)
end
if options.has_key?(:session_key)
ActiveSupport::Deprecation.warn "Giving :session_key to SessionStore is deprecated, " <<
"please use :key instead", caller
options[:key] = options.delete(:session_key)
end
if options.has_key?(:session_http_only)
ActiveSupport::Deprecation.warn "Giving :session_http_only to SessionStore is deprecated, " <<
"please use :httponly instead", caller
options[:httponly] = options.delete(:session_http_only)
end

View file

@ -59,12 +59,18 @@ module ActionController
# Process legacy CGI options
options = options.symbolize_keys
if options.has_key?(:session_path)
ActiveSupport::Deprecation.warn "Giving :session_path to SessionStore is deprecated, " <<
"please use :path instead", caller
options[:path] = options.delete(:session_path)
end
if options.has_key?(:session_key)
ActiveSupport::Deprecation.warn "Giving :session_key to SessionStore is deprecated, " <<
"please use :key instead", caller
options[:key] = options.delete(:session_key)
end
if options.has_key?(:session_http_only)
ActiveSupport::Deprecation.warn "Giving :session_http_only to SessionStore is deprecated, " <<
"please use :httponly instead", caller
options[:httponly] = options.delete(:session_http_only)
end

View file

@ -15,12 +15,12 @@
show = "document.getElementById('#{name.gsub /\s/, '-'}').style.display='block';"
hide = (names - [name]).collect {|hide_name| "document.getElementById('#{hide_name.gsub /\s/, '-'}').style.display='none';"}
%>
<a href="#" onclick="<%= hide %><%= show %>; return false;"><%= name %></a> <%= '|' unless names.last == name %>
<a href="#" onclick="<%= hide.join %><%= show %>; return false;"><%= name %></a> <%= '|' unless names.last == name %>
<% end %>
<% traces.each do |name, trace| %>
<div id="<%= name.gsub /\s/, '-' %>" style="display: <%= name == "Application Trace" ? 'block' : 'none' %>;">
<pre><code><%= trace.join "\n" %></code></pre>
<pre><code><%=h trace.join "\n" %></code></pre>
</div>
<% end %>
</div>

View file

@ -159,6 +159,9 @@ module ActionController
end
def rewrite(options = {})
if options.include?(:overwrite_params)
ActiveSupport::Deprecation.warn 'The :overwrite_params option is deprecated. Specify all the necessary parameters instead', caller
end
rewrite_url(options)
end
@ -194,7 +197,7 @@ module ActionController
options = options.symbolize_keys
options.update(options[:params].symbolize_keys) if options[:params]
if (overwrite = options.delete(:overwrite_params))
if overwrite = options.delete(:overwrite_params)
options.update(@parameters.symbolize_keys)
options.update(overwrite.symbolize_keys)
end