-
Notifications
You must be signed in to change notification settings - Fork 321
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
Non capitalized HTTP headers #524
Comments
I believe this is a dupe of #337, but I'll let @ixti confirm that. This gem canonicalizes both request and response headers. We've discussed disabling the canonicalization for requests, which I think is the most straightforward solution. We could also make it configurable on a request and response basis, e.g.: HTTP.canonicalize_headers(false)
HTTP.canonicalize_headers(:request)
HTTP.canonicalize_headers(:response)
HTTP.canonicailze_headers(:all) ...or thereabouts. |
Yeah it's a dupe. And I'm going to work on this soon. Finally have an idea in my head how to provide predictable API without intorducing public API changes. Will layout the idea as code soon so that discussion will be started :D But in few words, my idea is to change # imagine repsonse was sent with headers:
# foo_bar: 123
response.headers["Foo-Bar"] # => ["123"]
response.headers["foo_bar"] # => ["123"]
response.headers.keys # => ["foo_bar"] When passing headers, that's pretty much the only public API change that will be needed:
|
@ixti neat! SGTM 👍 |
Hi! Just came across this issue while checking to see if anyone had run into the problem we are currently dealing with. An API we need to communicate with requires a particular header be specified with an underscore in the header name. It's otherwise case-insensitive. HTTP.rb makes it impossible to pass a header in an underscore because of this line, which transforms it to Line 206 in e31d0a5
I would argue that the behavior of |
@brasic yes - I'm working on refactoring HTTP::Headers completely so that it will llow to pass any RFC compliant header (with or without normalization). |
any update for this? I still got the issue. |
I had no time to work on this yet. |
Just ran into this again, dealing with an API that has case-sensitive headers. That may be "wrong" on their side, but it is what it is, and switching http libraries is much easier than getting an external API to change their behavior. |
@joshuaflanagan I think if you implemented the change @ixti suggested here it'd be accepted, and shouldn't be too difficult: #524 (comment) |
The original behavior was to normalize all header names so that they were broken up into words, delimited by `-` or `_`, capitalize each word, and then join the words together with a `_`. This made it impossible to make a request with an underscore in the header name, or with a different casing (ex: all caps). However, the normalized name made it possible to access (or delete) headers, without having to know the exact casing. The new behavior is based on the following rules (as specified in httprb#524 (comment)) 1) Fail if a header name is not specified as a String or Symbol 2) If the header name is specified as a Symbol, normalize it when writing it in a request. If the header name is specified as a String, preserve it as-is when writing it in a request. 3) Allow lookup of any header using the normalized form of the name I implemented this behavior by storing three elements for each header value: 1) normalized header name 2) header name as it will be written in a request 3) header value Element 2 is the new addition. I considered just storing the header value as it would be written, and only doing normalization during lookup, but it seemed wasteful to potentially normalize the same value over and over when searching through the list for various lookups. This way we only normalize each name once, and can continue to use that value for lookups. However, whenever asked for the contents (ex: via `each` or `keys`) we return the new, non-normalized name. Fixes: httprb#524
The original behavior was to normalize all header names so that they were broken up into words, delimited by `-` or `_`, capitalize each word, and then join the words together with a `-`. This made it impossible to make a request with an underscore in the header name, or with a different casing (ex: all caps). However, the normalized name made it possible to access (or delete) headers, without having to know the exact casing. The new behavior is based on the following rules (as specified in httprb#524 (comment)) 1) Fail if a header name is not specified as a String or Symbol 2) If the header name is specified as a Symbol, normalize it when writing it in a request. If the header name is specified as a String, preserve it as-is when writing it in a request. 3) Allow lookup of any header using the normalized form of the name I implemented this behavior by storing three elements for each header value: 1) normalized header name 2) header name as it will be written in a request 3) header value Element 2 is the new addition. I considered just storing the header value as it would be written, and only doing normalization during lookup, but it seemed wasteful to potentially normalize the same value over and over when searching through the list for various lookups. This way we only normalize each name once, and can continue to use that value for lookups. However, whenever asked for the contents (ex: via `each` or `keys`) we return the new, non-normalized name. Fixes: httprb#524
The original behavior was to normalize all header names so that they were broken up into words, delimited by `-` or `_`, capitalize each word, and then join the words together with a `-`. This made it impossible to make a request with an underscore in the header name, or with a different casing (ex: all caps). However, the normalized name made it possible to access (or delete) headers, without having to know the exact casing. The new behavior is based on the following rules (as specified in httprb#524 (comment)) 1) Fail if a header name is not specified as a String or Symbol 2) If the header name is specified as a Symbol, normalize it when writing it in a request. If the header name is specified as a String, preserve it as-is when writing it in a request. 3) Allow lookup of any header using the normalized form of the name I implemented this behavior by storing three elements for each header value: 1) normalized header name 2) header name as it will be written in a request 3) header value Element 2 is the new addition. I considered just storing the header value as it would be written, and only doing normalization during lookup, but it seemed wasteful to potentially normalize the same value over and over when searching through the list for various lookups. This way we only normalize each name once, and can continue to use that value for lookups. However, whenever asked for the contents (ex: via `each` or `keys`) we return the new, non-normalized name. Fixes: httprb#524
The original behavior was to normalize all header names so that they were broken up into words, delimited by `-` or `_`, capitalize each word, and then join the words together with a `-`. This made it impossible to make a request with an underscore in the header name, or with a different casing (ex: all caps). However, the normalized name made it possible to access (or delete) headers, without having to know the exact casing. The new behavior is based on the following rules (as specified in httprb#524 (comment)) 1) Fail if a header name is not specified as a String or Symbol 2) If the header name is specified as a Symbol, normalize it when writing it in a request. If the header name is specified as a String, preserve it as-is when writing it in a request. 3) Allow lookup of any header using the normalized form of the name I implemented this behavior by storing three elements for each header value: 1) normalized header name 2) header name as it will be written in a request 3) header value Element 2 is the new addition. I considered just storing the header value as it would be written, and only doing normalization during lookup, but it seemed wasteful to potentially normalize the same value over and over when searching through the list for various lookups. This way we only normalize each name once, and can continue to use that value for lookups. However, whenever asked for the contents (ex: via `each` or `keys`) we return the new, non-normalized name. Fixes: httprb#524
The original behavior was to normalize all header names so that they were broken up into words, delimited by `-` or `_`, capitalize each word, and then join the words together with a `-`. This made it impossible to make a request with an underscore in the header name, or with a different casing (ex: all caps). However, the normalized name made it possible to access (or delete) headers, without having to know the exact casing. The new behavior is based on the following rules (as specified in httprb#524 (comment)) 1) Fail if a header name is not specified as a String or Symbol 2) If the header name is specified as a Symbol, normalize it when writing it in a request. If the header name is specified as a String, preserve it as-is when writing it in a request. 3) Allow lookup of any header using the normalized form of the name I implemented this behavior by storing three elements for each header value: 1) normalized header name 2) header name as it will be written in a request 3) header value Element 2 is the new addition. I considered just storing the header value as it would be written, and only doing normalization during lookup, but it seemed wasteful to potentially normalize the same value over and over when searching through the list for various lookups. This way we only normalize each name once, and can continue to use that value for lookups. However, whenever asked for the contents (ex: via `each` or `keys`) we return the new, non-normalized name. Fixes: httprb#524
The original behavior was to normalize all header names so that they were broken up into words, delimited by `-` or `_`, capitalize each word, and then join the words together with a `-`. This made it impossible to make a request with an underscore in the header name, or with a different casing (ex: all caps). However, the normalized name made it possible to access (or delete) headers, without having to know the exact casing. The new behavior is based on the following rules (as specified in #524 (comment)) 1) Fail if a header name is not specified as a String or Symbol 2) If the header name is specified as a Symbol, normalize it when writing it in a request. If the header name is specified as a String, preserve it as-is when writing it in a request. 3) Allow lookup of any header using the normalized form of the name I implemented this behavior by storing three elements for each header value: 1) normalized header name 2) header name as it will be written in a request 3) header value Element 2 is the new addition. I considered just storing the header value as it would be written, and only doing normalization during lookup, but it seemed wasteful to potentially normalize the same value over and over when searching through the list for various lookups. This way we only normalize each name once, and can continue to use that value for lookups. However, whenever asked for the contents (ex: via `each` or `keys`) we return the new, non-normalized name. Fixes: #524
Sorry for a dumb question.
I have to work with an API server which deals HTTP headers in case-sensitive manner.
(Yep I know that is a RFC violation)
Is there a good way to send non-capitalized HTTP headers?
The text was updated successfully, but these errors were encountered: