Skip to content

Commit

Permalink
rails: Merge pull request #46916 from ioquatix/actionpack-direct-set_…
Browse files Browse the repository at this point in the history
…response

Commit: a4b098a12f937d1d35b747fcbcfc69b840ce59ae
  • Loading branch information
Aaron Patterson authored and sourcegraph-bot committed Jan 9, 2023
1 parent 9103b0e commit a217311
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 2 deletions.
16 changes: 14 additions & 2 deletions rails/actionpack/lib/action_controller/metal.rb
Original file line number Diff line number Diff line change
Expand Up @@ -186,9 +186,8 @@ def url_for(string)
end

def response_body=(body)
body = [body] unless body.nil? || body.respond_to?(:each)

if body
body = [body] if body.is_a?(String)
response.body = body
super
else
Expand All @@ -210,9 +209,22 @@ def dispatch(name, request, response) # :nodoc:
end

def set_response!(response) # :nodoc:
if @_response
_, _, body = @_response
body.close if body.respond_to?(:close)
end

@_response = response
end

# Assign the response and mark it as committed. No further processing will occur.
def response=(response)
set_response!(response)

# Force `performed?` to return true:
@_response_body = true
end

def set_request!(request) # :nodoc:
@_request = request
@_request.controller_instance = self
Expand Down
50 changes: 50 additions & 0 deletions rails/actionpack/test/controller/new_base/bare_metal_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,20 @@ class BareController < ActionController::Metal
def index
self.response_body = "Hello world"
end

def assign_response_array
self.response = [200, { "content-type" => "text/html" }, ["Hello world"]]
end

def assign_response_object
self.response = Rack::Response.new("Hello world", 200, { "content-type" => "text/html" })
end

def assign_response_body_proc
self.response_body = proc do |stream|
stream.close
end
end
end

class BareTest < ActiveSupport::TestCase
Expand All @@ -32,9 +46,45 @@ class BareTest < ActiveSupport::TestCase
controller.set_request!(ActionDispatch::Request.empty)
controller.set_response!(BareController.make_response!(controller.request))
controller.index

assert controller.performed?
assert_equal ["Hello world"], controller.response_body
end

test "can assign response array as part of the controller execution" do
controller = BareController.new
controller.set_request!(ActionDispatch::Request.empty)
controller.assign_response_array

assert controller.performed?
assert_equal true, controller.response_body
assert_equal 200, controller.response[0]
assert_equal "text/html", controller.response[1]["content-type"]
end

test "can assign response object as part of the controller execution" do
controller = BareController.new
controller.set_request!(ActionDispatch::Request.empty)
controller.assign_response_object

assert controller.performed?
assert_equal true, controller.response_body
assert_equal 200, controller.response.status
assert_equal "text/html", controller.response.headers["content-type"]
end

test "can assign response body streamable object as part of the controller execution" do
controller = BareController.new
controller.set_request!(ActionDispatch::Request.empty)
controller.set_response!(BareController.make_response!(controller.request))
controller.assign_response_body_proc

assert controller.performed?
assert controller.response_body.is_a?(Proc)
assert_equal 200, controller.response.status
assert controller.response.headers.empty?
end

test "connect a request to controller instance without dispatch" do
env = {}
controller = BareController.new
Expand Down

0 comments on commit a217311

Please sign in to comment.