loadNetworkBytes function

Future<Uint8List> loadNetworkBytes(
  1. String url, {
  2. Duration timeout = const Duration(seconds: 30),
  3. int maxBytes = 64 * 1024 * 1024,
})

Downloads one resource with a total deadline and a bounded response body.

Implementation

Future<Uint8List> loadNetworkBytes(
  String url, {
  Duration timeout = const Duration(seconds: 30),
  int maxBytes = 64 * 1024 * 1024,
}) async {
  final uri = Uri.parse(url);
  if ((uri.scheme != 'http' && uri.scheme != 'https') || uri.host.isEmpty) {
    throw ArgumentError.value(url, 'url', 'Expected an HTTP or HTTPS URL');
  }
  if (maxBytes <= 0 || timeout <= Duration.zero) {
    throw ArgumentError('Download limits must be positive');
  }
  final client = http.Client();
  try {
    return await (() async {
      final response = await client.send(http.Request('GET', uri));
      if (response.statusCode < 200 || response.statusCode >= 300) {
        throw http.ClientException('HTTP ${response.statusCode}', uri);
      }
      if ((response.contentLength ?? 0) > maxBytes) {
        throw StateError('Resource exceeds $maxBytes bytes');
      }
      final bytes = BytesBuilder(copy: false);
      await for (final chunk in response.stream) {
        if (bytes.length + chunk.length > maxBytes) {
          throw StateError('Resource exceeds $maxBytes bytes');
        }
        bytes.add(chunk);
      }
      return bytes.takeBytes();
    })().timeout(timeout);
  } finally {
    client.close();
  }
}