Skip to content

Conversation

@AllyMarthaJ
Copy link
Contributor

If a content type header is provided with a malformed part, there's no nice way of interpreting it since instead of being a key/value pair it's just a key.

I think the sensible option here is to assume, like in the case where a param is provided with an empty value, that the value is an empty string. I'm not super tied to this, though (for example, it could just as easily be omitted from the params entirely, or the value could simply be nil; each option are equally as valid).

issue: #2250

@ioquatix ioquatix requested a review from jeremyevans November 23, 2024 11:05
@AllyMarthaJ
Copy link
Contributor Author

I'm actually thinking it might be better to omit it from the hash because actually we don't know whether it's a key, value, neither, or both...

Copy link
Contributor

@jeremyevans jeremyevans left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Having it be an empty string is consistent with what we do for parameters themselves with nothing after the = ( e.g. ?key=), so that seems like the best way.

Could be useful to update CHANGELOG in this PR, but that can always be done later.

@ioquatix
Copy link
Member

Could you please add documentation somewhere explaining the behaviour?

@AllyMarthaJ AllyMarthaJ force-pushed the bugfix/content-charset-nil-value branch from a66d946 to a4b3d29 Compare November 24, 2024 01:35
@AllyMarthaJ
Copy link
Contributor Author

Done 🙂

@ioquatix
Copy link
Member

ioquatix commented Nov 24, 2024

Thanks.

Just to be clear, this isn't the same as query parsing:

irb(main):002> Rack::Utils.parse_query("charset")
=> {"charset"=>nil}
irb(main):003> Rack::Utils.parse_query("charset=")
=> {"charset"=>""}

I think @jeremyevans prefers to use empty string, but this isn't consistent with the current implementation (which uses nil).

WDYT?

@AllyMarthaJ
Copy link
Contributor Author

Huh. Okay. It might be slightly cheaper to cleave off the || '' and make it actually in line with query parsing 😛

Does anyone in reality make the distinction between "present, but unspecified" and "present, but empty" for this kind of parameter? I...don't think the spec cares about it.

@ioquatix
Copy link
Member

I personally think it's good to be consistent with the query parser, but that's just me. @jeremyevans may have a different opinion.

@jeremyevans
Copy link
Contributor

The description in #2250 is Headers with = in them without a trailing parameter result in a NoMethodError. Therefore, I assumed this behavior was the charset= case and not the charset case, in which case the empty string would be consistent with query parsing.

Note that using an empty string for both cases (with or without =) for charset params seems fine to me. Absent backwards compatibility issues, that is how we would treat query parsing, and this doesn't have the backwards compatibility issues.

@AllyMarthaJ
Copy link
Contributor Author

Yeah, apologies — the original issue's repro was wrong (I'll update that now), which is why it sat there for so long 😅
I'll update comments.

If a content type header is provided with a malformed part, there's no
nice way of interpreting it since instead of being a key/value pair it's
just a key.

Instead, we mimic the behaviour of query parameters and opt to return an
empty string in lieu of missing values—this way we can still identify
their presence, but won't blow up. The behaviour isn't identical, but
we're also not worried about backwards compatibility here (given the
alternative was exploding)

issue: rack#2250
@AllyMarthaJ AllyMarthaJ force-pushed the bugfix/content-charset-nil-value branch from a4b3d29 to b682120 Compare November 24, 2024 11:47
@AllyMarthaJ
Copy link
Contributor Author

Alrighty, I've opted to go with empty strings for both, and I've updated the doc.
Any chance we're moving to go with the same behaviour for the query parser in the future, or have we missed out on that one? 😛

@ioquatix
Copy link
Member

ioquatix commented Nov 24, 2024

I think it is hard to change the default behaviour of the query parser due to compatibility. It may be possible by using a feature flag and gracefully switching. Using a feature flag makes downstream testing harder (every library needs to test both ways = combinatoric explosion of testing configurations).

@ioquatix ioquatix merged commit 05e3997 into rack:main Nov 24, 2024
14 checks passed
@ioquatix
Copy link
Member

Thanks for your contribution.

@gstokkink
Copy link

@ioquatix can we get a release for this fix please? We're running into this on production 😄 Much appreciated and thanks for the hard work on this awesome gem!

Earlopain pushed a commit to Earlopain/rack that referenced this pull request Jan 30, 2025
If a content type header is provided with a malformed part, there's no
nice way of interpreting it since instead of being a key/value pair it's
just a key.

Instead, we mimic the behaviour of query parameters and opt to return an
empty string in lieu of missing values—this way we can still identify
their presence, but won't blow up. The behaviour isn't identical, but
we're also not worried about backwards compatibility here (given the
alternative was exploding)
ioquatix pushed a commit to Earlopain/rack that referenced this pull request Jan 30, 2025
If a content type header is provided with a malformed part, there's no
nice way of interpreting it since instead of being a key/value pair it's
just a key.

Instead, we mimic the behaviour of query parameters and opt to return an
empty string in lieu of missing values—this way we can still identify
their presence, but won't blow up. The behaviour isn't identical, but
we're also not worried about backwards compatibility here (given the
alternative was exploding)
ioquatix pushed a commit that referenced this pull request Jan 30, 2025
If a content type header is provided with a malformed part, there's no
nice way of interpreting it since instead of being a key/value pair it's
just a key.

Instead, we mimic the behaviour of query parameters and opt to return an
empty string in lieu of missing values—this way we can still identify
their presence, but won't blow up. The behaviour isn't identical, but
we're also not worried about backwards compatibility here (given the
alternative was exploding)

Co-authored-by: Ally <28497049+AllyMarthaJ@users.noreply.github.com>
@gstokkink
Copy link

@ioquatix thanks for releasing, much appreciated! 🙇

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants