downloadPatchAssets method
Future<bool>
downloadPatchAssets({
- required UpdateManifest manifest,
- required void onProgress(
- double progress
override
Downloads patch binary assets with onProgress reporting.
Implementation
@override
Future<bool> downloadPatchAssets({
required UpdateManifest manifest,
required void Function(double progress) onProgress,
}) async {
if (manifest.downloadUrl == null || manifest.downloadUrl!.isEmpty) {
throw StateError('Cannot download patch: manifest.downloadUrl is empty.');
}
final uri = Uri.parse(manifest.downloadUrl!);
logger.info('BloomHttpUpdateAdapter: Downloading patch "${manifest.id}" from $uri');
try {
final request = http.Request('GET', uri);
request.headers.addAll(defaultHeaders);
final response = await httpClient.send(request);
if (response.statusCode < 200 || response.statusCode >= 300) {
throw HttpException('Download failed with HTTP status ${response.statusCode}', uri: uri);
}
final contentLength = response.contentLength ?? 0;
final bytesBuilder = BytesBuilder(copy: false);
var receivedBytes = 0;
await for (final chunk in response.stream) {
bytesBuilder.add(chunk);
receivedBytes += chunk.length;
if (contentLength > 0) {
onProgress(receivedBytes / contentLength);
} else {
onProgress(0.5);
}
}
final downloadedBytes = bytesBuilder.takeBytes();
onProgress(1.0);
// Verify SHA-256 integrity hash if provided in manifest
if (manifest.assetHash != null && manifest.assetHash!.isNotEmpty) {
final computedSha = sha256.convert(downloadedBytes).toString();
if (computedSha.toLowerCase() != manifest.assetHash!.toLowerCase()) {
throw StateError('Patch asset cryptographic integrity check failed: expected "${manifest.assetHash}", got "$computedSha"');
}
logger.debug('BloomHttpUpdateAdapter: Cryptographic asset hash verified: $computedSha');
}
// Stage patch file to disk
if (!stagingDir.existsSync()) {
stagingDir.createSync(recursive: true);
}
final patchFile = File(p.join(stagingDir.path, '${manifest.id}.patch'));
patchFile.writeAsBytesSync(downloadedBytes);
logger.info('BloomHttpUpdateAdapter: Staged patch "${manifest.id}" at ${patchFile.path} (${downloadedBytes.length} bytes)');
return true;
} catch (e, st) {
logger.error('BloomHttpUpdateAdapter: Patch download error: $e', e, st);
rethrow;
}
}