Closed BenderBlog closed 1 year ago
@BenderBlog This seems to be the expected behavior on the HTTP protocol: LINK
I had a similar issue a couple of days ago, and ended up having to place a ReGex guard on my headers to keep it running. I'm gathering that just removing/replacing/mapping the chars is not an option in your case, right?
I'm not sure if we can do something to help the circumstances. Header fields will eventually parsed by the parser embedded in the Dart, there seems to be no way to bypass the routine at this moment.
Could you evaluate the possibility of sending a raw request based on a HttpRequest
with your headers?
@BenderBlog This seems to be the expected behavior on the HTTP protocol: LINK
I had a similar issue a couple of days ago, and ended up having to place a ReGex guard on my headers to keep it running. I'm gathering that just removing/replacing/mapping the chars is not an option in your case, right?
You mean changing the dart's implementation on headers, like this? https://github.com/dart-lang/sdk/issues/42902
Or could you explain more about ReGex, did you changed the dart sdk code related to http?
And yes, it is expected behaviour.
@BenderBlog This seems to be the expected behavior on the HTTP protocol: LINK I had a similar issue a couple of days ago, and ended up having to place a ReGex guard on my headers to keep it running. I'm gathering that just removing/replacing/mapping the chars is not an option in your case, right?
You mean changing the dart's implementation on headers, like this? dart-lang/sdk#42902 Or could you explain more about ReGex, did you changed the dart sdk code related to http? And yes, it is expected behaviour.
We put the headers object through a ReGex filter, before adding it to the request. Something along this lines:
final cleanHeaders = oldHeaders.map((key, value) => value is String ? MapEntry(key, _removeNonAsciiChars(value)) : MapEntry(key, value));
The implementation of _removeNonAsciiChars
is very particular to our set of business rules, once we can get rid of some non-ascii chars, but still need to have some form of reconstructing the 'lost' info.
For instance, we register the public name of the wifi network from which the user is making the request:
{
'xWifiName':'Wifi do Paço'
}
The names tend to contain a lot of non-ascii chars, since the app is used by Portuguese-speaking customers. In this case, after we put the map above through the filter, we get this:
{
'xWifiName':'Wifi do Pa_231_o'
}
Where 231 is the ASCII code for the ç
char
This won´t cause any issues during the request but will keep our ability to reconstruct the info if ever needed.
At last, my opinion on this matter is: This kind of filter/treatment should not be part of dart-lang SDK or even the Dio Package.
And why is that?
Any char-specific treatment will incur some form of information mutation on the sent header, which of course will carry the opinion of those who come up with the implementation, which will lead to some other type of unforseable issues down the road.
Maybe docs should be more explicit on stating that chars not compliant with RULE will cause a FormatException
, but ultimately, the users of the Dio Package are the ones responsible for cleaning the headers before sending them on a request.
Based on https://github.com/cfug/dio/issues/1959#issuecomment-1717408299 from @DouglasValerio, you can try to submit a proposal to the Dart team, and see if they can handle this better. Closing as there is nothing Dio can do at this moment.
OK I have some solution right here.
You can encode the data with UrlEncoder, like Uri.encodeFull
. GBK and UTF transfer is another story...
Retrofit 2.10 added support for non-ascii characters on headers because is supported or even required for some services.
https://github.com/square/retrofit/blob/trunk/CHANGELOG.md#2100---2024-03-18
If you need to send device model on headers for some pruporse, it's not possible to send "iPhone XR", because Apple use a small R on model name witch isn't a ASCII character and needs a special treatment just for this case.
It tooks months to figure out what was happening, because this problem was affecting only iPhone XR devices.
Package
dio
Version
5.3.2
Operating-System
iOS
Output of
flutter doctor -v
Dart Version
3.13.2
Steps to Reproduce
example code
cookie example
especially
这里再用中文解释一下我的问题: 这个服务器使用 GBK 编码,其返回的 Cookie 包含 GBK 编码的中文字符。Dart 使用 UTF-16 解码会出现不合适的字符,然后当我想用这个 Cookie POST 请求的时候,其报错会引出“非法字符错误”。 顺便,我直接用中文发过去,照样报错。 根据 Cookie 规范,其只能是 ASCII 字符,但对于老服务器,有时候不会是这样。所以请求各位能考虑一下适配这样不太合适的需求吗,让 Headers 放行这样不正常的字符。
Expected Result
Well, it sends
Actual Result
Error: FormatException: Invalid HTTP header field value: "PhyEws_StuName=ä»»å®æ¶µ; path=/" (at character 16)
PhyEws_StuName=ä»»å®æ¶µ; path=/ ^
0 DioMixin.fetch. (package:dio/src/dio_mixin.dart:507:7)
1 _RootZone.runUnary (dart:async/zone.dart:1661:54)
2 _FutureListener.handleError (dart:async/future_impl.dart:174:22)
3 Future._propagateToListeners.handleError (dart:async/future_impl.dart:852:47)
4 Future._propagateToListeners (dart:async/future_impl.dart:873:13)
5 Future._completeError (dart:async/future_impl.dart:649:5)
6 _SyncCompleter._completeError (dart:async/future_impl.dart:60:12)
7 _Completer.completeError (dart:async/future_impl.dart:26:5)
8 Future.any.onError (dart:async/future.dart:620:45)
9 _RootZone.runBinary (dart:async/zone.dart:1666:54)
10 _FutureListener.handleError (dart:async/<…>