Support other optional parameters and quoted-strings on Content-Type parser

This commit is contained in:
r7kamura 2019-03-09 15:02:05 +09:00
parent 0771bd3ee8
commit 29b42f5e5c
2 changed files with 37 additions and 4 deletions

View File

@ -82,6 +82,7 @@ module ActionDispatch # :nodoc:
SET_COOKIE = "Set-Cookie"
LOCATION = "Location"
NO_CONTENT_CODES = [100, 101, 102, 204, 205, 304]
CONTENT_TYPE_PARSER = /\A(?<type>[^;\s]+)?(?:.*;\s*charset=(?<quote>"?)(?<charset>[^;\s]+)\k<quote>)?/ # :nodoc:
cattr_accessor :default_charset, default: "utf-8"
cattr_accessor :default_headers
@ -409,10 +410,8 @@ module ActionDispatch # :nodoc:
NullContentTypeHeader = ContentTypeHeader.new nil, nil
def parse_content_type(content_type)
if content_type
type, charset = content_type.split(/;\s*charset=/)
type = nil if type && type.empty?
ContentTypeHeader.new(type, charset)
if content_type && match = CONTENT_TYPE_PARSER.match(content_type)
ContentTypeHeader.new(match[:type], match[:charset])
else
NullContentTypeHeader
end

View File

@ -539,4 +539,38 @@ class ResponseIntegrationTest < ActionDispatch::IntegrationTest
assert_equal('"202cb962ac59075b964b07152d234b70"', @response.headers["ETag"])
assert_equal('"202cb962ac59075b964b07152d234b70"', @response.etag)
end
test "response Content-Type with optional parameters" do
@app = lambda { |env|
[
200,
{ "Content-Type" => "text/csv; charset=utf-16; header=present" },
["Hello"]
]
}
get "/"
assert_response :success
assert_equal("text/csv; charset=utf-16; header=present", @response.headers["Content-Type"])
assert_equal("text/csv", @response.content_type)
assert_equal("utf-16", @response.charset)
end
test "response Content-Type with quoted-string" do
@app = lambda { |env|
[
200,
{ "Content-Type" => 'text/csv; header=present; charset="utf-16"' },
["Hello"]
]
}
get "/"
assert_response :success
assert_equal('text/csv; header=present; charset="utf-16"', @response.headers["Content-Type"])
assert_equal("text/csv", @response.content_type)
assert_equal("utf-16", @response.charset)
end
end