Merge pull request #47091 from ioquatix/rack-3-case-insensitive-headers

Use Rack's own headers classes where appropriate.
This commit is contained in:
Rafael Mendonça França 2023-01-25 17:22:47 -05:00 committed by GitHub
commit 2cf8740e15
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 29 additions and 42 deletions

View File

@ -40,6 +40,7 @@ module ActionDispatch
class IllegalStateError < StandardError
end
deprecate_constant :IllegalStateError
class MissingController < NameError
end

View File

@ -32,27 +32,14 @@ module ActionDispatch # :nodoc:
# end
# end
class Response
class Header < DelegateClass(Hash) # :nodoc:
def initialize(response, header)
@response = response
super(header)
end
def []=(k, v)
if @response.sending? || @response.sent?
raise ActionDispatch::IllegalStateError, "header already sent"
end
super
end
def merge(other)
self.class.new @response, __getobj__.merge(other)
end
def to_hash
__getobj__.dup
end
begin
# For `Rack::Headers` (Rack 3+):
require "rack/headers"
Header = ::Rack::Headers
rescue LoadError
# For `Rack::Utils::HeaderHash`:
require "rack/utils"
Header = ::Rack::Utils::HeaderHash
end
# The request that the response is responding to.
@ -168,10 +155,14 @@ module ActionDispatch # :nodoc:
# The underlying body, as a streamable object.
attr_reader :stream
def initialize(status = 200, header = {}, body = [])
def initialize(status = 200, header = nil, body = [])
super()
@header = Header.new(self, header)
@header = Header.new
header&.each do |key, value|
@header[key] = value
end
self.body, self.status = body, status
@ -461,8 +452,8 @@ module ActionDispatch # :nodoc:
# our last chance.
commit! unless committed?
headers.freeze
request.commit_cookie_jar! unless committed?
@header.freeze
@request.commit_cookie_jar! unless committed?
end
def build_buffer(response, body)

View File

@ -1086,8 +1086,11 @@ class ResponseDefaultHeadersTest < ActionController::TestCase
test "response contains default headers" do
get :leave_alone
# Response headers start out with the defaults
assert_equal @defaults.merge("Content-Type" => "text/html"), response.headers
expected_headers = @defaults.merge("Content-Type" => "text/html")
expected_headers.each do |key, value|
assert_equal value, @response.headers[key]
end
end
test "response deletes a default header" do

View File

@ -24,8 +24,9 @@ module ActionController
end
end
header = r.new.header
assert_kind_of(ActionController::Live::Response::Header, header)
headers = r.create.headers
assert_kind_of(ActionController::Live::Response::Header, headers)
assert_equal "g", headers["omg"]
end
def test_parallel
@ -98,11 +99,10 @@ module ActionController
latch.wait
assert_predicate @response.headers, :frozen?
e = assert_raises(ActionDispatch::IllegalStateError) do
assert_raises(FrozenError) do
@response.headers["Content-Length"] = "zomg"
end
assert_equal "header already sent", e.message
@response.stream.close
t.join
end
@ -112,10 +112,9 @@ module ActionController
# we can add data until it's actually written, which happens on `each`
@response.each { |x| }
e = assert_raises(ActionDispatch::IllegalStateError) do
assert_raises(FrozenError) do
@response.headers["Content-Length"] = "zomg"
end
assert_equal "header already sent", e.message
end
end
end

View File

@ -423,14 +423,12 @@ class ResponseHeadersTest < ActiveSupport::TestCase
test "has_header?" do
assert @response.has_header? "Foo"
assert_not @response.has_header? "foo"
assert_not @response.has_header? nil
assert @response.has_header? "foo"
end
test "get_header" do
assert_equal "1", @response.get_header("Foo")
assert_nil @response.get_header("foo")
assert_nil @response.get_header(nil)
assert_equal "1", @response.get_header("foo")
end
test "set_header" do
@ -444,11 +442,6 @@ class ResponseHeadersTest < ActiveSupport::TestCase
end
test "delete_header" do
assert_nil @response.delete_header(nil)
assert_nil @response.delete_header("foo")
assert @response.has_header?("Foo")
assert_equal "1", @response.delete_header("Foo")
assert_not @response.has_header?("Foo")
end