diff --git a/lib/src/cache.dart b/lib/src/cache.dart index 1073d361..1124437a 100644 --- a/lib/src/cache.dart +++ b/lib/src/cache.dart @@ -1,6 +1,7 @@ import 'dart:async'; import 'package:angel_framework/angel_framework.dart'; import 'package:intl/intl.dart'; +import 'package:pool/pool.dart'; final DateFormat _fmt = new DateFormat('EEE, d MMM yyyy HH:mm:ss'); @@ -14,12 +15,16 @@ class ResponseCache { ResponseCache({this.timeout}); + /// Removes an entry from the response cache. + void invalidate(String path) => _cache.remove(path); + /// A middleware that handles requests with an `If-Modified-Since` header. /// /// This prevents the server from even having to access the cache, and plays very well with static assets. Future ifModifiedSince(RequestContext req, ResponseContext res) async { if (req.headers.value('if-modified-since') != null) { - var modifiedSince = _fmt.parse(req.headers.value('if-modified-since')); + var modifiedSince = _fmt + .parse(req.headers.value('if-modified-since').replaceAll('GMT', '')); // Check if there is a cache entry. for (var pattern in patterns) { @@ -38,11 +43,30 @@ class ResponseCache { return true; } + /// A response finalizer that saves responses to the cache. Future responseFinalizer( RequestContext req, ResponseContext res) async { if (res.statusCode == 304) return true; - var now = new DateTime.now().toUtc(); + // Check if there is a cache entry. + for (var pattern in patterns) { + if (pattern.allMatches(req.uri.path).isNotEmpty) { + var now = new DateTime.now().toUtc(); + + // Invalidate the response, if need be. + if (_cache.containsKey(req.uri.path)) { + // If there is no timeout, don't invalidate. + if (timeout == null) return true; + + // Otherwise, don't invalidate unless the timeout has been exceeded. + var response = _cache[req.uri.path]; + if (now.difference(response.timestamp) < timeout) return true; + + // If the cache entry should be invalidated, then invalidate it. + invalidate(req.uri.path); + } + } + } } void setCachedHeaders( diff --git a/pubspec.yaml b/pubspec.yaml index 091d738c..d06ce879 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -3,6 +3,7 @@ dependencies: angel_framework: ">=1.0.0-dev <2.0.0" intl: ^0.15.0 meta: ^1.0.0 + pool: ^1.0.0 dev_dependencies: angel_test: ^1.1.0 glob: ^1.0.0