-
Notifications
You must be signed in to change notification settings - Fork 115
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
Downcase headers when inserting/fetching in HPACK #172
Conversation
Before this commit, we would insert headers in the HPACK table without downcasing their name, and we would look up headers without downcasing their name either. With this commit, we downcase header names (since they're case insensitive) before inserting/looking up in the HPACK table. Closes #171.
The more efficient way would be to only
Another option would be to validate and return an error, not sure what is preferred. I do think we should do it at the boundary and not in HPACK. |
We can do the same we do for HTTP/1 https://github.com/ericmj/mint/blob/master/lib/mint/http1/request.ex#L33. |
I pushed an update that uses the lowercasing we had for HTTP/1. However, not sure we should do the downcasing at the boundary since I think HPACK should work in a semantically correct way so that if you insert |
I am not sure HPACK requires lower case header keys. I could only find it in the HTTP/2 spec. |
@ericmj updated the PR, we now downcase header names in HTTP/2 and HTTP/1 and I added a comment in the HPACK implementation that headers should get to HPACK already downcased. |
Please note that there are services (incorrectly) using case-sensitive headers. Yes, I know they're bad, but they exist :( I'm not familiar with HPACK.. but shouldn't we delegate the responsibility of "using same case" when putting and retrieving headers to callers, not downcasing blindly? Or at least provide option to use raw value. Or use it only for HTTP2. |
I would rather do that when we have an example of a service that does this. I think it's better to follow the spec until we find a counter-example. Plug does the same thing but we haven't found any clients that require case-sensitive headers yet. |
Spec says client/server should treat them case insensitive, not client/server should down case them. (Correction: case sensitive -> case insensitive) Bad server application implementation exists - and I did have that issue once. Plug is different - it's server side so users decide how to consume it. On the contrary, if server behaves bad ( expecting specific case), I cannot use any library mutating outgoing http header. (Note: I think it's reasonable to downcase response headers - since it's less likely to have a webservice returns same header in different cases to differentiate them) I think it's fine to apply some changes on response, but outgoing changes should be more carefully decided. .... or let's just document it and keep going! I'm fine with that - but I really wish any such built-in transformation must be explicitly mentioned :) |
Can you link to the spec sections that say that header keys should be treated case sensitive?
That does not mean a new client in 2019 should still allow for bad implementations. Like I said before if you can find examples in the wild that does not follow the spec then we can discuss around those, but right now it's hypothetical.
I agree, could you send a PR that mentions this in the documentation? |
I ran into a strange issue today when connecting to an upstream server with Mojito - there’s a custom header which is being converted to lower case, however the upstream server expects the exact casing. Though I think this is a bad design, is there an option to force Mojito or Mint to maintain your case without converting them. Counting on your usual support. |
What is the header and what upstream server is expecting in a specific casing? |
The upstream server has a custom header field which is set with {"Msisdn", "#{msisdn}"} in Mojito, however the server is reading a case sensitive header Msisdn, my request is failing due to the lower case conversion by Mojito. I tried using php curl and it works since curl/libcurl is not down casing the header. I would like to stick entirely with Elixir. A quick update - I used hackney for the same call and it works. |
It is hard for mint to support this because we support both HTTP/1.1 and HTTP/2 with automatic version negation and the user not having to know which version is in use. HTTP/2 requires that headers are downcased, if we have different behavior for HTTP/1.1 and HTTP/2 it will be confusing for users. |
Thanks for the swift response. Kudos for the awesome work done with |
I just want to make sure it's noted that they're the ones breaking the spec 😄 You might consider bringing it up with them and see if they're interested in a fix :) |
Before this commit, we would insert headers in the HPACK table without downcasing their name, and we would look up headers without downcasing their name either. With this commit, we downcase header names (since they're case insensitive) before inserting/looking up in the HPACK table.
Closes #171.
@ericmj not sure if there's a better or more efficient way of doing this. We might downcase at the boundary when headers are given to Mint but it's pretty much the same thing I think.