diff options
author | Derek Prior <derekprior@gmail.com> | 2015-12-16 09:41:47 -0500 |
---|---|---|
committer | Derek Prior <derekprior@gmail.com> | 2015-12-16 11:42:25 -0500 |
commit | dc4429ca3b21005d0016fca78967c2ebbe9677c9 (patch) | |
tree | 57651dd8a204da68fba0d3e800d413193fb67389 /actionpack | |
parent | 13fd5586cef628a71e0e2900820010742a911099 (diff) | |
download | rails-dc4429ca3b21005d0016fca78967c2ebbe9677c9.tar.gz rails-dc4429ca3b21005d0016fca78967c2ebbe9677c9.tar.bz2 rails-dc4429ca3b21005d0016fca78967c2ebbe9677c9.zip |
Deprecate `redirect_to :back`
Applications that use `redirect_to :back` can be forced to 500 by
clients that do not send the HTTP `Referer` (sic) header.
`redirect_back` requires the user to consider this possibility up front
and avoids this trivially-caused application error.
Diffstat (limited to 'actionpack')
-rw-r--r-- | actionpack/CHANGELOG.md | 6 | ||||
-rw-r--r-- | actionpack/lib/action_controller/metal/redirecting.rb | 16 | ||||
-rw-r--r-- | actionpack/test/controller/redirect_test.rb | 17 |
3 files changed, 27 insertions, 12 deletions
diff --git a/actionpack/CHANGELOG.md b/actionpack/CHANGELOG.md index bdc0fbe01a..8b2943af74 100644 --- a/actionpack/CHANGELOG.md +++ b/actionpack/CHANGELOG.md @@ -1,3 +1,9 @@ +* Deprecate `redirect_to :back` in favor of `redirect_back`, which accepts a + required `fallback_location` argument, thus eliminating the possibility of a + `RedirectBackError`. + + *Derek Prior* + * Add `redirect_back` method to `ActionController::Redirecting` to provide a way to safely redirect to the `HTTP_REFERER` if it is present, falling back to a provided redirect otherwise. diff --git a/actionpack/lib/action_controller/metal/redirecting.rb b/actionpack/lib/action_controller/metal/redirecting.rb index 72ceb9a5bc..aeecb48f85 100644 --- a/actionpack/lib/action_controller/metal/redirecting.rb +++ b/actionpack/lib/action_controller/metal/redirecting.rb @@ -20,8 +20,6 @@ module ActionController # * <tt>String</tt> starting with <tt>protocol://</tt> (like <tt>http://</tt>) or a protocol relative reference (like <tt>//</tt>) - Is passed straight through as the target for redirection. # * <tt>String</tt> not containing a protocol - The current protocol and host is prepended to the string. # * <tt>Proc</tt> - A block that will be executed in the controller's context. Should return any option accepted by +redirect_to+. - # * <tt>:back</tt> - Back to the page that issued the request. Useful for forms that are triggered from multiple places. - # Short-hand for <tt>redirect_to(request.env["HTTP_REFERER"])</tt> # # === Examples: # @@ -30,7 +28,6 @@ module ActionController # redirect_to "http://www.rubyonrails.org" # redirect_to "/images/screenshot.jpg" # redirect_to articles_url - # redirect_to :back # redirect_to proc { edit_post_url(@post) } # # The redirection happens as a "302 Found" header unless otherwise specified using the <tt>:status</tt> option: @@ -61,10 +58,6 @@ module ActionController # 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, - # <tt>ActionController::RedirectBackError</tt> will be raised. You - # may specify some fallback behavior for this case by rescuing - # <tt>ActionController::RedirectBackError</tt>. def redirect_to(options = {}, response_status = {}) #:doc: raise ActionControllerError.new("Cannot redirect to nil!") unless options raise ActionControllerError.new("Cannot redirect to a parameter hash!") if options.is_a?(ActionController::Parameters) @@ -78,9 +71,6 @@ module ActionController # Redirects the browser to the page that issued the request if possible, # otherwise redirects to provided default fallback location. # - # This avoids the <tt>ActionController::RedirectBackError</tt> that can - # occur if the request has no associated <tt>HTTP_REFERER</tt>. - # # redirect_back fallback_location: { action: "show", id: 5 } # redirect_back fallback_location: post # redirect_back fallback_location: "http://www.rubyonrails.org" @@ -110,6 +100,12 @@ module ActionController when String request.protocol + request.host_with_port + options when :back + ActiveSupport::Deprecation.warn(<<-MESSAGE.squish) + `redirect_to :back` is deprecated and will be removed from Rails 5.1. + Please use `redirect_back(fallback_location: fallback_location)` where + `fallback_location` represents the location to use if the request has + no HTTP referer information. + MESSAGE request.headers["Referer"] or raise RedirectBackError when Proc _compute_redirect_to_location request, options.call diff --git a/actionpack/test/controller/redirect_test.rb b/actionpack/test/controller/redirect_test.rb index 28ff1f36cf..21dfd9cd03 100644 --- a/actionpack/test/controller/redirect_test.rb +++ b/actionpack/test/controller/redirect_test.rb @@ -191,7 +191,11 @@ class RedirectTest < ActionController::TestCase def test_redirect_to_back_with_status @request.env["HTTP_REFERER"] = "http://www.example.com/coming/from" - get :redirect_to_back_with_status + + assert_deprecated do + get :redirect_to_back_with_status + end + assert_response 307 assert_equal "http://www.example.com/coming/from", redirect_to_url end @@ -240,7 +244,11 @@ class RedirectTest < ActionController::TestCase def test_redirect_to_back @request.env["HTTP_REFERER"] = "http://www.example.com/coming/from" - get :redirect_to_back + + assert_deprecated do + get :redirect_to_back + end + assert_response :redirect assert_equal "http://www.example.com/coming/from", redirect_to_url end @@ -248,6 +256,11 @@ class RedirectTest < ActionController::TestCase def test_redirect_to_back_with_no_referer assert_raise(ActionController::RedirectBackError) { @request.env["HTTP_REFERER"] = nil + + assert_deprecated do + get :redirect_to_back + end + get :redirect_to_back } end |