Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Header fields should be case insensitive (RFC 7230 §3.2, RFC 9110 §5.1) #735

Open
tgrushka opened this issue Dec 13, 2024 · 1 comment

Comments

@tgrushka
Copy link

I'm working with http::HeaderMap and noticed that HeaderMap::get, HeaderMap::insert, and HeaderName::from_static all seem to be case sensitive (in fact, the latter panics:

HeaderName::from_static("Content-Type")

panics with:

index out of bounds: the len is 0 but the index is 0

while:

HeaderName::from_static("content-type")

does not.

This goes against the HTTP spec requiring case-insensitive handling of header values:

  • RFC 7230 §3.2

    Each header field consists of a case-insensitive field name followed by a colon (":"), optional leading whitespace, the field value, and optional trailing whitespace.

  • RFC 9110 §5.1

    Field names are case-insensitive...

IMO, this is distinct from #670, and in fact case-insensitive keys should solve that issue as well, while not requiring the original cases to be changed.

It looks like crates like case_insensitive_hashmap and unicase are examples of case-insensitive String handling.

Is there any way to just make the HeaderMap case-insensitive for retrieval? That would preserve original case as well as allow any case for HeaderMap::get to meet the spec and prevent errors.

@seanmonstar
Copy link
Member

HeaderName does support any casing, depending on how you use it. If you are parsing dynamic strings, such as with TryFrom or FromStr or from_bytes, etc, then it will handle and normalize the casing.

What you've noticed is that using a static string will enforce that the casing is lowercase. That was decided because static string likely means you have access to it at compile-time, so we can enforce that it is the optimal case. If you want dynamic casing, parse the values as a HeaderName first.

For some more background, there's some explanation in https://docs.rs/http/latest/http/header/index.html.

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

No branches or pull requests

2 participants