[native_dio_adapter] ConversionLayerAdapter silently drops proxy, badCertificateCallback, and persistentConnection config
@AlexV525 is already working on this.
Since Sep 7, 2026.
- Dominant language
- Dart
- Stars
- 12.8k
- Forks
- 1.6k
- PR merge metrics
- No merged PRs in 30d
Description
Package
native_dio_adapter
Version
1.8.0
Operating-System
Android, iOS, MacOS
Adapter
NativeAdapter
Output of flutter doctor -v
Dart Version
No response
Steps to Reproduce
- Configure a
Dioinstance with the defaultIOHttpClientAdapterand set a proxy (RequestOptions/HttpClient.findProxy) and abadCertificateCallbackthat accepts a specific self-signed cert. Confirm both work end to end (e.g. traffic visibly routes through the proxy; the self-signed endpoint succeeds). - Swap the adapter to
NativeAdapter(...)with no other code changes. - Re-run the exact same requests against the same proxy and self-signed endpoint.
// Before: works
dio.httpClientAdapter = IOHttpClientAdapter(
createHttpClient: () => HttpClient()
..findProxy = (uri) => 'PROXY 127.0.0.1:8888'
..badCertificateCallback = (cert, host, port) => true,
);
// After: proxy and cert override silently stop applying
dio.httpClientAdapter = NativeAdapter(
createCronetEngine: () => CronetEngine.build(),
createCupertinoConfiguration: () => URLSessionConfiguration.defaultSessionConfiguration(),
);
Expected Result
Switching adapters should either (a) preserve proxy and certificate-override behavior, or (b) fail loudly (throw / assert / log a warning) so the app doesn't silently start talking to the real endpoint without the proxy or start rejecting/accepting certs differently than configured.
Actual Result
Both settings silently stop having any effect — no exception, no log, no UnsupportedError. Confirmed by reading plugins/native_dio_adapter/lib/src/conversion_layer_adapter.dart, method _fromOptionsAndStream: it reads and forwards headers, followRedirects, maxRedirects, and the request body stream, but has no code path that reads any proxy-related field off RequestOptions, nor any bridge for a certificate-override callback. persistentConnection is also read by RequestOptions but is not forwarded to the constructed http.Request even though http.BaseRequest.persistentConnection exists and compatibility_layer's equivalent conversion function already does forward it (plugins/compatibility_layer/lib/src/conversion_layer_adapter.dart, ..persistentConnection = options.persistentConnection).
This is a silent capability regression on adapter swap, not a documented limitation — users who rely on proxy or self-signed-cert testing setups (very common in a CI/QA environment) get no signal that these stopped working.
Solution Brainstorm (proposed fix)
Split into three independently landable pieces:
-
persistentConnection— trivial, no upstream dependency. Add one line in_fromOptionsAndStream:request.persistentConnection = options.persistentConnection; -
badCertificateCallback— needs an upstream hook first.cronet_http'sCronetEngine.builddoes not currently expose a per-request or per-engine "accept this certificate" callback comparable todart:io'sHttpClient.badCertificateCallback;cupertino_http'sNSURLSessionis validated by the system trust store with no Dart-side override point at all. Concretely:- For the Cronet path, this needs a feature request against
cronet_httpfirst (expose a certificate-verification callback onCronetEngine), thenNativeAdapter/ConversionLayerAdaptercan threadoptions→ that callback. - For the Cupertino path, this is a platform limitation with no code-level fix available; the right deliverable here is documentation —
NativeAdapter's doc comment and README should explicitly state "self-signed/private-CA certificates are not supported viaCupertinoAdapter; fall back toIOHttpClientAdapterfor that scenario," so users don't discover this by a silent failure in production.
- For the Cronet path, this needs a feature request against
-
Proxy — likely also needs an upstream hook. Neither
cronet_httpnorcupertino_httpexpose a documented way to set proxy configuration per-request; both platforms currently rely on system-level proxy settings being picked up transparently byCronetEngine/URLSessionConfiguration. If that's the intended behavior, it should be stated explicitly inNativeAdapter's doc comment (it currently is not); if per-request/explicit proxy configuration is wanted, that's a feature request against the two upstreamhttppackages, not somethingnative_dio_adaptercan add on its own.
Given (2) and (3) require upstream API additions, the immediately actionable, no-dependency part of this issue is (1) plus updating NativeAdapter's doc comment to explicitly list proxy and certificate-override as not supported / silently ignored, until upstream hooks land.
Additional context
Related, separate but adjacent robustness gap in the same package: plugins/native_dio_adapter/lib/src/cronet_fallback_adapter.dart's isCronetProviderUnavailableMessage detects "all Cronet providers disabled" purely by message.contains(cronetProvidersDisabledMessage) against JThrowable.message. This is a Java exception-message substring match with no structural type check; if a future Cronet/Play Services release changes that message text, the fallback silently stops firing and requests fail with the raw JNI exception instead of falling back to the configured HttpClientAdapter. Happy to file this as its own issue if preferred, since it's a distinct failure mode (fallback-detection fragility) from the silent-config-drop problem above — flagging here for visibility since it was found during the same audit pass.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Assessment
This issue has not been assessed yet.