diff options
author | r7kamura <r7kamura@gmail.com> | 2019-03-09 15:02:05 +0900 |
---|---|---|
committer | r7kamura <r7kamura@gmail.com> | 2019-03-10 16:48:10 +0900 |
commit | 29b42f5e5c80e4397cd02b556f28265ac3e62966 (patch) | |
tree | 30dfbdfcdb5b470126454e69a2e0547619fae39b | |
parent | 0771bd3ee891f8eaf822bb47f68f4d0266763728 (diff) | |
download | rails-29b42f5e5c80e4397cd02b556f28265ac3e62966.tar.gz rails-29b42f5e5c80e4397cd02b556f28265ac3e62966.tar.bz2 rails-29b42f5e5c80e4397cd02b556f28265ac3e62966.zip |
Support other optional parameters and quoted-strings on Content-Type parser
-rw-r--r-- | actionpack/lib/action_dispatch/http/response.rb | 7 | ||||
-rw-r--r-- | actionpack/test/dispatch/response_test.rb | 34 |
2 files changed, 37 insertions, 4 deletions
diff --git a/actionpack/lib/action_dispatch/http/response.rb b/actionpack/lib/action_dispatch/http/response.rb index 1d38942a31..69798f99e0 100644 --- a/actionpack/lib/action_dispatch/http/response.rb +++ b/actionpack/lib/action_dispatch/http/response.rb @@ -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 diff --git a/actionpack/test/dispatch/response_test.rb b/actionpack/test/dispatch/response_test.rb index 60817c1c4d..7758b0406a 100644 --- a/actionpack/test/dispatch/response_test.rb +++ b/actionpack/test/dispatch/response_test.rb @@ -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 |