-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Description
Package
dio
Version
5.9.0
Operating-System
iOS
Adapter
Default Dio
Output of flutter doctor -v
[✓] Flutter (Channel stable, 3.38.5, on macOS 26.2 25C56 darwin-arm64, locale en-US) [421ms]
• Flutter version 3.38.5 on channel stable at /Users/sulaimankhan/flutter
• Upstream repository https://github.com/flutter/flutter.git
• Framework revision f6ff1529fd (7 weeks ago), 2025-12-11 11:50:07 -0500
• Engine revision 1527ae0ec5
• Dart version 3.10.4
• DevTools version 2.51.1
• Feature flags: enable-web, enable-linux-desktop, enable-macos-desktop, enable-windows-desktop, enable-android, enable-ios, cli-animations,
enable-native-assets, omit-legacy-version-file, enable-lldb-debugging
[✓] Android toolchain - develop for Android devices (Android SDK version 36.1.0) [2.3s]
• Android SDK at /Users/sulaimankhan/Library/Android/sdk
• Emulator version 36.3.10.0 (build_id 14472402) (CL:N/A)
• Platform android-36, build-tools 36.1.0
• Java binary at: /Applications/Android Studio.app/Contents/jbr/Contents/Home/bin/java
This is the JDK bundled with the latest Android Studio installation on this machine.
To manually set the JDK path, use: `flutter config --jdk-dir="path/to/jdk"`.
• Java version OpenJDK Runtime Environment (build 21.0.8+-14196175-b1038.72)
• All Android licenses accepted.
[✓] Xcode - develop for iOS and macOS (Xcode 26.2) [1,978ms]
• Xcode at /Applications/Xcode.app/Contents/Developer
• Build 17C52
• CocoaPods version 1.16.2
[✓] Chrome - develop for the web [9ms]
• Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome
[✓] Connected device (4 available) [6.0s]
• Khan (wireless) (mobile) • 00008130-0010043E0A50001C • ios • iOS 26.2.1 23C71
• LDC iPhone (mobile) • 00008101-001159680E85001E • ios • iOS 26.2 23C55
• macOS (desktop) • macos • darwin-arm64 • macOS 26.2 25C56 darwin-arm64
• Chrome (web) • chrome • web-javascript • Google Chrome 144.0.7559.97
! Error: Browsing on the local area network for Felipe’s iPhone. Ensure the device is unlocked and attached with a cable or associated with the same
local area network as this Mac.
The device must be opted into Developer Mode to connect wirelessly. (code -27)
[✓] Network resources [270ms]
• All expected network resources are available.
• No issues found!Dart Version
3.10.4
Steps to Reproduce
- Create a put request
- Add headers(ex: 'Content-Type': 'application/json') and give something in the body
- Set dio.options.preserveHeaderCase = true;
- Send the request
- You will see that dio only set this Content-Type to capital but Content-Length and other defaults header are small letter
'content-length' - My expectation was it should be 'Content-Length'
Expected Result
Content-Type': 'application/json'
Content-Length': x
Actual Result
'Content-Type': 'application/json'
'content-length': x
Codes
@singleton
@Named('sdb')
Dio sdbDio(AppLogInterceptor logInterceptor, SdbContentLengthInterceptor sdbContentLengthInterceptor) {
final dio = Dio();
dio.options.headers.clear();
dio.interceptors.addAll([logInterceptor]);
dio.options.baseUrl = 'http://192.168.42.1';
dio.options.preserveHeaderCase = true;
return dio;
}
@RestApi(baseUrl: '')
abstract class SdbConnectivityRemoteDataSourceImpl extends SdbConnectivityRemoteDataSource {
@factoryMethod
factory SdbConnectivityRemoteDataSourceImpl(@Named('sdb') Dio dio) = _SdbConnectivityRemoteDataSourceImpl;
@override
@Headers({'Content-Type': 'application/json'})
@PUT('/wlan/config')
Future<void> sendCredentials(@Body() SdbWifiCredentialsRequestDto credentials);
@override
@GET('/wlan/state')
Future<OnboardingSdbConfigurationStateResponseDto> getConfigurationState();
@override
@Headers({'Content-Type': 'application/json'})
@PUT('/wlan/scan')
Future<void> scanForNetworks({@Body() Map<String, dynamic> body = const {}});
@override
@GET('/wlan/list')
Future<SdbWifiNetworksResponseDto> getAvailableWifiNetworks();
}
Logs from Insomnia:
> PUT /wlan/scan HTTP/1.1
> Host: 192.168.42.1
> Content-Type: application/json
> User-Agent: insomnia/12.3.0
> Accept: */*
> Content-Length: 0
Logs from flutter devtools :
Request header:
user-agent: [Dart/3.10 (dart:io)]
Content-Type: [application/json] -> i explicitly defined and set preserveHeader = true
accept-encoding: [gzip]
content-length: [2]
host: [192.168.42.1]
*** Observations
As i set dio.options.preserveHeaderCase = true; , only Content-Type is kept as it is. Rest of the HTTP Header properties which dio added are used as small letter. Though the standard is camel case. as an example 'Content-Length'.
Note: This doesn't have any issue with standard server side. As i am connecting to iOT which use http 1.1 protocol and there they handle everything manually by cpp codes, there they check the header's key as string and you by default convert the properties to small letter words, i am getting http error from their end(Note: that project is not maintained anymore, can't change there)
*** Solution/Workaround I used:
class SdbContentLengthInterceptor extends Interceptor {
@override
void onRequest(RequestOptions options, RequestInterceptorHandler handler) {
if (options.data != null && (options.data is Map)) {
final rawJson = jsonEncode(options.data);
final bytes = utf8.encode(rawJson);
options.data = bytes;
options.headers.remove('content-length');
options.headers['Content-Length'] = bytes.length;
}
handler.next(options);
}
}