-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
[Breaking Change Request] HttpHeaders allows cased header fields #39657
Comments
cc @Hixie @matanlurey @dgrove any concerns? |
Hey guys (@sstrickl & @leafpetersen), I saw that you worked on a previous breaking change request. I was wondering if there could be a suggestion on how to get this cross platform fix accepted. I'm currently trying to use Flutter with my Nginx/Laravel installations, and I am having issues with the server not accepting my headers (please see other comment from last week for details). Is it possible that the intent is that the Dart SDK only allows lowercase http headers @aartbik? |
I guess I'm fine with this but we should document that if this affects server behaviour it is a standards violation. Maybe call the argument "supportBrokenServersByPreservingCase" or some such. |
@Hixie One can say that Dart's HttpClient also breaks the standard. I believe this change is going in the wrong direction to begin with. Instead of making breaking changes why not refactor HttpClient internals so anyone can overload/re-implement parts they want to change. This would allow people to relatively easy change default behavior and would make everyone happy. |
Perhaps an immediate workaround
Forcing lowercase is also, by definition, breaking the standard. At the very least, allow the user to implement on override. I am in a position where an API, outside of our control, is rejecting the call due to this. |
A friendly ping. Is there any other concern except argument naming? |
Just a note below on the comment from @Hixie
There ideally should not be a name that is indicative of calling out "support ... broken" or anything like that. Since the standard does not impose case, any party could implement a solution where it is forced server-side and fails a request (unfortunately) as an indirect consequence of an internal byproduct, misconfig, or legacy solution. In Ngenix, this can be controlled for example. Something simple and clear such as "lowercaseHeaderOverride" - which simply and succinctly states what's being done. @zichangg it would be great to have this implemented as soon as possible. Perhaps even considered a "hotfix"? As the impact is zero, since you have to explicitly override to enable - and forcing lowercase kills many API calls (there is a third-party package that does this, which is unnecessary). |
@mit-mit That would work, sure. Descriptive and need to set it to invoke, perfect. |
@mit-mit
I don't understand. Per the standard, there can be no difference in behavior whether the header is uppercase or lowercase.
By what definition? There's nothing in the HTTP specification that says a client API can't lowercase the headers. It makes no difference, per HTTP.
That's why we're considering a workaround for broken servers. It doesn't mean that the server isn't broken though.
Why? |
@Hixie by the same logic that using uppercase is breaking the standard. |
Using uppercase isn't breaking the standard. What the standard says is that the server must act the same whether you use uppercase or lowercase or a mixture:
|
This breaking change is approved, with the argument name |
I prefer
|
@zichangg @mit-mit @Hixie @shaxxx @sortie To be blunt, there should be no override needed. This was an unfortunate implementation, since casing does not belong at this level. It should be a holistic approach at the framework level and allow the implementer to decide if it is required between endpoints. That would be the true definition of carrying forward the case insensitive "source of truth" from the spec, and allow the developer to decide if and when it matters. The name of the parameter is inconsequential in the overall picture if that is the direction. Just have it short and descriptive. EDIT: As the casing is irrelevant, there should be no issue in removing the current lowercase force correct? That would be more in line with the spec and remove unnecessary workarounds. Simplest approach might be the best here. |
@sortie I don't have strong opinions on the name, so long as we document that if this affects server behaviour it is a standards violation on the part of the server. If it was me I'd call it something like "supportBrokenServersByPreservingHeaderCase". |
What's the current status of this? Are you still discussing the name of optional parameter or something else? |
I beleive @zichangg is in the process of landing the change. |
I'm working on places that affected by this breaking change. I need to make sure landing this change won't break testing bots. After this, there should be nothing blocking. |
@zichangg may we have an update on when this might land, please? |
It landed! It should be in next stable release if there is no more regression. The current status is that this change has not been merged into internal codebase, because rolling is dead for a couple of day. |
Thanks; closing this issue to reflect that this is in master. CL was d39cdf0 |
@zichangg perfect, thanks for working this in quickly! |
We need to pick up version `2.2.0` of `http_multi_server` for compatibility with a breaking change in the SDK. dart-lang/sdk#39657
We need to pick up version `2.2.0` of `http_multi_server` for compatibility with a breaking change in the SDK. dart-lang/sdk#39657
The intended change in behavior
Current implementation of
HttpHeaders
will always force all header fields to be lower-cased. An optional named parameters will be added to following methods to loosen this restriction.Methods in abstract Class
HttpHeaders
will be changed:add
will be functionally the same as before. What's new?Header names will be always converted to lower-case unless
preserveHeaderCase
is set to true. If two header names are the same when converted to lower-case, they are considered to be the same header, with one set of values. The current case of a header is the name assigned by the lastset
oradd
call for that header.set
will remove the entity that has the same lower-cased header field and perform anadd
.The implementation class
_HttpHeaders
in dart:io will be modified accordingly.The justification
Header fields of
HttpHeaders
are case-insensitive according to specification. Implementation class_HttpHeaders
will convert all header fields into lowercases by default. This is expected behavior. However, some servers do rely on cased header fields.Relative issues:
#33501
#25120
Expected impact
Code that has classes extends/implements the
HttpHeaders
will now get compile time error.Steps for mitigation
Code that doesn't have classes extends/implements abstract
HttpHeaders
will not need to make any change. Otherwise, updateadd()
andset()
as showed above.Proposed implementation
https://dart-review.googlesource.com/c/sdk/+/119100
@lrhn @mit-mit @a-siva
The text was updated successfully, but these errors were encountered: