Update to Rails 2.3.8
This commit is contained in:
parent
6677b46cb4
commit
f0635301aa
429 changed files with 17683 additions and 4047 deletions
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)}
|
||||
#
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue