diff --git a/actionpack/CHANGELOG.md b/actionpack/CHANGELOG.md index b907eea3c1e5187168fb7834a47f2b3302b0ae81..b4d50b7072487c7b762412d903cafd0b845246b9 100644 --- a/actionpack/CHANGELOG.md +++ b/actionpack/CHANGELOG.md @@ -1,5 +1,9 @@ ## Rails 4.0.0 (unreleased) ## +* Extracted redirect logic from `ActionController::ForceSSL::ClassMethods.force_ssl` into `ActionController::ForceSSL#force_ssl_redirect` + + *Jeremy Friesen* + * Make possible to use a block in button_to helper if button text is hard to fit into the name parameter, e.g.: diff --git a/actionpack/lib/action_controller/metal/force_ssl.rb b/actionpack/lib/action_controller/metal/force_ssl.rb index ac12cbb625566c099d5679064885ba2655e15614..77d799a38a784f52950b9aad18dd9cead4c03837 100644 --- a/actionpack/lib/action_controller/metal/force_ssl.rb +++ b/actionpack/lib/action_controller/metal/force_ssl.rb @@ -40,15 +40,23 @@ module ClassMethods def force_ssl(options = {}) host = options.delete(:host) before_filter(options) do - unless request.ssl? - redirect_options = {:protocol => 'https://', :status => :moved_permanently} - redirect_options.merge!(:host => host) if host - redirect_options.merge!(:params => request.query_parameters) - flash.keep if respond_to?(:flash) - redirect_to redirect_options - end + force_ssl_redirect(host) end end end + + # Redirect the existing request to use the HTTPS protocol. + # + # ==== Parameters + # * host - Redirect to a different host name + def force_ssl_redirect(host = nil) + unless request.ssl? + redirect_options = {:protocol => 'https://', :status => :moved_permanently} + redirect_options.merge!(:host => host) if host + redirect_options.merge!(:params => request.query_parameters) + flash.keep if respond_to?(:flash) + redirect_to redirect_options + end + end end end diff --git a/actionpack/test/controller/force_ssl_test.rb b/actionpack/test/controller/force_ssl_test.rb index 5b423c81519b7d18b2f7aa7de6055c61e28449d3..6758668b7a726ac8bdcb2e03663e848ef7620574 100644 --- a/actionpack/test/controller/force_ssl_test.rb +++ b/actionpack/test/controller/force_ssl_test.rb @@ -49,6 +49,15 @@ def use_flash end end +class RedirectToSSL < ForceSSLController + def banana + force_ssl_redirect || render(:text => 'monkey') + end + def cheeseburger + force_ssl_redirect('secure.cheeseburger.host') || render(:text => 'ihaz') + end +end + class ForceSSLControllerLevelTest < ActionController::TestCase tests ForceSSLControllerLevel @@ -149,3 +158,25 @@ def test_cheeseburger_redirects_to_https assert_equal "hello", assigns["flashy"] end end + +class RedirectToSSLTest < ActionController::TestCase + tests RedirectToSSL + def test_banana_redirects_to_https_if_not_https + get :banana + assert_response 301 + assert_equal "https://test.host/redirect_to_ssl/banana", redirect_to_url + end + + def test_cheeseburgers_redirects_to_https_with_new_host_if_not_https + get :cheeseburger + assert_response 301 + assert_equal "https://secure.cheeseburger.host/redirect_to_ssl/cheeseburger", redirect_to_url + end + + def test_banana_does_not_redirect_if_already_https + request.env['HTTPS'] = 'on' + get :cheeseburger + assert_response 200 + assert_equal 'ihaz', response.body + end +end \ No newline at end of file