From 20fece149185d7eed03d464b1bbc8a7636bb4f98 Mon Sep 17 00:00:00 2001 From: Christiaan Van den Poel Date: Thu, 15 May 2014 16:08:53 +0200 Subject: [PATCH] fixes stack level too deep exception on action named 'status' returning 'head :ok' --- actionpack/CHANGELOG.md | 7 +++++ actionpack/lib/action_controller/metal.rb | 4 +++ .../lib/action_controller/metal/head.rb | 2 +- .../metal/rack_delegation.rb | 2 +- .../lib/action_dispatch/http/response.rb | 3 ++ .../test/controller/integration_test.rb | 31 +++++++++++++++++++ 6 files changed, 47 insertions(+), 2 deletions(-) diff --git a/actionpack/CHANGELOG.md b/actionpack/CHANGELOG.md index d54e47a658..a18ff54fa3 100644 --- a/actionpack/CHANGELOG.md +++ b/actionpack/CHANGELOG.md @@ -119,4 +119,11 @@ *Tony Wooster* +* Fix 'Stack level too deep' when rendering `head :ok` in an action method + called 'status' in a controller. + + Fixes #13905 + + *Christiaan Van den Poel* + Please check [4-1-stable](https://github.com/rails/rails/blob/4-1-stable/actionpack/CHANGELOG.md) for previous changes. diff --git a/actionpack/lib/action_controller/metal.rb b/actionpack/lib/action_controller/metal.rb index 0f4cc7a8f5..696fbf6e09 100644 --- a/actionpack/lib/action_controller/metal.rb +++ b/actionpack/lib/action_controller/metal.rb @@ -232,5 +232,9 @@ module ActionController new.dispatch(name, klass.new(env)) end end + + def _status_code + @_status + end end end diff --git a/actionpack/lib/action_controller/metal/head.rb b/actionpack/lib/action_controller/metal/head.rb index 43407f5b78..84a9112144 100644 --- a/actionpack/lib/action_controller/metal/head.rb +++ b/actionpack/lib/action_controller/metal/head.rb @@ -27,7 +27,7 @@ module ActionController self.status = status self.location = url_for(location) if location - if include_content?(self.status) + if include_content?(self._status_code) self.content_type = content_type || (Mime[formats.first] if formats) self.response.charset = false if self.response self.response_body = " " diff --git a/actionpack/lib/action_controller/metal/rack_delegation.rb b/actionpack/lib/action_controller/metal/rack_delegation.rb index bdf6e88699..6921834044 100644 --- a/actionpack/lib/action_controller/metal/rack_delegation.rb +++ b/actionpack/lib/action_controller/metal/rack_delegation.rb @@ -6,7 +6,7 @@ module ActionController extend ActiveSupport::Concern delegate :headers, :status=, :location=, :content_type=, - :status, :location, :content_type, :to => "@_response" + :status, :location, :content_type, :_status_code, :to => "@_response" def dispatch(action, request) set_response!(request) diff --git a/actionpack/lib/action_dispatch/http/response.rb b/actionpack/lib/action_dispatch/http/response.rb index 3d27ff2b24..eaea93b730 100644 --- a/actionpack/lib/action_dispatch/http/response.rb +++ b/actionpack/lib/action_dispatch/http/response.rb @@ -296,6 +296,9 @@ module ActionDispatch # :nodoc: cookies end + def _status_code + @status + end private def before_committed diff --git a/actionpack/test/controller/integration_test.rb b/actionpack/test/controller/integration_test.rb index 200a2dcc47..214eab2f0d 100644 --- a/actionpack/test/controller/integration_test.rb +++ b/actionpack/test/controller/integration_test.rb @@ -775,3 +775,34 @@ class UrlOptionsIntegrationTest < ActionDispatch::IntegrationTest assert_equal "/foo/1/edit", url_for(:action => 'edit', :only_path => true) end end + +class HeadWithStatusActionIntegrationTest < ActionDispatch::IntegrationTest + class FooController < ActionController::Base + def status + head :ok + end + end + + def self.routes + @routes ||= ActionDispatch::Routing::RouteSet.new + end + + def self.call(env) + routes.call(env) + end + + def app + self.class + end + + routes.draw do + get "/foo/status" => 'head_with_status_action_integration_test/foo#status' + end + + test "get /foo/status with head result does not cause stack overflow error" do + assert_nothing_raised do + get '/foo/status' + end + assert_response :ok + end +end