Do not include default response headers for AC::Metal

In Rails 4.2, `ActionController::Metal` controllers did not include the
default headers from `ActionDispatch::Response`. However, through e16afe6, and a
general shift towards having `ActionController::Metal` objects contain
`ActionDispatch::Response` objects (instead of just returning an array
of status, headers, and body), this behavior was lost. This PR helps to
restore the original behavior by having `ActionController::Metal`
controllers generate Response objects without the default headers, while
`ActionController::Base` now overrides the factory method to make sure
its version does have the default headers.
This commit is contained in:
Jon Moss 2017-03-29 17:36:54 -04:00
parent f77a6be8d2
commit 9d695743de
4 changed files with 64 additions and 1 deletions

View File

@ -261,6 +261,12 @@ module ActionController
PROTECTED_IVARS
end
def self.make_response!(request)
ActionDispatch::Response.create.tap do |res|
res.request = request
end
end
ActiveSupport.run_load_hooks(:action_controller, self)
end
end

View File

@ -129,7 +129,7 @@ module ActionController
end
def self.make_response!(request)
ActionDispatch::Response.create.tap do |res|
ActionDispatch::Response.new.tap do |res|
res.request = request
end
end

View File

@ -11,6 +11,12 @@ end
class EmptyController < ActionController::Base
end
class SimpleController < ActionController::Base
def hello
self.response_body = "hello"
end
end
class NonEmptyController < ActionController::Base
def public_action
head :ok
@ -118,6 +124,27 @@ class ControllerInstanceTests < ActiveSupport::TestCase
controller = klass.new
assert_equal "examples", controller.controller_path
end
def test_response_has_default_headers
original_default_headers = ActionDispatch::Response.default_headers
ActionDispatch::Response.default_headers = {
"X-Frame-Options" => "DENY",
"X-Content-Type-Options" => "nosniff",
"X-XSS-Protection" => "1;"
}
response_headers = SimpleController.action("hello").call(
"REQUEST_METHOD" => "GET",
"rack.input" => -> {}
)[1]
assert response_headers.key?("X-Frame-Options")
assert response_headers.key?("X-Content-Type-Options")
assert response_headers.key?("X-XSS-Protection")
ensure
ActionDispatch::Response.default_headers = original_default_headers
end
end
class PerformActionTest < ActionController::TestCase

View File

@ -0,0 +1,30 @@
require "abstract_unit"
class MetalControllerInstanceTests < ActiveSupport::TestCase
class SimpleController < ActionController::Metal
def hello
self.response_body = "hello"
end
end
def test_response_has_default_headers
original_default_headers = ActionDispatch::Response.default_headers
ActionDispatch::Response.default_headers = {
"X-Frame-Options" => "DENY",
"X-Content-Type-Options" => "nosniff",
"X-XSS-Protection" => "1;"
}
response_headers = SimpleController.action("hello").call(
"REQUEST_METHOD" => "GET",
"rack.input" => -> {}
)[1]
refute response_headers.key?("X-Frame-Options")
refute response_headers.key?("X-Content-Type-Options")
refute response_headers.key?("X-XSS-Protection")
ensure
ActionDispatch::Response.default_headers = original_default_headers
end
end