-
Notifications
You must be signed in to change notification settings - Fork 354
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
FormatException with non-ASCII header field value in request #227
Comments
This looks like a bug around here: Line 42 in 45f4082
I think we need something like: final headerEncoding = Encoding.getByName('iso-8859-1');
request.headers.forEach((name, value) {
ioRequest.headers.set(name, headerEncoding.encode(value));
}); I can't reproduce this on the web though, I'm not sure if string encoding is not something we need to worry about there... |
cc @mit-mit to triage. I'm not sure if the SDK should be handling this for us, or if we need to handle it here... I'm also not super confident that my proposed solution would do the right thing. |
cc @jonasfj wdyt? |
Note RFC 7230. section 3.2 says: (emphasis added)
It seems to me that the inability to communicate with legacy systems that requires encoded header values could be considered a bug or a feature request. Ideally, you should have to jump through some hoops to use non-ASCII header values, but it seems reasonable that this should be possible. Perhaps we can offload the encoding to the caller, I don't know how often anyone will need this. @leutb, unless you're communicating with a legacy system I would suggest the string be UTF-8 and base64 encoded before sending it as a header value. |
We'd need to change the headers from |
Or add a new option I'm not sure there is an obvious fix.. |
if you the info device in the user agent you now end up with the same issue:
|
Hello there, I'm having a very similar issue. I'm making a GET request to an API, however it seems that it is returning an unsupported value in the response header:
Is there any way this can be resolved? On my native app I am calling the same API using Retrofit and I am not having those issues... |
Works with flutter stable? |
@AndroidNils Thanks for the quick reply. I've just tested it and indeed it works; on |
@bnxm I'm facing with this issue too. This code works only on
Important: Metadata & ContentDisposition of this file includes german umlauts like If I use the dart:io http client instead of http package, everything works (stable, beta and dev). Same issue with Dio Package (https://pub.dev/packages/dio) |
@AndroidNils I've filed an issue for this over here: dart-lang/sdk#41688 |
@sortie - can you help me understand if the fix in the SDK covers this entire issue, or if there was some secondary issue that cropped up here and was solved? The SDK issue sounds like a recent regression but this was filed a while ago, and I can't quite tell from the discussion if there are multiple root causes. |
@natebosch The SDK decodes HTTP headers as ISO-8859-1. I don't understand quite understand this question or what to do here. There was a regression for a while, introduced in https://dart-review.googlesource.com/c/sdk/+/138860 and fixed in https://dart-review.googlesource.com/c/sdk/+/145244. Is this issue still relevant? Do you have any specific question about the dart:io behavior, or an example of a problem, or something? |
The remaining question, is should the following code work, or should it throw an error: import 'dart:io';
void main() async {
var client = HttpClient();
var request = await client.openUrl('GET', Uri.http('google.com', ''));
request.headers.set('something', 'Pétange');
} Running this results in:
So, if I pass a |
Yes that is your responsibility. Dart will decode headers as ISO/IEC 8859-1 per a SHOULD in the standard for interoperability, but it's not recommended to actually send non-ascii data in the headers, so Dart doesn't let you do it in its own requests. We could allow ISO/IEC 8859-1 characters in the request for symmetry, but that probably just hides the fact that it's not UTF-8 for a while longer and leads to surprises and issues with interoperability with systems that don't decode the headers correctly. If you need to transfer non-ASCII data in the headers, consider using a request body instead, or encoding your data as UTF-8 using URL encoding, base64, UTF-7, or any other scheme; depending on what the remote side supports. Did that answer your question? |
Thanks! That does answer the question. Now the question goes back to this package. Our current API doesn't give users a way to accomplish this, and I think it would be breaking to add one. Since it's not something most users should do, we can either say it won't be allowed in this package (and users have to go to cc @zichangg for thoughts. |
Like what @sortie has explained! I don't think we have a plan to allow users to customize the encoding. I vaguely remembered the conversation with Lasse in one of the sdk issue. It is probably won't be added until next big jump(dart3?). I think It would be nice to clearly document somewhere. Correct me if I', wrong, I don't think For |
@zichangg Yes, excellent point, we should document this behavior clearly in dart:io. |
One use case for setting raw headers without validation is ICY headers. Some servers may serve audio with an HTTP response header like this:
where the title might contain non-ASCII characters if, for example, it is German. Now the audio player just_audio passes requests through a local proxy to implement some features, and to do this it needs to copy the raw HTTP headers across without modifying them. But because It would be nice to have a |
This is needed for basically every non-English language... I wanted to use a dictionary API on my application but this limitation just makes it impossible... |
Field value containing a non English character is invalid like 'Pétange'.
If changed to 'Petange' is OK.
Any idea ?
Map<String, String> _headers = { 'authorization': basicAuth, 'Entity': 'Pétange', }; http.Response _result = await _webUtils.get(_url, headers: _headers).then((dynamic res) { return res; });
Error :
FormatException: Invalid HTTP header field value: "Pétange"
The text was updated successfully, but these errors were encountered: