mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
Add :status to redirect_to allowing users to choose their own response code without manually setting headers. Closes #8297 [codahale, chasgrundy]
git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@7820 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
This commit is contained in:
parent
19c9c7fafb
commit
4aabe46341
4 changed files with 105 additions and 10 deletions
|
@ -1,5 +1,7 @@
|
||||||
*SVN*
|
*SVN*
|
||||||
|
|
||||||
|
* Add :status to redirect_to allowing users to choose their own response code without manually setting headers. #8297 [codahale, chasgrundy]
|
||||||
|
|
||||||
* Add link_to :back which uses your referrer with a fallback to a javascript link. #7366 [eventualbuddha, tarmo]
|
* Add link_to :back which uses your referrer with a fallback to a javascript link. #7366 [eventualbuddha, tarmo]
|
||||||
|
|
||||||
* error_messages_for and friends also work with local variables. #9699 [Frederick Cheung]
|
* error_messages_for and friends also work with local variables. #9699 [Frederick Cheung]
|
||||||
|
|
|
@ -987,32 +987,47 @@ module ActionController #:nodoc:
|
||||||
# redirect_to "/images/screenshot.jpg"
|
# redirect_to "/images/screenshot.jpg"
|
||||||
# redirect_to :back
|
# redirect_to :back
|
||||||
#
|
#
|
||||||
# The redirection happens as a "302 Moved" header.
|
# 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
|
||||||
#
|
#
|
||||||
# When using <tt>redirect_to :back</tt>, if there is no referrer,
|
# When using <tt>redirect_to :back</tt>, if there is no referrer,
|
||||||
# RedirectBackError will be raised. You may specify some fallback
|
# RedirectBackError will be raised. You may specify some fallback
|
||||||
# behavior for this case by rescuing RedirectBackError.
|
# behavior for this case by rescuing RedirectBackError.
|
||||||
def redirect_to(options = {}) #:doc:
|
def redirect_to(options = {}, response_status = {}) #:doc:
|
||||||
|
|
||||||
|
if options.is_a?(Hash) && options[:status]
|
||||||
|
status = options.delete(:status)
|
||||||
|
elsif response_status[:status]
|
||||||
|
status = response_status[:status]
|
||||||
|
else
|
||||||
|
status = 302
|
||||||
|
end
|
||||||
|
|
||||||
case options
|
case options
|
||||||
when %r{^\w+://.*}
|
when %r{^\w+://.*}
|
||||||
raise DoubleRenderError if performed?
|
raise DoubleRenderError if performed?
|
||||||
logger.info("Redirected to #{options}") if logger
|
logger.info("Redirected to #{options}") if logger && logger.info?
|
||||||
response.redirect(options)
|
response.redirect(options, interpret_status(status))
|
||||||
response.redirected_to = options
|
response.redirected_to = options
|
||||||
@performed_redirect = true
|
@performed_redirect = true
|
||||||
|
|
||||||
when String
|
when String
|
||||||
redirect_to(request.protocol + request.host_with_port + options)
|
redirect_to(request.protocol + request.host_with_port + options, :status=>status)
|
||||||
|
|
||||||
when :back
|
when :back
|
||||||
request.env["HTTP_REFERER"] ? redirect_to(request.env["HTTP_REFERER"]) : raise(RedirectBackError)
|
request.env["HTTP_REFERER"] ? redirect_to(request.env["HTTP_REFERER"], :status=>status) : raise(RedirectBackError)
|
||||||
|
|
||||||
when Hash
|
when Hash
|
||||||
redirect_to(url_for(options))
|
redirect_to(url_for(options), :status=>status)
|
||||||
response.redirected_to = options
|
response.redirected_to = options
|
||||||
|
|
||||||
else
|
else
|
||||||
redirect_to(url_for(options))
|
redirect_to(url_for(options), :status=>status)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -28,8 +28,8 @@ module ActionController
|
||||||
charset.blank? ? nil : charset.strip.split("=")[1]
|
charset.blank? ? nil : charset.strip.split("=")[1]
|
||||||
end
|
end
|
||||||
|
|
||||||
def redirect(to_url, permanently = false)
|
def redirect(to_url, response_status)
|
||||||
self.headers["Status"] = "302 Found" unless headers["Status"] == "301 Moved Permanently"
|
self.headers["Status"] = response_status
|
||||||
self.headers["Location"] = to_url
|
self.headers["Location"] = to_url
|
||||||
|
|
||||||
self.body = "<html><body>You are being <a href=\"#{to_url}\">redirected</a>.</body></html>"
|
self.body = "<html><body>You are being <a href=\"#{to_url}\">redirected</a>.</body></html>"
|
||||||
|
|
|
@ -24,6 +24,34 @@ class RedirectController < ActionController::Base
|
||||||
redirect_to :action => "hello_world"
|
redirect_to :action => "hello_world"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def redirect_with_status
|
||||||
|
redirect_to({:action => "hello_world", :status => 301})
|
||||||
|
end
|
||||||
|
|
||||||
|
def redirect_with_status_hash
|
||||||
|
redirect_to({:action => "hello_world"}, {:status => 301})
|
||||||
|
end
|
||||||
|
|
||||||
|
def url_redirect_with_status
|
||||||
|
redirect_to("http://www.example.com", :status => :moved_permanently)
|
||||||
|
end
|
||||||
|
|
||||||
|
def url_redirect_with_status_hash
|
||||||
|
redirect_to("http://www.example.com", {:status => 301})
|
||||||
|
end
|
||||||
|
|
||||||
|
def relative_url_redirect_with_status
|
||||||
|
redirect_to("/things/stuff", :status => :found)
|
||||||
|
end
|
||||||
|
|
||||||
|
def relative_url_redirect_with_status_hash
|
||||||
|
redirect_to("/things/stuff", {:status => 301})
|
||||||
|
end
|
||||||
|
|
||||||
|
def redirect_to_back_with_status
|
||||||
|
redirect_to :back, :status => 307
|
||||||
|
end
|
||||||
|
|
||||||
def host_redirect
|
def host_redirect
|
||||||
redirect_to :action => "other_host", :only_path => false, :host => 'other.test.host'
|
redirect_to :action => "other_host", :only_path => false, :host => 'other.test.host'
|
||||||
end
|
end
|
||||||
|
@ -72,6 +100,56 @@ class RedirectTest < Test::Unit::TestCase
|
||||||
assert_equal "http://test.host/redirect/hello_world", redirect_to_url
|
assert_equal "http://test.host/redirect/hello_world", redirect_to_url
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_redirect_with_no_status
|
||||||
|
get :simple_redirect
|
||||||
|
assert_response 302
|
||||||
|
assert_equal "http://test.host/redirect/hello_world", redirect_to_url
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_redirect_with_status
|
||||||
|
get :redirect_with_status
|
||||||
|
assert_response 301
|
||||||
|
assert_equal "http://test.host/redirect/hello_world", redirect_to_url
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_redirect_with_status_hash
|
||||||
|
get :redirect_with_status_hash
|
||||||
|
assert_response 301
|
||||||
|
assert_equal "http://test.host/redirect/hello_world", redirect_to_url
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_url_redirect_with_status
|
||||||
|
get :url_redirect_with_status
|
||||||
|
assert_response 301
|
||||||
|
assert_equal "http://www.example.com", redirect_to_url
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_url_redirect_with_status_hash
|
||||||
|
get :url_redirect_with_status_hash
|
||||||
|
assert_response 301
|
||||||
|
assert_equal "http://www.example.com", redirect_to_url
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
def test_relative_url_redirect_with_status
|
||||||
|
get :relative_url_redirect_with_status
|
||||||
|
assert_response 302
|
||||||
|
assert_equal "http://test.host/things/stuff", redirect_to_url
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_relative_url_redirect_with_status_hash
|
||||||
|
get :relative_url_redirect_with_status_hash
|
||||||
|
assert_response 301
|
||||||
|
assert_equal "http://test.host/things/stuff", redirect_to_url
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_redirect_to_back_with_status
|
||||||
|
@request.env["HTTP_REFERER"] = "http://www.example.com/coming/from"
|
||||||
|
get :redirect_to_back_with_status
|
||||||
|
assert_response 307
|
||||||
|
assert_equal "http://www.example.com/coming/from", redirect_to_url
|
||||||
|
end
|
||||||
|
|
||||||
def test_simple_redirect_using_options
|
def test_simple_redirect_using_options
|
||||||
get :host_redirect
|
get :host_redirect
|
||||||
assert_response :redirect
|
assert_response :redirect
|
||||||
|
|
Loading…
Reference in a new issue