get method

Future<FetchResponse> get(
  1. Uri uri, {
  2. Map<String, String> headers = const {},
  3. ByteProgress? onProgress,
  4. CancelToken? cancel,
  5. int? maxBytes,
  6. ByteRange? range,
  7. Duration? deadline,
})

GETs uri with headers. A 304 (the If-None-Match copy is still good) comes back with an empty body; any other status but 200 throws a FetchException, as does a body over maxBytes (defaultMaxBytes when null), a redirect away from https:, a timeout and a failed connection.

With range, only that part of the file is asked for, and only a 206 holding exactly that part (as its Content-Range says) is accepted. A server that sends the whole file instead (200) is refused before its body is read — a FetchException with status 200, which tells the caller to download the file in full instead.

The whole fetch fails once deadline passes (deadlineFor the limit, when null).

Implementation

Future<FetchResponse> get(
  Uri uri, {
  Map<String, String> headers = const {},
  ByteProgress? onProgress,
  CancelToken? cancel,
  int? maxBytes,
  ByteRange? range,
  Duration? deadline,
}) async {
  if (!isFetchAllowed(uri)) {
    throw FetchException('Downloads must use https.', uri: uri);
  }
  final limit = maxBytes ?? defaultMaxBytes;
  final allowed = deadline ?? deadlineFor(range?.length ?? limit);
  final clock = Stopwatch()..start();
  final sent = range == null ? headers : {...headers, 'Range': range.header};
  for (var attempt = 1; ; attempt++) {
    cancel?.check();
    final left = allowed - clock.elapsed;
    if (left <= Duration.zero) throw _late(uri, allowed);
    final (response, retryAfter) = await _attempt(
      uri,
      headers: sent,
      onProgress: onProgress,
      cancel: cancel,
      maxBytes: limit,
      range: range,
      attempt: attempt,
      left: left,
      late: () => _late(uri, allowed),
    );
    if (response != null) return response;
    if (clock.elapsed + retryAfter! >= allowed) throw _late(uri, allowed);
    await _pause(retryAfter, cancel);
  }
}