getBlobStream method
Future<Stream<BlobResponse> >
getBlobStream({
- required String sha256,
- required List<
String> serverUrls, - Nip01Event? authorization,
- int chunkSize = 1024 * 1024,
override
checks if the server supports range requests, if no server supports range requests, the entire blob is returned otherwise, the blob is returned in chunks. @see MDN HTTP range requests
Implementation
@override
Future<Stream<BlobResponse>> getBlobStream({
required String sha256,
required List<String> serverUrls,
Nip01Event? authorization,
int chunkSize = 1024 * 1024, // 1MB chunks
}) async {
// Find a server that supports range requests
String? supportedServer;
int? contentLength;
for (final url in serverUrls) {
try {
final rangeResponse = await supportsRangeRequests(
sha256: sha256,
serverUrl: url,
);
if (rangeResponse.first) {
supportedServer = url;
contentLength = rangeResponse.second;
break;
}
} catch (_) {
continue;
}
}
if (supportedServer == null || contentLength == null) {
// Fallback to regular download if no server supports range requests
final bytes = await getBlob(sha256: sha256, serverUrls: serverUrls);
return Stream.value(bytes);
}
// Create a stream controller to manage the chunks
final controller = StreamController<BlobResponse>();
// Start downloading chunks
int offset = 0;
while (offset < contentLength) {
final end = (offset + chunkSize - 1).clamp(0, contentLength - 1);
try {
final chunk = await getBlob(
sha256: sha256,
serverUrls: [supportedServer],
start: offset,
end: end,
);
controller.add(chunk);
offset = end + 1;
} catch (e) {
await controller.close();
rethrow;
}
}
await controller.close();
return controller.stream;
}