getCached method
The text at uri, kept in cache (with its ETag beside it) so an
unchanged file costs one small request and the last copy still reads
offline. refresh asks again even when the copy would do. decode
turns the bytes into text, and may throw an Exception to refuse
them; the cached copy is then used, as when offline.
The text may be maxBytes long (defaultMaxTextBytes when null);
cancel stops the request (a cancelled one never falls back on the
cached copy).
Throws what get or decode throws when there is no cached copy to
fall back on.
Implementation
Future<CachedText> getCached(
Uri uri, {
required File? cache,
required String Function(Uint8List bytes) decode,
bool refresh = false,
int? maxBytes,
CancelToken? cancel,
}) async {
final cached = cache == null ? null : _readCache(cache);
final etag = refresh ? null : cached?.etag;
final FetchResponse response;
try {
response = await get(
uri,
headers: {'If-None-Match': ?etag},
maxBytes: maxBytes ?? defaultMaxTextBytes,
cancel: cancel,
);
} on Object catch (e) {
if (e is! FetchException && e is! IOException && e is! TimeoutException) {
rethrow;
}
if (cached != null) {
return CachedText(cached.text, offline: true, error: e);
}
rethrow;
}
if (response.status == HttpStatus.notModified && cached != null) {
return CachedText(cached.text);
}
final String text;
try {
text = decode(response.body);
} on Exception catch (e) {
// A captive portal's page, or a half-published catalog: the last good
// copy is better than nothing.
if (cached != null) {
return CachedText(cached.text, offline: true, error: e);
}
rethrow;
}
if (cache != null) _writeCache(cache, text, response.etag);
return CachedText(text);
}