From 1969f40a3a0aa7393b4815b7f7227c79f28b343a Mon Sep 17 00:00:00 2001 From: Edouard CHIN Date: Fri, 12 Oct 2018 02:06:13 -0400 Subject: fix `follow_redirect!` not using the same HTTP verb on 307 redirection: - According to the HTTP 1.1 spec, the 307 redirection guarantees that the method and the body will not be changed during redirection. This PR fixes that since follow_redirect! would always follow the redirection my making a GET request. Ref https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/307 --- actionpack/CHANGELOG.md | 5 +++++ actionpack/lib/action_dispatch/testing/integration.rb | 11 ++++++++--- actionpack/test/controller/integration_test.rb | 13 +++++++++++++ 3 files changed, 26 insertions(+), 3 deletions(-) (limited to 'actionpack') diff --git a/actionpack/CHANGELOG.md b/actionpack/CHANGELOG.md index 99a4ac6845..ca7ae6621b 100644 --- a/actionpack/CHANGELOG.md +++ b/actionpack/CHANGELOG.md @@ -1,3 +1,8 @@ +* Fix IntegrationTest `follow_redirect!` to follow redirection using the same HTTP verb when following + a 307 redirection. + + *Edouard Chin* + * System tests require Capybara 3.26 or newer. *George Claghorn* diff --git a/actionpack/lib/action_dispatch/testing/integration.rb b/actionpack/lib/action_dispatch/testing/integration.rb index c5f8b816a4..9e7b4301a8 100644 --- a/actionpack/lib/action_dispatch/testing/integration.rb +++ b/actionpack/lib/action_dispatch/testing/integration.rb @@ -49,11 +49,16 @@ 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. Any arguments are passed to the - # underlying call to `get`. + # performed on the location header. If the redirection is a 307 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? - get(response.location, **args) + + method = response.status == 307 ? request.method.downcase : :get + 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 cce229b30d..caacd66bd6 100644 --- a/actionpack/test/controller/integration_test.rb +++ b/actionpack/test/controller/integration_test.rb @@ -213,6 +213,10 @@ class IntegrationProcessTest < ActionDispatch::IntegrationTest redirect_to action_url("get") end + def redirect_307 + redirect_to action_url("post"), status: 307 + end + def remove_header response.headers.delete params[:header] head :ok, "c" => "3" @@ -337,6 +341,15 @@ class IntegrationProcessTest < ActionDispatch::IntegrationTest end end + def test_307_redirect_uses_the_same_http_verb + with_test_route_set do + post "/redirect_307" + assert_equal 307, status + follow_redirect! + assert_equal "POST", request.method + end + end + def test_redirect_reset_html_document with_test_route_set do get "/redirect" -- cgit v1.2.3