Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 14 additions & 1 deletion flutter_cache_manager/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ you call this method with other height/width parameters.
When your files are stored on Firebase Storage you can use [flutter_cache_manager_firebase](https://pub.dev/packages/flutter_cache_manager_firebase).

## Customize
The cache manager is customizable by creating a new CacheManager. It is very important to not create more than 1
The cache manager is customizable by creating a new CacheManager. It is very important to not create more than one
CacheManager instance with the same key as these bite each other. In the example down here the manager is created as a
Singleton, but you could also use for example Provider to Provide a CacheManager on the top level of your app.
Below is an example with other settings for the maximum age of files, maximum number of objects
Expand All @@ -85,6 +85,7 @@ class CustomCacheManager {
- [How are the cache files stored?](#how-are-the-cache-files-stored)
- [When are the cached files updated?](#when-are-the-cached-files-updated)
- [When are cached files removed?](#when-are-cached-files-removed)
- [Why are cached files kept even though the server sends max-age=0?](#why-are-cached-files-kept-even-though-the-server-sends-max-age0)


### How are the cache files stored?
Expand Down Expand Up @@ -113,6 +114,18 @@ The cache knows when files have been used latest. When cleaning the cache (which
deletes files when there are too many, ordered by last use, and when files just haven't been used for longer than
the stale period.

### Why are cached files kept even though the server sends max-age=0?

The case when a web server responds with `Cache-Control: max-age=0` is kind of an edge case.
It could either mean, that the content expires really fast (then `Cache-Control: no-cache` might
be a better response) or it could be that the server has some misconfiguration in place.

There where some confusions among users of this library because of the second case (see also
[this issue](https://github.com/Baseflow/flutter_cache_manager/issues/283) so as a default
behaviour this library ignores `max-age=0`.

If you want to treat `max-age=0` the same as `no-cache`, then set the `Config` parameter
`respectMaxAgeZero` to `true`.

## Breaking changes in v2
- There is no longer a need to extend on BaseCacheManager, you can directly call the constructor. The BaseCacheManager
Expand Down
4 changes: 3 additions & 1 deletion flutter_cache_manager/lib/src/config/_config_io.dart
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,13 @@ class Config implements def.Config {
CacheInfoRepository? repo,
FileSystem? fileSystem,
FileService? fileService,
bool? respectMaxAgeZero,
}) : stalePeriod = stalePeriod ?? const Duration(days: 30),
maxNrOfCacheObjects = maxNrOfCacheObjects ?? 200,
repo = repo ?? _createRepo(cacheKey),
fileSystem = fileSystem ?? IOFileSystem(cacheKey),
fileService = fileService ?? HttpFileService();
fileService = fileService ??
HttpFileService(respectMaxAgeZero: respectMaxAgeZero ?? false);

@override
final CacheInfoRepository repo;
Expand Down
2 changes: 2 additions & 0 deletions flutter_cache_manager/lib/src/config/_config_unsupported.dart
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ class Config implements def.Config {
FileSystem? fileSystem,
//ignore: avoid_unused_constructor_parameters
FileService? fileService,
//ignore: avoid_unused_constructor_parameters
bool? respectMaxAgeZero,
}) {
throw UnsupportedError('Platform is not supported');
}
Expand Down
4 changes: 3 additions & 1 deletion flutter_cache_manager/lib/src/config/_config_web.dart
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,13 @@ class Config implements def.Config {
CacheInfoRepository? repo,
FileSystem? fileSystem,
FileService? fileService,
bool? respectMaxAgeZero,
}) : stalePeriod = stalePeriod ?? const Duration(days: 30),
maxNrOfCacheObjects = maxNrOfCacheObjects ?? 200,
repo = repo ?? NonStoringObjectProvider(),
fileSystem = fileSystem ?? MemoryCacheSystem(),
fileService = fileService ?? HttpFileService();
fileService = fileService ??
HttpFileService(respectMaxAgeZero: respectMaxAgeZero ?? false);

@override
final CacheInfoRepository repo;
Expand Down
5 changes: 5 additions & 0 deletions flutter_cache_manager/lib/src/config/config.dart
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,18 @@ abstract class Config {
/// [JsonCacheInfoRepository].
/// The [fileSystem] defines where the cached files are stored and the
/// [fileService] defines where files are fetched, for example online.
/// If an http response contains a cache-control header with max-age=0 this
/// might mean that the content expires really fast or it could be a
/// misconfiguration of the server. With [respectMaxAgeZero] one can
/// control the lib's behaviour in this case.
factory Config(
String cacheKey, {
Duration stalePeriod,
int maxNrOfCacheObjects,
CacheInfoRepository repo,
FileSystem fileSystem,
FileService fileService,
bool respectMaxAgeZero,
}) = impl.Config;

String get cacheKey;
Expand Down
14 changes: 9 additions & 5 deletions flutter_cache_manager/lib/src/web/file_service.dart
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,11 @@ abstract class FileService {
/// [WebHelper]. One can easily adapt it to use dio or any other http client.
class HttpFileService extends FileService {
final http.Client _httpClient;
final bool _respectMaxAgeZero;

HttpFileService({http.Client? httpClient})
: _httpClient = httpClient ?? http.Client();
HttpFileService({http.Client? httpClient, bool? respectMaxAgeZero})
: _httpClient = httpClient ?? http.Client(),
_respectMaxAgeZero = respectMaxAgeZero ?? false;

@override
Future<FileServiceResponse> get(String url,
Expand All @@ -36,7 +38,7 @@ class HttpFileService extends FileService {
}
final httpResponse = await _httpClient.send(req);

return HttpGetResponse(httpResponse);
return HttpGetResponse(httpResponse, _respectMaxAgeZero);
}
}

Expand Down Expand Up @@ -64,12 +66,14 @@ abstract class FileServiceResponse {

/// Basic implementation of a [FileServiceResponse] for http requests.
class HttpGetResponse implements FileServiceResponse {
HttpGetResponse(this._response);
HttpGetResponse(this._response, this._respectMaxAgeZero);

final DateTime _receivedTime = clock.now();

final http.StreamedResponse _response;

final bool _respectMaxAgeZero;

@override
int get statusCode => _response.statusCode;

Expand Down Expand Up @@ -98,7 +102,7 @@ class HttpGetResponse implements FileServiceResponse {
if (sanitizedSetting.startsWith('max-age=')) {
final validSeconds =
int.tryParse(sanitizedSetting.split('=')[1]) ?? 0;
if (validSeconds > 0) {
if (validSeconds > 0 || _respectMaxAgeZero) {
ageDuration = Duration(seconds: validSeconds);
}
}
Expand Down
5 changes: 2 additions & 3 deletions flutter_cache_manager/lib/src/web/web_helper.dart
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,8 @@ const statusCodesNewFile = [HttpStatus.ok, HttpStatus.accepted];
const statusCodesFileNotChanged = [HttpStatus.notModified];

class WebHelper {
WebHelper(this._store, FileService? fileFetcher)
: _memCache = {},
fileFetcher = fileFetcher ?? HttpFileService();
WebHelper(this._store, this.fileFetcher)
: _memCache = {};

final CacheStore _store;
@visibleForTesting
Expand Down