downloadRaw method

Future<RemoteDownloadResult<RawContent>> downloadRaw(
  1. String url, {
  2. bool requiresAuth = true,
  3. String? ifNoneMatch,
  4. required IriTerm documentIri,
  5. required String acceptContentType,
  6. bool isBinary = false,
})

Downloads a resource, returning raw RawContent (text or binary).

Passing isBinary = true returns BinaryContent (from response bytes); otherwise TextContent (from response body decoded as UTF-8 or per charset header) is returned. The acceptContentType header is sent verbatim.

Implementation

Future<RemoteDownloadResult<RawContent>> downloadRaw(
  String url, {
  bool requiresAuth = true,
  String? ifNoneMatch,
  required IriTerm documentIri,
  required String acceptContentType,
  bool isBinary = false,
}) async {
  final dpop = requiresAuth
      ? await _authProvider.getDpopToken(_prepareUrlForDpopToken(url), 'GET')
      : null;

  _log.fine(
      'GET $url auth=$requiresAuth ifNoneMatch=$ifNoneMatch accept=$acceptContentType isBinary=$isBinary');

  final response = await _client.get(
    Uri.parse(url),
    headers: {
      'Accept': acceptContentType,
      if (dpop != null) 'Authorization': 'DPoP ${dpop.accessToken}',
      if (dpop != null) 'DPoP': dpop.dPoP,
      if (ifNoneMatch != null) 'If-None-Match': ifNoneMatch,
    },
  );

  _log.fine('Response status: ${response.statusCode}');

  if (response.statusCode == 401) {
    _log.warning('401 Unauthorized for $url');
    throw AuthException(
      'Solid Pod authentication failed for $url',
      cause: 'HTTP 401 Unauthorized',
    );
  }
  if (response.statusCode == 404) {
    return NotFoundDownloadResult<RawContent>(
      documentIri: documentIri,
      requestETag: ifNoneMatch,
    );
  }
  if (response.statusCode == 304) {
    return NotModifiedDownloadResult<RawContent>(
      documentIri: documentIri,
      requestETag: ifNoneMatch,
      etag: ifNoneMatch!,
    );
  }
  if (response.statusCode != 200) {
    _log.warning('Failed to fetch $url: ${response.statusCode}');
    _log.warning('Response body: ${response.body}');
    throw SolidClientException(
        'Failed with status ${response.statusCode} to fetch $url. ${response.body.isNotEmpty ? '\nResponse body: ${response.body}' : ''}');
  }

  final contentType = response.headers['content-type'] ?? '';
  final mimeType = contentType.split(';').first.trim();
  final RawContent content = isBinary
      ? BinaryContent(response.bodyBytes, contentType: mimeType)
      : TextContent(response.body, contentType: mimeType);

  return SuccessDownloadResult<RawContent>(
    documentIri: documentIri,
    requestETag: ifNoneMatch,
    graph: content,
    etag: response.headers['etag'] ?? '',
  );
}