getDocument method

Future<DocumentResponse?> getDocument({
  1. required PeerId ownerPeerId,
  2. required String path,
  3. String? ifNoneMatch,
  4. PeerId? fromServer,
})

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');
      }
    }
  }
}