Fix race condition of expired cache files
Fix race condition of expired cache files

While cache expired, the original implementation returns older cache
information without waiting for possible new-downloaded file or
modification check. In situations where ETag has changed, updated file
will be downloaded using a new file name and old cache file be deleted
(according to `WebHelper._manageResponse()` and
`WebHelper._setDataFromHeaders()`).

If old cache file is returned immediately as in the original
implementation, in cases where the old cache file is still consuming,
it'll be very likely deleted by web helper routine. Thus
downloading-accessing race condition arise.

Here `CacheManager.getSingleFile()` was refactored to clarify two
situations.

- Cache exist and not expired: return the cache.
- Otherwise: just call `downloadFile()` and wait. Class `WebHelper` will
  do the rest for us smartly (Using `If-None-Match` HTTP request header).

Baseflow/flutter_cache_manager,Baseflow/flutter_cache_manager,Baseflow/flutter_cache_manager,Baseflow/flutter_cache_manager