From: Shan Shaji <s.shaji@proxmox.com>
To: pve-devel@lists.proxmox.com
Subject: [pve-devel] [PATCH proxmox_dart_api_client v2 1/2] fix: ios: use `cupertino_http` package to honor custom user certificates
Date: Wed, 17 Sep 2025 14:06:15 +0200 [thread overview]
Message-ID: <20250917120616.80136-2-s.shaji@proxmox.com> (raw)
In-Reply-To: <20250917120616.80136-1-s.shaji@proxmox.com>
In iOS when a user installs a custom certificate and manually trusts it
from the certificate trust settings of iOS. The app was not
honoring the installed certificate [0] and was still throwing
`HandShakeException`.
The issue is because the `IOClient` doesn't by default honor user
installed certificate. To fix the issue, used the `cupertino_http` [1]
package which will honor the user installed certificates.
The `cupertino_http` package internally uses the native
iOS URL loading system [2].
- [0] https://support.apple.com/en-us/102390
- [1] https://pub.dev/packages/cupertino_http
- [2] https://developer.apple.com/documentation/foundation/url-loading-system
Signed-off-by: Shan Shaji <s.shaji@proxmox.com>
---
changes since v1:
- Rebased with master
lib/src/utils_native.dart | 10 +++++++++-
pubspec.lock | 26 +++++++++++++++++++++++++-
pubspec.yaml | 1 +
3 files changed, 35 insertions(+), 2 deletions(-)
diff --git a/lib/src/utils_native.dart b/lib/src/utils_native.dart
index a4b7397..de66b31 100644
--- a/lib/src/utils_native.dart
+++ b/lib/src/utils_native.dart
@@ -1,4 +1,5 @@
import 'package:cronet_http/cronet_http.dart';
+import 'package:cupertino_http/cupertino_http.dart';
import 'package:http/http.dart' as http;
import 'package:http/io_client.dart' as http_io;
import 'dart:io';
@@ -6,9 +7,10 @@ import 'dart:io';
http.Client getCustomIOHttpClient({bool validateSSL = true}) {
var ioClient = HttpClient();
+ const cacheMaxSizeInBytes = 1024 * 1024;
if (Platform.isAndroid && validateSSL) {
final engine = CronetEngine.build(
- cacheMaxSize: 1024 * 1024,
+ cacheMaxSize: cacheMaxSizeInBytes,
cacheMode: CacheMode.memory,
);
return CronetClient.fromCronetEngine(
@@ -17,6 +19,12 @@ http.Client getCustomIOHttpClient({bool validateSSL = true}) {
);
}
+ if (Platform.isIOS && validateSSL) {
+ final config = URLSessionConfiguration.ephemeralSessionConfiguration()
+ ..cache = URLCache.withCapacity(memoryCapacity: cacheMaxSizeInBytes);
+ return CupertinoClient.fromSessionConfiguration(config);
+ }
+
if (!validateSSL) {
ioClient.badCertificateCallback =
((X509Certificate cert, String host, int port) {
diff --git a/pubspec.lock b/pubspec.lock
index 6496e27..9a754ea 100644
--- a/pubspec.lock
+++ b/pubspec.lock
@@ -177,6 +177,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "3.0.3"
+ cupertino_http:
+ dependency: "direct main"
+ description:
+ name: cupertino_http
+ sha256: "72187f715837290a63479a5b0ae709f4fedad0ed6bd0441c275eceaa02d5abae"
+ url: "https://pub.dev"
+ source: hosted
+ version: "2.3.0"
dart_style:
dependency: transitive
description:
@@ -358,6 +366,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.0.2"
+ objective_c:
+ dependency: transitive
+ description:
+ name: objective_c
+ sha256: "9f034ba1eeca53ddb339bc8f4813cb07336a849cd735559b60cdc068ecce2dc7"
+ url: "https://pub.dev"
+ source: hosted
+ version: "7.1.0"
package_config:
dependency: transitive
description:
@@ -595,6 +611,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "0.5.1"
+ web_socket:
+ dependency: transitive
+ description:
+ name: web_socket
+ sha256: "34d64019aa8e36bf9842ac014bb5d2f5586ca73df5e4d9bf5c936975cae6982c"
+ url: "https://pub.dev"
+ source: hosted
+ version: "1.0.1"
web_socket_channel:
dependency: transitive
description:
@@ -621,4 +645,4 @@ packages:
version: "3.1.2"
sdks:
dart: ">=3.7.0 <4.0.0"
- flutter: ">=3.22.0"
+ flutter: ">=3.24.0"
diff --git a/pubspec.yaml b/pubspec.yaml
index 3aa881b..c864606 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -11,6 +11,7 @@ dependencies:
built_collection: ^5.1.1
retry: ^3.1.0
cronet_http: ^1.5.0
+ cupertino_http: ^2.3.0
dev_dependencies:
lints: ^3.0.0
--
2.50.1
_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel
next prev parent reply other threads:[~2025-09-17 12:06 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-09-17 12:06 [pve-devel] [PATCH proxmox_dart_api_client v2 0/2] fix: ios: add support for " Shan Shaji
2025-09-17 12:06 ` Shan Shaji [this message]
2025-09-17 12:06 ` [pve-devel] [PATCH proxmox_dart_api_client v2 2/2] fix: ios: add explicit throw of `HandshakeException` Shan Shaji
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20250917120616.80136-2-s.shaji@proxmox.com \
--to=s.shaji@proxmox.com \
--cc=pve-devel@lists.proxmox.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox