Support other optional parameters and quoted-strings on Content-Type parser#35549
Support other optional parameters and quoted-strings on Content-Type parser#35549kamipo merged 1 commit intorails:masterfrom
Conversation
e439c35 to
52e6eee
Compare
There was a problem hiding this comment.
How about extract more descriptive regex as CONTENT_TYPE_PARSER?
CONTENT_TYPE_PARSER = /\A(?<type>[^;\s]+)(?:\s*;\s*charset=(?<charset>[^;\s]+))?/ # :nodoc:
def parse_content_type(content_type)
if content_type && match = CONTENT_TYPE_PARSER.match(content_type)
ContentTypeHeader.new(match[:type], match[:charset])
else
NullContentTypeHeader
end
endThere was a problem hiding this comment.
Looks pretty good. I'll change it soon.
By the way, https://tools.ietf.org/html/rfc7231#section-3.1.1.1 says text/csv; charset="utf-16" is a valid representation of Content-Type. I don't know if we should support this quoted-string in this pull request. What do you think of this, @kamipo? If we support this type of quoted-string, I think we have no choice but to use Regexp here anyway.
There was a problem hiding this comment.
Yeah, I'm fine to support quoted-string, that is easer and no complex.
There was a problem hiding this comment.
hmm, I'm trying to support these patterns by Regexp parser, but it's not so simple...
text/csv; charset="utf-16"; header=present
text/csv; header=present; charset="utf-16"
There was a problem hiding this comment.
Does any client send the text/csv; header=present; charset="utf-16"?
There was a problem hiding this comment.
Anyway, it could make just one regex.
CONTENT_TYPE_PARSER = /\A(?<type>[^;\s]+)(?:.*;\s*charset=(?<quote>"?)(?<charset>[^;\s]+)\k<quote>)?/ # :nodoc:There was a problem hiding this comment.
Does any client send the text/csv; header=present; charset="utf-16"?
ah, a Rails app in our company has this kind of code... 😇
(To be accurate, our app returns text/csv; header=present; charset=sjis)
Anyway, it could make just one regex.
Awesome! I pushed dc3c2ec, but slightly changed its Regexp like this:
/\A(?<type>[^;\s]+)?(?:.*;\s*charset=(?<quote>"?)(?<charset>[^;\s]+)\k<quote>)?/
^
added this `?`This is because its Content-Type might be half-cooked on #parsed_content_type_header and this make some existent tests to be failed. The code below is an example from test/dispatch/response_test.rb:
test "response charset and content type from railsish app" do
@app = lambda { |env|
ActionDispatch::Response.new.tap { |resp|
resp.charset = "utf-16"
# resp.headers['Content-Type'] #=> "; charset=utf-16" OMG ;(
resp.content_type = Mime[:xml]
resp.body = "Hello"
resp.request = ActionDispatch::Request.empty
}.to_a
}
get "/"
assert_response :success
assert_equal("utf-16", @response.charset)
assert_equal(Mime[:xml], @response.content_type)
assert_equal("application/xml; charset=utf-16", @response.headers["Content-Type"])
endThere was a problem hiding this comment.
# resp.headers['Content-Type'] #=> "; charset=utf-16" OMG ;(
I see... nice catch 👍
kamipo
left a comment
There was a problem hiding this comment.
Looks good to me.
Can you squash your commits?
dc3c2ec to
29b42f5
Compare
|
Thanks! |
Support other optional parameters and quoted-strings on Content-Type parser
…-charset" This reverts commit 4185881.
Revert 5-2-stable backport of #35549
Summary
There is a possibility that Content-Type header includes optional parameters other than
charset.As an example, to indicate the presence or absence of the header line, text/csv type has optional
headerparameter like this:To exclude this type of optional parameters from
#charset, I changed#parse_content_typeimplementation in this pull request.Other Information