getDocument method
Get a document from a peer's store
ownerPeerId The peer who owns the document
path Document path (e.g., "profile", "avatar")
ifNoneMatch Optional ETag for conditional GET (returns null if unchanged)
fromServer Optional: specify which server to retrieve from
Implementation
Future<DocumentResponse?> getDocument({
required PeerId ownerPeerId,
required String path,
String? ifNoneMatch,
PeerId? fromServer,
}) async {
final serverId = fromServer ?? await _serverSelector.selectServer(config.preferredServers);
if (serverId == null) {
_logger.warning('No S&F server available for document retrieval');
return null;
}
dynamic stream;
try {
final context = Context();
stream = await host.newStream(
serverId,
['/ricochet/store/doc/1.0.0'],
context,
).timeout(config.connectionTimeout);
final response = await DocumentHandler.getDocument(
stream,
ownerPeerId: ownerPeerId,
path: path,
ifNoneMatch: ifNoneMatch,
).timeout(config.messageTimeout);
await stream.close();
_logger.info('GET document ${ownerPeerId.toBase58().substring(0, 12)}.../doc/$path: ${response.status}');
return DocumentResponse(
status: response.status,
etag: response.etag,
contentType: response.contentType,
lastModified: response.lastModified,
content: response.body,
version: response.version,
history: response.history,
);
} on TimeoutException {
_logger.warning('GET document timed out');
return null;
} catch (e) {
_logger.warning('Failed to GET document: $e');
return null;
} finally {
if (stream != null && !stream.isClosed) {
try {
await stream.close();
} catch (e) {
_logger.fine('Error closing document stream: $e');
}
}
}
}