get method
Future<FetchResponse>
get(
- Uri uri, {
- Map<
String, String> headers = const {}, - ByteProgress? onProgress,
- CancelToken? cancel,
- int? maxBytes,
- ByteRange? range,
- 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);
}
}