diff --git a/actionpack/CHANGELOG.md b/actionpack/CHANGELOG.md index d726b82e96..c428021bcd 100644 --- a/actionpack/CHANGELOG.md +++ b/actionpack/CHANGELOG.md @@ -1,3 +1,8 @@ +* Fix `follow_redirect!` to follow redirection with same HTTP verb when following + a 308 redirection. + + *Alan Tan* + * When multiple domains are specified for a cookie, a domain will now be chosen only if it is equal to or is a superdomain of the request host. diff --git a/actionpack/lib/action_dispatch/testing/integration.rb b/actionpack/lib/action_dispatch/testing/integration.rb index 1aef36d0cd..b77ffcc638 100644 --- a/actionpack/lib/action_dispatch/testing/integration.rb +++ b/actionpack/lib/action_dispatch/testing/integration.rb @@ -54,16 +54,21 @@ module ActionDispatch # Follow a single redirect response. If the last response was not a # redirect, an exception will be raised. Otherwise, the redirect is - # performed on the location header. If the redirection is a 307 redirect, + # performed on the location header. If the redirection is a 307 or 308 redirect, # the same HTTP verb will be used when redirecting, otherwise a GET request # will be performed. Any arguments are passed to the # underlying request. def follow_redirect!(**args) raise "not a redirect! #{status} #{status_message}" unless redirect? - method = response.status == 307 ? request.method.downcase : :get - public_send(method, response.location, **args) + method = + if [307, 308].include?(response.status) + request.method.downcase + else + :get + end + public_send(method, response.location, **args) status end end diff --git a/actionpack/test/controller/integration_test.rb b/actionpack/test/controller/integration_test.rb index 81027ba00b..2b73a471f4 100644 --- a/actionpack/test/controller/integration_test.rb +++ b/actionpack/test/controller/integration_test.rb @@ -235,6 +235,10 @@ class IntegrationProcessTest < ActionDispatch::IntegrationTest redirect_to action_url("post"), status: 307 end + def redirect_308 + redirect_to action_url("post"), status: 308 + end + def remove_header response.headers.delete params[:header] head :ok, "c" => "3" @@ -368,6 +372,15 @@ class IntegrationProcessTest < ActionDispatch::IntegrationTest end end + def test_308_redirect_uses_the_same_http_verb + with_test_route_set do + post "/redirect_308" + assert_equal 308, status + follow_redirect! + assert_equal "POST", request.method + end + end + def test_redirect_reset_html_document with_test_route_set do get "/redirect"