getBlob method
Future<BlobResponse>
getBlob({
- required String sha256,
- required List<
String> serverUrls, - Nip01Event? authorization,
- int? start,
- int? end,
override
Gets a blob by trying servers sequentially until success
If authorization
is null, the server must be public
If start
and end
are null, the entire blob is returned
start
and end
are used to download a range of bytes, @see MDN HTTP range requests
Implementation
@override
Future<BlobResponse> getBlob({
required String sha256,
required List<String> serverUrls,
Nip01Event? authorization,
int? start,
int? end,
}) async {
Exception? lastError;
for (final url in serverUrls) {
try {
final headers = <String, String>{};
if (start != null) {
// Create range header in format "bytes=start-end"
// If end is null, it means "until the end of the file"
headers['range'] = 'bytes=$start-${end ?? ''}';
}
if (authorization != null) {
headers['Authorization'] = "Nostr ${authorization.toBase64()}";
}
final response = await client.get(
url: Uri.parse('$url/$sha256'),
headers: headers,
);
// Check for both 200 (full content) and 206 (partial content) status codes
if (response.statusCode == 200 || response.statusCode == 206) {
return BlobResponse(
data: response.bodyBytes,
mimeType: response.headers['content-type'],
contentLength:
int.tryParse(response.headers['content-length'] ?? ''),
contentRange: response.headers['content-range'] ?? '',
);
}
lastError = Exception('HTTP ${response.statusCode}');
} catch (e) {
lastError = e is Exception ? e : Exception(e.toString());
}
}
throw Exception(
'Failed to get blob from any of the servers. Last error: $lastError');
}