httpRequest method
Sends an HTTP request with certificate pinning support.
This method performs an HTTP request using the specified method and url,
with optional body, headers, and encoding. The request is secured using
the provided certificateHashes for certificate pinning.
Supports backup pins: provide multiple hashes so the connection succeeds if ANY hash matches. This prevents app downtime during certificate rotation.
Returns a SmartResponse object containing the result or error details.
Implementation
Future<SmartResponse> httpRequest({
required String method,
required String url,
Object? body,
Map<String, String>? headers,
String? encoding,
required List<String> certificateHashes,
required PinningMethod pinningMethod,
}) async {
if (certificateHashes.isEmpty) {
throw ArgumentError('certificateHashes must not be empty');
}
// Join hashes with comma for the native CSV format
final String resolvedHash = certificateHashes.join(',');
final String bodyStr;
if (body == null) {
bodyStr = '';
} else if (body is String) {
bodyStr = body;
} else if (body is Map) {
bodyStr = jsonEncode(body);
} else {
throw ArgumentError('Body must be a String or Map');
}
final String headersStr = headers == null ? '' : jsonEncode(headers);
final params = _FFIRequestParams(
method: method,
url: url,
bodyStr: bodyStr,
headersStr: headersStr,
encoding: encoding ?? 'json',
certificateHash: resolvedHash,
pinningMethod: pinningMethod.value,
);
final String resultJson;
if (Platform.isAndroid) {
resultJson = await compute(_executeFFIInIsolateAndroid, params);
} else if (Platform.isIOS) {
resultJson = await compute(_executeFFIInIsolateIOS, params);
} else {
throw UnsupportedError(
'Unsupported platform \'${Platform.operatingSystem}\'',
);
}
try {
final Map<String, dynamic> jsonMap = jsonDecode(resultJson);
return SmartResponse.fromJson(jsonMap);
} catch (e) {
return SmartResponse(
success: false,
error: 'Failed to parse native response: $resultJson',
errorType: 'JSONParseError',
);
}
}